Android 自定义View之PorterDuffXfermode的使用(刮刮卡的效果实现)
2017-04-17 11:33
603 查看
回想一下,在刮奖的时候的那个效果,怎么实现的呢,我们来看一下简单的实现方法。
![](http://img.blog.csdn.net/20170417163233067?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGVkb25nXzc3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
这里我们要用到画笔特效处理中的PorterDuffXfermode来实现这个效果。在学习PorterDuffXfermode之前,先看看看这张图:
![](http://img.blog.csdn.net/20170417095907994?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGVkb25nXzc3/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
图来自API demo。基本上讲PorterDuffXfermode的文章都引用了该图,类似于取并集,交集的概念。
它控制了两个图像之间的混合现实模式。
注意:PorterDuffXfermode显示的是两个图层交集区域的显示方式DST是先画的图形,src是后画的图形。一般来说,用得最多的是使用一张图片作为另一张图片的遮罩层,进而控制被遮罩层下的图片的显示效果,用得最多的就是DST_IN和SRC_IN,可以实现将矩形图片变成圆形图片或者圆形图片的效果。
不多费口舌,来看看刮刮卡的效果。
第一步,初始化画笔:
为了让画笔笔触更润滑一点,设置一下paint的属性, mPaint.setStrokeJoin(Paint.Join.ROUND);和 mPaint.setStrokeCap(Paint.Cap.ROUND);
后面是两个背景了,后背景就是要瓜了之后看到的图,前背景大小根据后背景图大小而定。
接下来就是用户手指滑动产生的路径了,再把路径保存下来,这里使用Path来操作。
最后还有一步,就是使用DET_IN模式将路径绘制到前面覆盖的图层上即可。最关键的一步就是要将画笔的透明度试着为0。这样才能显示擦除的效果。透明度设置为0的原因是因为PorterDuffXfermode进行图层混合时,并不是简单地只是进行图层的计算,同时也会去计算透明通道的值,正式由于混合了有名通道,才形成这样的效果。下面是完整代码:
布局:
自己动手试一下吧。
这里我们要用到画笔特效处理中的PorterDuffXfermode来实现这个效果。在学习PorterDuffXfermode之前,先看看看这张图:
图来自API demo。基本上讲PorterDuffXfermode的文章都引用了该图,类似于取并集,交集的概念。
它控制了两个图像之间的混合现实模式。
注意:PorterDuffXfermode显示的是两个图层交集区域的显示方式DST是先画的图形,src是后画的图形。一般来说,用得最多的是使用一张图片作为另一张图片的遮罩层,进而控制被遮罩层下的图片的显示效果,用得最多的就是DST_IN和SRC_IN,可以实现将矩形图片变成圆形图片或者圆形图片的效果。
不多费口舌,来看看刮刮卡的效果。
第一步,初始化画笔:
mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeWidth(100); mPaint.setStrokeCap(Paint.Cap.ROUND); mPath = new Path(); mBgBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.home_menu3); mFgBitmap = Bitmap.createBitmap(mBgBitmap.getWidth(), mBgBitmap.getHeight(), Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mFgBitmap); mCanvas.drawColor(Color.GRAY);
为了让画笔笔触更润滑一点,设置一下paint的属性, mPaint.setStrokeJoin(Paint.Join.ROUND);和 mPaint.setStrokeCap(Paint.Cap.ROUND);
后面是两个背景了,后背景就是要瓜了之后看到的图,前背景大小根据后背景图大小而定。
接下来就是用户手指滑动产生的路径了,再把路径保存下来,这里使用Path来操作。
@Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: mPath.lineTo(event.getX(), event.getY()); break; case MotionEvent.ACTION_DOWN: mPath.reset(); mPath.moveTo(event.getX(), event.getY()); break; } mCanvas.drawPath(mPath, mPaint); invalidate(); return true; }
最后还有一步,就是使用DET_IN模式将路径绘制到前面覆盖的图层上即可。最关键的一步就是要将画笔的透明度试着为0。这样才能显示擦除的效果。透明度设置为0的原因是因为PorterDuffXfermode进行图层混合时,并不是简单地只是进行图层的计算,同时也会去计算透明通道的值,正式由于混合了有名通道,才形成这样的效果。下面是完整代码:
/**
* Created by dong.he on 2017/3/15 0015.
* <p>
* 画笔特效处理
*/
public class PorterDuffXfermodeView extends View {
private Paint mPaint;
private Canvas mCanvas;
private Path mPath;
private Bitmap mBgBitmap, mFgBitmap;
public PorterDuffXfermodeView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mPaint = new Paint();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeWidth(100);
mPaint.setStrokeCap(Paint.Cap.ROUND);//为了让画笔笔触更润滑一点,设置一下paint的属性
mPath = new Path();
mBgBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.home_menu3);
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_MOVE: mPath.lineTo(event.getX(), event.getY()); break; case MotionEvent.ACTION_DOWN: mPath.reset(); mPath.moveTo(event.getX(), event.getY()); break; } mCanvas.drawPath(mPath, mPaint); invalidate(); return true; }
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mBgBitmap, 0, 0, null);
canvas.drawBitmap(mFgBitmap, 0, 0, null);
}
布局:
<com.example.donghe.myview.view.PorterDuffXfermodeView android:layout_width="wrap_content" android:layout_gravity="center" android:layout_height="200dp" />
自己动手试一下吧。
相关文章推荐
- 自定义View通过PorterDuffXfermode实现图片遮罩效果
- PorterDuffXfermode实现Android刮刮卡效果
- 自定义view之PorterDuffXfermode实现刮刮卡
- Android使用PorterDuffXfermode实现遮罩效果
- 使用PorterDuffXfermode实现橡皮檫效果(可实现Showcase效果)
- Android自定义View---PorterDuffXfermode两个交叠图形的显示
- 0917Android基础自定义View(颜色渲染PorterDuff及Xfermode)
- android之刮刮卡中奖效果PorterDuffXfermode与paint属性详解
- PorterDuffXfermode实现刮刮卡效果
- 使用PorterDuffXferMode实现自定义的圆角图片
- PorterDuffXfermode 实现刮刮卡效果
- PorterDuffXfermode ——实现刮刮卡效果
- 使用PorterDuffXfermode实现遮罩层
- android PorterDuffXfermode ,PorterDuff.Mode 使用 以及Porter-Duff规则详解
- Xfermode和PorterDuff详解、自定义View的属性、涂鸦和悬浮球绘制
- Android 自定义View修炼-【2014年最后的分享啦】Android实现自定义刮刮卡效果View
- Android 自定义View 实现刮刮卡效果
- android PorterDuffXfermode ,PorterDuff.Mode 使用 以及Porter-Duff规则详解
- Android中Canvas绘图之PorterDuffXfermode使用及工作原理详解
- android PorterDuffXfermode ,PorterDuff.Mode 使用 以及Porter-Duff规则详解