先附上妹子圖一張
android刮刮卡效果原理講解:
刮刮卡其實就是上面有個遮罩層,遮罩層會随着手指的滑動慢慢不可見,我們在記憶體中建立一塊畫布,讓手指的滑動的區域和這塊遮罩層的交集消失不可見即可。 我們這裡讓底部顯示了一張妹子的圖檔,當然也可以是文字或者别的,底部背景是圖檔還是文字我們不需要關心,我們隻需要關心的是這個遮罩層和手勢滑動過的區域的交集處。
畫筆有setXferMode方法,這個是進行圖層混合用到的,請看下圖:
我們看下DstIn 和DstOut :
進行混合時底部的圖層為Dst,上層的為Src.在這裡,遮罩層為Dst,手勢走過的路徑為Src.
我們看DstIn,代表取Dst中兩者的交集部分顯示。這個顯然不符合。
我們再看Dstout,代表取Dst中兩者的不相交部分顯示。我們手勢劃過的部分與遮罩層相交(這塊的遮罩層不顯示),沒滑到的地方就不相交,(這塊的遮罩層顯示)。這樣正好符合我們的要求。
上代碼:
/**
* Time:2019/9/11
* Author:Jimmy Wang
* Email:[email protected]
* 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;
}
}
寫在最後:
如果這裡的遮蓋層是妹子的衣服,然後背景是個沒穿衣服的妹子,我們不停滑的話會怎樣,真不敢想象