Android刮刮樂效果-proterDuffXfermode

Android刮刮樂效果-proterDuffXfermode

先看看實現的效果
效果展現這個場景主要是模擬咱們有些app裏面的刮刮樂中獎的效果,主要是利用Android的proterDuffXfermode這個類去實現的。java

proterDuffXfermode

在用Android中的Canvas進行繪圖時,能夠經過使用PorterDuffXfermode將所繪製的圖形的像素與Canvas中對應位置的像素按照必定規則進行混合,造成新的像素值,從而更新Canvas中最終的像素顏色值,這樣會建立不少有趣的效果。PorterDuffXfermode的功能十分的強大,其餘的應用場景這裏就很少介紹,主要是看,刮刮樂的實現和原理。android

public class PorterDuffXfermode extends Xfermode

PorterDuffXfermode 繼承了Xfermode,使用的時候注意的API是Paint.setXfermode(Xfermode xfermode)。
PorterDuffXfermode支持如下十幾種像素顏色的混合模式,分別爲:CLEAR、SRC、DST、SRC_OVER、DST_OVER、SRC_IN、DST_IN、SRC_OUT、DST_OUT、SRC_ATOP、DST_ATOP、XOR、DARKEN、LIGHTEN、MULTIPLY、SCREEN。
這裏是使用PorterDuff.Mode.DST_IN,取兩層繪製交集,顯示下層。這個模式,來進行操做的。
在這裏插入圖片描述canvas

  • 自定義view繼承ImageView
    代碼比較少,我就直接來了
public class ProterDuffXfermodeView extends AppCompatImageView {
    private Bitmap mBgBitmap,mFgBitmap;
    private Paint mPaint;
    private Canvas mCanvas;
    private Path mPath;

    public ProterDuffXfermodeView(Context context, AttributeSet attrs) {
        super(context,attrs);
        init();
    }

     private void init() {
        //建立Paint
        mPaint=new Paint();
        //設置透明度
        mPaint.setAlpha(0);
        //設置Xfermode模式
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        //Paint類型
        mPaint.setStyle(Paint.Style.STROKE);
        //Paint.Join.MITER-銳角,ROUND-圓弧,BEVEL-直線
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeWidth(50);
        //線帽
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPath=new Path();
        Drawable drawable =getDrawable();
        mBgBitmap=((BitmapDrawable)drawable).getBitmap();
        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);
    }
}

首先有兩個bitmap,一個是背景(刮刮樂的照片),一個是前置的(灰色遮擋)。
這裏解釋一下幾個APIapi

//設置畫筆的樣式
        mPaint.setStyle(Paint.Style.FILL);//填充內容
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mPaint.setStyle(Paint.Style.STROKE);//描邊
//線帽
        mPaint.setStrokeCap(Paint.Cap.BUTT);//沒有
        mPaint.setStrokeCap(Paint.Cap.ROUND);//圓的
        mPaint.setStrokeCap(Paint.Cap.SQUARE);//方形
mPaint.setStrokeJoin(Paint.Join.MITER);//銳角
	mPaint.setStrokeJoin(Paint.Join.ROUND);//圓弧
	mPaint.setStrokeJoin(Paint.Join.BEVEL);//直線

別的API都好理解,這裏就不介紹了。
onTouchEvent事件分發
主要使用了Path
Path封裝了由直線和曲線(二次,三次貝塞爾曲線)構成的幾何路徑。你能用Canvas中的drawPath來把這條路徑畫出來(一樣支持Paint的不一樣繪製模式),也能夠用於剪裁畫布和根據路徑繪製文字。咱們有時會用Path來描述一個圖像的輪廓,因此也會稱爲輪廓線(輪廓線僅是Path的一種使用方法,二者並不等價)。
Path詳解 若是不瞭解能夠看下這篇文章
moveTo 移動下一次操做的起點位置
lineTo 添加上一個點到當前點之間的直線到Path
主要用到了這兩個api
最後就是onDraw().app

  • XML直接引用自定義view便可。
    固然,實現這個功能可能還有其它寫法,這裏只是提供一種思路,也是最簡單的實現。

歡迎關注公衆號 拖鞋王子豬 一塊兒開心起來。ide

相關文章
相關標籤/搜索