自定义view之PorterDuffXfermode实现刮刮卡
2015-11-12 15:38
465 查看
首先 先来看看刮刮卡的实现demo吧
效果棒棒哒!
在看代码之前,我们先来了解下PorterDuffXfermode。
PorterDuffXfermode
PorterDuffXfermode设置的是两个图层交集区域的显示方式,dst是先画的图形,而src是后画的图形。
当然,这些模式也不是经常使用的,用的最多的是,使用一张图片作为另一张图片的遮罩层,通过控制遮罩层的图形,来控制下面被遮罩图形的显示效果。其中最常用的就是通过DST_IN、SRC_IN模式来实现。
我们的刮刮卡也是通过这个原理实现的。在初始状态下,上面的图层会将下面整个图层覆盖,当你用手刮上面的图层的时候,下面的图层会慢慢显示出来,这也类似很多画图工具中的橡皮擦效果。
下面具体来分析实现原理。
首先需要做一些初始化工作,例如背景图、遮罩图和我们画图的Paint的一些属性,代码如下:
在上面的代码中,给Paint设置一些属性,让他的笔触和连接处更加圆滑一点,即Paint.Join.ROUND和Paint.Cap.ROUND属性。
将Paint的透明度设为0,这样才能显示出橡皮擦的效果,这是因为在使用PorterDuffXfermode进行图层混合时,并不是简单的只进行图层的计算,同事也会去计算透明通道的值。
接下来,看一下如何获取用户手指滑动所产生的路径。
好了,到这里代码估计就清晰了。首先初始化了一张背景图和一张灰色的图,并且混合模式为DST_IN,在滑动的时候,上层的灰色变透明,下层的和上层的合并,就出现了类似的效果。
最后看一下全部代码:
效果棒棒哒!
在看代码之前,我们先来了解下PorterDuffXfermode。
PorterDuffXfermode
PorterDuffXfermode设置的是两个图层交集区域的显示方式,dst是先画的图形,而src是后画的图形。
当然,这些模式也不是经常使用的,用的最多的是,使用一张图片作为另一张图片的遮罩层,通过控制遮罩层的图形,来控制下面被遮罩图形的显示效果。其中最常用的就是通过DST_IN、SRC_IN模式来实现。
我们的刮刮卡也是通过这个原理实现的。在初始状态下,上面的图层会将下面整个图层覆盖,当你用手刮上面的图层的时候,下面的图层会慢慢显示出来,这也类似很多画图工具中的橡皮擦效果。
下面具体来分析实现原理。
首先需要做一些初始化工作,例如背景图、遮罩图和我们画图的Paint的一些属性,代码如下:
mPaint = new Paint(); mPaint.setAlpha(0); //设置混合模式为DST_IN mPaint.setXfermode( new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); //设置画笔,让笔触和连接处更加圆滑 mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeWidth(50); mPaint.setStrokeCap(Paint.Cap.ROUND); mPath = new Path(); //设置背景图 mBgBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.beauty); //设置遮罩图 mFgBitmap = Bitmap.createBitmap(mBgBitmap.getWidth(), mBgBitmap.getHeight(), Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mFgBitmap); mCanvas.drawColor(Color.GRAY);
在上面的代码中,给Paint设置一些属性,让他的笔触和连接处更加圆滑一点,即Paint.Join.ROUND和Paint.Cap.ROUND属性。
将Paint的透明度设为0,这样才能显示出橡皮擦的效果,这是因为在使用PorterDuffXfermode进行图层混合时,并不是简单的只进行图层的计算,同事也会去计算透明通道的值。
接下来,看一下如何获取用户手指滑动所产生的路径。
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mPath.reset(); mPath.moveTo(event.getX(), event.getY()); break; case MotionEvent.ACTION_MOVE: mPath.lineTo(event.getX(), event.getY()); break; } mCanvas.drawPath(mPath, mPaint); invalidate(); return true; }
好了,到这里代码估计就清晰了。首先初始化了一张背景图和一张灰色的图,并且混合模式为DST_IN,在滑动的时候,上层的灰色变透明,下层的和上层的合并,就出现了类似的效果。
最后看一下全部代码:
import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import com.example.cntvuser.myapplication.R; public class XfermodeView extends View { private Bitmap mBgBitmap, mFgBitmap; private Paint mPaint; private Canvas mCanvas; private Path mPath; public XfermodeView(Context context) { super(context); init(); } public XfermodeView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public XfermodeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaint = new Paint(); mPaint.setAlpha(0); //设置混合模式为DST_IN mPaint.setXfermode( new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); //设置画笔,让笔触和连接处更加圆滑 mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeWidth(50); mPaint.setStrokeCap(Paint.Cap.ROUND); mPath = new Path(); //设置背景图 mBgBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.beauty); //设置遮罩图 mFgBitmap = Bitmap.createBitmap(mBgBitmap.getWidth(), mBgBitmap.getHeight(), Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mFgBitmap); mCanvas.drawColor(Color.GRAY); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mPath.reset(); mPath.moveTo(event.getX(), event.getY()); break; case MotionEvent.ACTION_MOVE: mPath.lineTo(event.getX(), event.getY()); break; } mCanvas.drawPath(mPath, mPaint); invalidate(); return true; } @Override protected void onDraw(Canvas canvas) { //画背景 canvas.drawBitmap(mBgBitmap, 0, 0, null); //画灰色 canvas.drawBitmap(mFgBitmap, 0, 0, null); } }
相关文章推荐
- JS获取时间
- 纯CSS实现delay连续动画
- 初识java之String与StringBuffer(上)
- 织梦dedecms 生成专题列表/special/index.html 的模板是哪个模板文件呢?
- js中数组和对象的区别
- 【html5】cookie、sessionStorage、localStorage
- mysql: Error Code: 1175. You are using safe update
- [LeetCode237]Delete Node in a Linked List
- 【优化】前端性能优化
- JS中class的实现方式,另模拟dojo.declare
- js隐藏切换文本信息
- JSP中page、include等指令小结
- jquery控制按钮的禁用与启
- javascript生成随机数方法汇总
- JSP针对XML文件操作技巧实例分析
- 关于在jsp中使用图片相对路径的问题
- SharedPreferences使用
- js二维数组和多维数组的定义声明
- 使用系统方法 创建一个 自定义样式的button
- 奇 偶 行的css 设置背景颜色.