先附上妹子图一张
android刮刮卡效果原理讲解:
刮刮卡其实就是上面有个遮罩层,遮罩层会随着手指的滑动慢慢不可见,我们在内存中创建一块画布,让手指的滑动的区域和这块遮罩层的交集消失不可见即可。 我们这里让底部显示了一张妹子的图片,当然也可以是文字或者别的,底部背景是图片还是文字我们不需要关心,我们只需要关心的是这个遮罩层和手势滑动过的区域的交集处。画笔有setXferMode方法,这个是进行图层混合用到的,请看下图:
我们看下DstIn 和DstOut :
进行混合时底部的图层为Dst,上层的为Src.在这里,遮罩层为Dst,手势走过的路径为Src.
我们看DstIn,代表取Dst中两者的交集部分显示。这个显然不符合。
我们再看Dstout,代表取Dst中两者的不相交部分显示。我们手势划过的部分与遮罩层相交(这块的遮罩层不显示),没滑到的地方就不相交,(这块的遮罩层显示)。这样正好符合我们的要求。
上代码:
/**
* Time:2019/9/11
* Author:Jimmy Wang
* Email:wzy901213@163.com
* Blog:https://blog.csdn.net/wzy901213
* Description:
*/
public class GuaGuaKaView extends View {
/**
* 绘制线条的Paint,即用户手指绘制Path
*/
private Paint mOutterPaint = new Paint();
/**
* 绘制遮罩层Paint
*/
private Paint mPaint = new Paint();
/**
* 记录用户绘制的Path
*/
private Path mPath = new Path();
/**
* 美女背景图
*/
private Bitmap mBitmap;
/**
* 遮罩层目标背景图
*/
private Bitmap mDstBitmap;
/**
* 内存缓存的Canvas
*/
Canvas mCanvas ;
private int mLastX,mLastY;
public GuaGuaKaView(Context context) {
super(context);
}
public GuaGuaKaView(Context context,AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mBitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.beauty);
mOutterPaint.setColor(Color.RED);
mOutterPaint.setAntiAlias(true);
mOutterPaint.setDither(true);
mOutterPaint.setStyle(Paint.Style.STROKE);
mOutterPaint.setStrokeJoin(Paint.Join.ROUND); // 圆角
mOutterPaint.setStrokeCap(Paint.Cap.ROUND); // 圆角
// 设置画笔宽度
mOutterPaint.setStrokeWidth(50);
mOutterPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mDstBitmap = Bitmap.createBitmap(getMeasuredWidth(),getMeasuredHeight() ,Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mDstBitmap);
mCanvas.drawColor(Color.GRAY);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mBitmap,0,0, mPaint);
canvas.drawBitmap(mDstBitmap,0,0, mPaint);
drawPath();
}
/**
* 绘制线条
*/
private void drawPath()
{
mCanvas.drawPath(mPath, mOutterPaint);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();
int x = (int) event.getX();
int y = (int) event.getY();
switch (action)
{
case MotionEvent.ACTION_DOWN:
mLastX = x;
mLastY = y;
mPath.moveTo(mLastX, mLastY);
break;
case MotionEvent.ACTION_MOVE:
int dx = Math.abs(x - mLastX);
int dy = Math.abs(y - mLastY);
if (dx > 3 || dy > 3)
mPath.lineTo(x, y);
mLastX = x;
mLastY = y;
break;
}
invalidate();
return true;
}
}
写在最后:
如果这里的遮盖层是妹子的衣服,然后背景是个没穿衣服的妹子,我们不停滑的话会怎样,真不敢想象