自定义的刮刮卡view,使用了画笔的PorterDuffXfermode属性

/**
 * 画笔paint的属性PorterDuffXfermode使用
 * 这里自定义了一个刮刮卡效果的view
 * <p>
 * PorterDuffXfermode 是设置两个图层交集的地方的显示方式,
 * des是先画的图层,src是后画的图层。
 */
public class PaintXfermodeView extends android.support.v7.widget.AppCompatImageView {

    //先画的图层
    private Bitmap bgBitmap;
    //后画的原本图层的副本图层
    private Bitmap fgBitmap;
    //画笔对象,设置PorterDuffXfermode,来修改两个图层的交集显示情况
    private Paint paint;
    //canvas画布对象,用来绘制副本图层的图像
    private Canvas canvas;
    //路径对象,用来记录手指划过的路径
    private Path path;

    public PaintXfermodeView(Context context) {
        this(context, null);
    }

    public PaintXfermodeView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PaintXfermodeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    /**
     * 初始化画笔,位图,画布
     */
    private void init() {
        //初始化路径 位图,画布,在第二图层上画上灰色
        bgBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.flower);
        fgBitmap = Bitmap.createBitmap(bgBitmap.getWidth(), bgBitmap.getHeight(), Bitmap.Config.ARGB_8888);
        canvas = new Canvas(fgBitmap);
        canvas.drawColor(Color.GRAY);
        path = new Path();

        //初始化画笔,带有PorterDuffXfermode模式
        paint = new Paint();
        //画笔的透明度设置为0,才能出现擦除效果
        paint.setAlpha(Color.TRANSPARENT);
        paint.setStyle(Paint.Style.STROKE);
        paint.setAntiAlias(true);
        //笔触是圆滑的
        paint.setStrokeCap(Paint.Cap.ROUND);
        //笔触连接处圆滑的
        paint.setStrokeJoin(Paint.Join.ROUND);
        //画笔宽度
        paint.setStrokeWidth(50);
        //DST_IN:Keeps the source pixels that do not cover destination pixels.
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制背景图,覆盖图层
        canvas.drawBitmap(bgBitmap, 0, 0, null);
        canvas.drawBitmap(fgBitmap, 0, 0, null);
    }

    float currX, currY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                path.reset();
                currX = x;
                currY = y;
                path.moveTo(x, y);

                break;
            case MotionEvent.ACTION_MOVE:
                //使用二阶贝塞尔曲线绘制滑动路线,前一个quadTo()的终点,就是下一个quadTo()函数的起点
                path.quadTo(currX, currY, event.getX(), event.getY());
                currX = event.getX();
                currY = event.getY();
                break;
        }
        //将滑动路径用paint画笔绘制到canvas上
        canvas.drawPath(path, paint);
        invalidate();
        return true;
    }
}

猜你喜欢

转载自blog.csdn.net/hpp_1225/article/details/88780636

相关文章