【问题标题】:how to fix the wrong coordinates of zoomed canvas in Android如何修复Android中缩放画布的错误坐标
【发布时间】:2019-09-26 12:04:42
【问题描述】:

我有一个自定义的paint_view,它扩展了 image_view 并且可以使用矩阵进行缩放。 我为画布设置了这个矩阵并缩放它并通过这个矩阵拖动它,但是在画布缩放或平移之后,路径或可绘制对象被绘制在错误的坐标中。 我已经尝试设置坐标,但我不知道设置它的优化方式。
这是我的代码:

public class PaintView extends View {


private Path     drawPath;
private Paint    drawPaint;
private Paint    rect_paint;
public boolean   zoomMode    = false;
private Matrix   matrix      = new Matrix();
private Matrix   savedMatrix = new Matrix();
float            oldDist;
PointF           start       = new PointF();
PointF           mid         = new PointF();

static final int NONE        = 0;
static final int DRAG        = 1;
static final int ZOOM        = 2;
int              mode        = NONE;


public PaintView(Context context) {
    super(context);
}


public PaintView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setupDrawing();
}


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


private void setupDrawing() {
    drawPath = new Path();
    drawPaint = new Paint();
    drawPaint.setColor(Color.BLACK);
    drawPaint.setAntiAlias(true);
    drawPaint.setStyle(Paint.Style.STROKE);
    drawPaint.setStrokeJoin(Paint.Join.ROUND);
    drawPaint.setStrokeCap(Paint.Cap.ROUND);
    drawPaint.setStrokeWidth(10);
    rect_paint = new Paint();
    rect_paint.setColor(Color.BLACK);
    rect_paint.setAntiAlias(true);
    rect_paint.setStyle(Paint.Style.STROKE);
    rect_paint.setStrokeJoin(Paint.Join.ROUND);
    rect_paint.setStrokeCap(Paint.Cap.ROUND);
    rect_paint.setStrokeWidth(20);
}


protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.setMatrix(matrix);
    canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), rect_paint);
    canvas.drawPath(drawPath, drawPaint);
}


public boolean onTouchEvent(MotionEvent event) {
    if (zoomMode) {
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                savedMatrix.set(matrix);
                start.set(event.getX(), event.getY());
                mode = DRAG;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                oldDist = spacing(event);
                if (oldDist > 10f) {
                    savedMatrix.set(matrix);
                    midPoint(mid, event);
                    mode = ZOOM;
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                break;
            case MotionEvent.ACTION_MOVE:
                if (mode == DRAG) {
                    matrix.set(savedMatrix);
                    matrix.postTranslate(event.getX() - start.x,
                            event.getY() - start.y);
                }
                else if (mode == ZOOM) {
                    float newDist = spacing(event);
                    if (newDist > 10f) {
                        matrix.set(savedMatrix);
                        float scale = newDist / oldDist;
                        matrix.postScale(scale, scale, mid.x, mid.y);
                    }
                }
                break;

        }
    } else {
        float touchX = event.getX();
        float touchY = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                drawPath.moveTo(touchX, touchY);
                break;
            case MotionEvent.ACTION_MOVE:
                drawPath.lineTo(touchX, touchY);
                break;
            case MotionEvent.ACTION_UP:
                drawPath.lineTo(touchX, touchY);
                break;
        }
    }
    invalidate();
    return true;
}


private float spacing(MotionEvent event) {
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return FloatMath.sqrt(x * x + y * y);
}


private void midPoint(PointF point, MotionEvent event) {
    float x = event.getX(0) + event.getX(1);
    float y = event.getY(0) + event.getY(1);
    point.set(x / 2, y / 2);
}}

【问题讨论】:

    标签: android matrix canvas coordinates touch-event


    【解决方案1】:

    只需要将屏幕坐标转换为修改后的画布坐标即可:

    //如果我已经移动(翻译)了画布:TouchX = TouchX-translatedX; TouchY=TouchY - 翻译Y;

    // 如果我缩放了画布:TouchX = TouchX/scaleFactor; TouchY = TouchY/scaleFactor;

    //如果我已经平移和移动了画布:TouchX= (TouchX-translatedX)/scaleFactor; TouchY = (TouchY-translatedY)/scaleFactor;

    //然后我们应该用这个TouchX和TouchY进行绘制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-27
      • 2016-01-01
      • 2012-03-07
      • 2016-11-11
      • 2016-10-29
      • 2021-11-18
      相关资源
      最近更新 更多