画布捏缩放问题(轴心点)

时间:2014-02-09 17:50:01

标签: android graphics drawing android-canvas android-view

我在自定义视图上绘制线条并添加了平移和缩放功能。 问题是,当我用两根手指放大时,中间点会被正确计算,但是当我执行matrix.scale(scaleFactor, scaleFactor, midX, midY)时,画布会跳转(翻译)到midXmidY。之前。

让我直截了当地说:

我用0/0初始化我的手指之间的中点。一旦第二个指针出现在屏幕上,我就会计算中点并使onDraw无效。然后绘图跳转(翻译)到最后一个已知的中点并开始放大。 我不希望将绘图转换到中点而不是仅缩放到选定的中点。

以下是相关的代码段:

onDraw方法

private float startX = 0f;
private float startY = 0f;

private float translateX;
private float translateY;

private float previousTranslateX = 0f;
private float previousTranslateY = 0f;

private float midX = 0f;
private float midY = 0f;
...

public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    cx = canvas.getWidth();
    cy = canvas.getHeight();

    mat.reset();

    canvas.save();

    int count = 0; 

    mat.postScale(scaleFactor, -scaleFactor, midX, midY);           
    mat.postTranslate(translateX, translateY);

    canvas.setMatrix(mat);

    // draw stuff here...

    canvas.restore();
}

onTouch方法

public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:

        mode = DRAG;
        startX = event.getX() - previousTranslateX;
        startY = event.getY() - previousTranslateY;

        break;

    case MotionEvent.ACTION_MOVE:

        if (event.getPointerCount() > 1) {
            mode = ZOOM;
        } else {
            translateX = event.getX() - startX;
            translateY = event.getY() - startY;
        }

        break;

    case MotionEvent.ACTION_POINTER_DOWN:

            mode = NONE;
            getMidPoint(event);

        break;

    case MotionEvent.ACTION_UP:

        mode = NONE;
        previousTranslateX = translateX;
        previousTranslateY = translateY;

        break;

    case MotionEvent.ACTION_POINTER_UP:

        mode = DRAG;
        previousTranslateX = translateX;
        previousTranslateY = translateY;

        break;
    }

    detector.onTouchEvent(event);

    if ((mode == DRAG) || mode == ZOOM) {
        invalidate();
    }

    return true;
}

计算中点

private void getMidPoint(MotionEvent event) {

    //get offset screensize -> canvas
    int offX = sx-cx;
    int offY = sy-cy;

    //get finger coordinates relative to offset
    f1x = event.getX(0)+offX;
    f1y = event.getY(0)+offY;
    f2x = event.getX(1)+offX;
    f2y = event.getY(1)+offY;

    midX = (f1x + f2x)/2;
    midY = (f1y + f2y)/2;

    //because my points are in a local coordinate system the 
 screen coordinates need to be mapped to current canvas matrix
    Matrix m = new Matrix(mat);
    m.invert(m);
    float[] touch = new float[] { midX, midY };
    m.mapPoints(touch);
    midX = touch[0];
    midY = touch[1];
}

以下是一些图片: 这是活动开始的时候。红点标记初始化中点的0/0位置

只要把我的手指放在蓝点的位置并开始缩放:

这将是结果。一旦我开始变焦,就会发生这种情况。

如果有人对我有答案,我真的很感激!提前致谢。

0 个答案:

没有答案