先看看實現的效果
這個場景主要是模擬咱們有些app裏面的刮刮樂中獎的效果,主要是利用Android的proterDuffXfermode這個類去實現的。java
在用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
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
歡迎關注公衆號 拖鞋王子豬 一塊兒開心起來。ide