Paint之Xfermode實現刮刮卡等一些列效果

前段時間,產品有個需求就是要搞一個抽獎活動,類似支付寶的刮刮卡功能.自然想到了Paint的Xfermode.話不多說,先上效果.

刮刮卡

在Paint的使用中,有一個方法叫做setXfermode,這個方法需要傳遞一個Xfermode的實例,為了實現這個效果,我們使用PorterDuffXfermode中的SRC_OUT模式,先上代碼再講原理.

首先,準備好兩張圖片,一張是底圖,這個是不變的 也就是最下面那張圖.一張是源圖,也就是最上層那張圖.

還是老套路,自定義控件繼承自View,在構造方法中先初始化畫筆Paint,準備好底圖以及源圖,還有一張跟源圖相同大小的透明圖片,初始化Path.

public GuaguaCard(Context context, AttributeSet attrs) {

????super(context, attrs);

????mBitPaint=newPaint();

????mBitPaint.setColor(Color.BLACK);

????mBitPaint.setStyle(Paint.Style.STROKE);

????mBitPaint.setStrokeWidth(45);

????BmpText=BitmapFactory.decodeResource(getResources(),R.drawable.guaguaka_text1,n????ull);

????BmpSRC= BitmapFactory.decodeResource(getResources(),R.drawable.guaguaka,null);

????BmpDST= Bitmap.createBitmap(BmpSRC.getWidth(),BmpSRC.getHeight(), ????Bitmap.Config.ARGB_8888);

????mPath=newPath();

}

在onDraw方法中先將BmpText繪制到畫布上.創建一個新圖層,然后根據將手指的移動軌跡繪制到BmpDST上,將BmpDST繪制到畫布上,最后將BmpSRC以PorterDuff.Mode.SRC_OUT的模式繪制到canvas上.這樣底層圖片BmpText永遠都在最下面的圖層,然后BmpDST與BmpSRC的混合結果將鋪在上面.這樣就可以達到我們想要的結果.

上代碼:

@Override

protected void onDraw(Canvas canvas) {

????super.onDraw(canvas);

????canvas.drawBitmap(BmpText,0,0,mBitPaint);

????//官方叫法離屏緩存

????intlayerId = canvas.saveLayer(0,0, getWidth(), getHeight(),null, ? ?????Canvas.ALL_SAVE_FLAG);

????//將path繪制到dst圖像上

????Canvas canvas1 =newCanvas(BmpDST);

????canvas1.drawPath(mPath,mBitPaint);

????//然后把目標圖像畫到畫布上

????canvas.drawBitmap(BmpDST,0,0,mBitPaint);

????//使用Xfermode繪制源圖

????mBitPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));

????canvas.drawBitmap(BmpSRC,0,0,mBitPaint);

????// 還原混合模式

????mBitPaint.setXfermode(null);

????// 還原畫布

????canvas.restoreToCount(layerId);

? ?}

@Override

public boolean onTouchEvent(MotionEvent event) {

????switch(event.getAction()){

????case MotionEvent.ACTION_DOWN:

????mPath.moveTo(event.getX(),event.getY());

????mPreX= event.getX();

????mPreY= event.getY();

????return true;

????case MotionEvent.ACTION_MOVE:

????float endX = (mPreX+event.getX())/2;

????float endY = (mPreY+event.getY())/2;

????mPath.quadTo(mPreX,mPreY,endX,endY);

????mPreX= event.getX();

????mPreY=event.getY();

????break;

????case MotionEvent.ACTION_UP:

????break;

}

????postInvalidate();

????return super.onTouchEvent(event);

}

這里面有一個特別重要的方法就是mBitPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT))

根據PorterDuff的模式不同,展現的效果也不同.SRC_OUT的效果就是按照源圖片BmpSRC以及目標圖片BmpDST的進行組合,最終來繪制源圖片.那這個組合的方式我們來看一下源碼:

/** [Sa * (1 - Da), Sc * (1 - Da)] */

也就是根據上面的規則對源圖片以及目標圖片的顏色ARGB通道來進行組合,當我手勢滑動的時候目標圖片的對應區域的alpha值就變成1了,所以對應的區域就透明了,其他區域時透明的所以對應區域就按源圖展示,這樣就實現了刮刮卡效果了,是不是很神奇!

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容