用帆布橡皮擦效果 [英] Eraser effect using canvas

查看:236
本文介绍了用帆布橡皮擦效果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有延伸视图的自定义视图类。我使用过缠身的onDraw方法涂鸦画布上。我有一个POJO,其中包括路径和画图的帮助,而我可以重新创建旧的路径绘制的清单是这样的:

I have a custom view class which extends the view. I am using the over-ridden onDraw method to doodle on the canvas. I have a list of a POJO which includes Path and Paint with the help of which I can re-create the old paths drawn, something like this:

@Override
protected void onDraw(Canvas canvas){
for (POJO pojo : pojoList {
  canvas.drawPath(pojo.path, pojo.paint);
}
canvas.drawPath(path, paint);
}

我要实现擦除功能,它应该像一个适当的擦除。我知道这样做是为了写一个位图和使用setXfermode以清除其正常工作的一种方式。但像素化不看在小分辨率的设备不错。我不想用白色油漆的颜色,因为这观点我有一个ImageView的下方,因此它的着色白也将影响ImageView的为好。
任何想法或片段对解决这个问题是高度AP preciated。

I want to implement erase function which should work like a proper erase. I know one way to do it to write to a bitmap and use setXfermode to CLEAR which properly works. But pixelation doesn't look good on smaller resolution devices. I don't want to use WHITE color paint as underneath this view I have an ImageView, so coloring it white will also effect the ImageView as well. Any idea or snippet towards solving this problem is highly appreciated.

推荐答案

这工作得很好。如果有人找到一个更好的解决方案。请更新

This works just fine. If someone finds a better solution. Kindly update

private Context mContext;
private ArrayList<Draw> mDrawList;
private Paint mPaint;
private Path mPath;
private boolean isErase;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;

public EraseDoodleView(Context context) {
    super(context);
    init(context);
}

public EraseDoodleView(Context context, AttributeSet attributeSet) {
    super(context, attributeSet);
    init(context);
}

private void init(Context context) {
    mContext = context;
    mDrawList = new ArrayList<Draw>();
    mPath = new Path();
    setupPaint();
    setLayerType(View.LAYER_TYPE_HARDWARE, mPaint);
}

private void setupPaint() {
    mPaint = new Paint();
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setFilterBitmap(true);
    mPaint.setAntiAlias(true);
    mPaint.setStrokeWidth(4);
    mPaint.setColor(ContextCompat.getColor(mContext, android.R.color.black));
    if (isErase) {
        mPaint.setXfermode(new PorterDuffXfermode(
                PorterDuff.Mode.CLEAR));
        mPaint.setStrokeWidth(16);
    }
}

public void setErase(boolean isErase) {
    this.isErase = isErase;
    setupPaint();
}

public boolean getErase() {
    return this.isErase;
}

@Override
protected void onDraw(Canvas canvas) {
    for (Draw draw : mDrawList) {
        canvas.drawPath(draw.path, draw.paint);
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    float x = event.getX();
    float y = event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touchStart(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_MOVE:
            touchMove(x, y);
            invalidate();
            break;
        case MotionEvent.ACTION_UP:
            touchUp();
            invalidate();
            break;
    }
    return true;
}

private void touchStart(float x, float y) {
    mPath.reset();
    mPath.moveTo(x, y);
    mDrawList.add(new Draw(mPath, mPaint));
    mX = x;
    mY = y;
}
private void touchMove(float x, float y) {
    float dx = Math.abs(x - mX);
    float dy = Math.abs(y - mY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
        mX = x;
        mY = y;
    }
}

private void touchUp() {
    mPath.lineTo(mX, mY);
    mPath = new Path();
}


class Draw {
    Path path;
    Paint paint;

    public Draw(Path path, Paint paint) {
        this.paint = paint;
        this.path = path;
    }
}

这篇关于用帆布橡皮擦效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆