Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 缩放和画布-缩放图像后如何调整原点?_Android_Canvas_Android Canvas_Scale_Onscroll - Fatal编程技术网

Android 缩放和画布-缩放图像后如何调整原点?

Android 缩放和画布-缩放图像后如何调整原点?,android,canvas,android-canvas,scale,onscroll,Android,Canvas,Android Canvas,Scale,Onscroll,我有一个带有自定义组件的非常简单的测试应用程序,它显示一个可滚动和可缩放的图像(在类似拼字游戏的文字游戏中代表一个棋盘): 1) 在“比例侦听器”中,我调整比例因子: public boolean onScale(ScaleGestureDetector detector) { mScale *= detector.getScaleFactor(); // XXX how to adjust mOffsetX and mOffsetY ? XXX constrain

我有一个带有自定义组件的非常简单的测试应用程序,它显示一个可滚动和可缩放的图像(在类似拼字游戏的文字游戏中代表一个棋盘):

1) 在“比例侦听器”中,我调整比例因子:

public boolean onScale(ScaleGestureDetector detector) {
    mScale *= detector.getScaleFactor();

    // XXX how to adjust mOffsetX and mOffsetY ? XXX

    constrainZoom();
    constrainOffsets();
    invalidate();
    return true;
}
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.translate(mOffsetX, mOffsetY);
    canvas.scale(mScale, mScale);
    gameBoard.setBounds(
        0, 
        0, 
        gameBoard.getIntrinsicWidth(),
        gameBoard.getIntrinsicHeight()
    );
    gameBoard.draw(canvas);  
}
2) 然后在自定义组件的绘图方法中,我应用平移和比例因子:

public boolean onScale(ScaleGestureDetector detector) {
    mScale *= detector.getScaleFactor();

    // XXX how to adjust mOffsetX and mOffsetY ? XXX

    constrainZoom();
    constrainOffsets();
    invalidate();
    return true;
}
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.translate(mOffsetX, mOffsetY);
    canvas.scale(mScale, mScale);
    gameBoard.setBounds(
        0, 
        0, 
        gameBoard.getIntrinsicWidth(),
        gameBoard.getIntrinsicHeight()
    );
    gameBoard.draw(canvas);  
}
不幸的是,当用捏手势缩放时,似乎有一个小错误-

我可以看到,缩放后的比例和边界大小正确,但图像的偏移量不正确

当挤压手势的焦点远离屏幕的0,0点时,问题会变得更糟

用文字描述这个问题有点困难,但当您签出时,您会立即看到它(并且您可以随时双击重置偏移和比例)

这可能是一个常见的问题,有一个标准的解决方法,但我还没有找到它


电路板图像为,代码基于博客。

您将画布移动两次:首先使用
翻译
,然后使用
缩放(sx、sy、px、py)


您可以将焦点与
onScale
中的偏移相结合,然后使用
scale(sx,sy)

而不是画布。translate/scale/rotate使用矩阵,使用一个矩阵对象更容易,它也可以用于两个不同系统(Matrix.mapPoints)之间的映射@为什么它比在画布中使用本机矩阵更好?例如,请参阅我在这里的答案:,关于如何缩放、旋转和转换图像,所有这些都由一个矩阵控制谢谢,但您的源代码似乎太高级了,无法解决我的小问题。我有一种感觉,我只需要在我的
onScale
方法中调整
mOffsetX
mOffsetY
(基于
scale
?可能在手势的焦点上?),这就足够了。不,不,不太高级,例如,您可以通过调用Matrix.mapRect+1来获得游戏板的最终可绘制边界。感谢您的宝贵评论,但我不知道如何正确组合
offsetX
focusX
?可能最容易将缩放、偏移和焦点(currentGestureFocus)作为单独的变量。然后在一个手势持续时间内跟踪焦点(从
onScaleBegin
onScaleEnd
)。在缩放结束时,将焦点添加到偏移。在手势过程中,应在onDraw处添加偏移和焦点。请记住,焦点需要与当前手势和屏幕中心成比例。矩阵将更容易,因为它可以更好地处理链接,但强制执行边界则更难。希望这是有意义的。