Android实现刮刮卡效果

最终实现效果:

需要注意的点:

Paint.setXfermode()

是用来设置两张图片相交时的模式的,google官方展示了16种效果,具体可以去查看官方文档。可以这么理解DST和SRC,在设置Paint.setXfermode()之前Canvas上的内容就是DST, 在Paint.setXfermode()之后画的就是SRC了,Paint.setXfermode()就是设置DST和SRC相交区域混合模式。

canvas.saveLayer()和canvas.restoreToCount()

它的作用是生成一个新的图层,这个图层是透明的,在调用saveLayer()之后所有draw方法都是在这个图层上进行的,我们可以任意的设置颜色和画任何的图形,而对之前的Canvas不会造成任何影响,最后我们使用restoreToCount()将新的层与底下的Canvas相结合就形成一个完整的图像。

实现流程

1.初始化

    private void init() {
        //初始化画笔
        mPaint = new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(80);
​
        //禁用硬件加速,某些API不支持硬件加速
        setLayerType(LAYER_TYPE_SOFTWARE, null);
​
        //初始化图像对象
        mTxtBmp = BitmapFactory.decodeResource(getResources(), R.drawable.result);
        mSrcBmp = BitmapFactory.decodeResource(getResources(), R.drawable.src);
        mDstBmp = Bitmap.createBitmap(mSrcBmp.getWidth(), mSrcBmp.getHeight(), Bitmap.Config.ARGB_8888);
​
        //路径(贝赛尔曲线)
        mPath = new Path();
    }

2.绘制相关图层

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
​
        //绘制刮奖结果
        canvas.drawBitmap(mTxtBmp, 0, 0, mPaint);
​
        //使用离屏绘制
        int layerID = canvas.saveLayer(0,0,getWidth(),getHeight(),mPaint);
​
        //先将路径绘制到 bitmap上
        Canvas dstCanvas = new Canvas(mDstBmp);
        dstCanvas.drawPath(mPath, mPaint);
​
        //绘制目标图像
        canvas.drawBitmap(mDstBmp,0,0,mPaint);
        //设置模式为SRC_OUT,擦橡皮区域为交集区域需要清掉像素
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
        //绘制源图像
        canvas.drawBitmap(mSrcBmp,0,0,mPaint);
​
        mPaint.setXfermode(null);
​
        canvas.restoreToCount(layerID);
​
    }

3.触摸事件处理

    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
​
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mEventX = event.getX();
                mEventY = event.getY();
                mPath.moveTo(mEventX,mEventY);
                break;
            case MotionEvent.ACTION_MOVE:
                float endX = (event.getX() - mEventX) / 2 + mEventX;
                float endY = (event.getY() - mEventY) / 2 + mEventY;
                //画二阶贝塞尔曲线
                mPath.quadTo(mEventX, mEventY, endX, endY);
                mEventX = event.getX();
                mEventY = event.getY();
                break;
        }
        invalidate();
        return true;
    }

 

你可能感兴趣的:(android)