自定义视图中的居中缩放 - 计算画布坐标

发布于 2024-10-24 04:22:23 字数 876 浏览 0 评论 0原文

我正在开发我的第一个“真正的”Android 应用程序,一个图形工作流程编辑器。绘图是在自定义类中完成的,该类是 View 的子类。目前我的元素是在画布上绘制的矩形。为了检测元素上的操作,我比较坐标并检查触摸位置上的元素。

为了实现缩放手势,我尝试了 http://android- Developers.blogspot.com/2010/06/making-sense-of-multitouch.html

使用 4 个参数 canvas.scale(...) 函数,居中缩放效果很好,但我失去了计算画布坐标使用 mPosX 和 mPosY 的偏移量来检测缩放后的触摸是否在元素上。

我尝试更改上面博客文章中的示例,以使画布在缩放手势上居中:

canvas.save();
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor, mScalePivotX, mScalePivotY);
//drawing ....
canvas.restore();

我没有找到任何有关如何在不丢失计算坐标的参考偏移的情况下完成此操作的示例。有一个简单的解决方法吗?我尝试使用手势中心和缩放因子计算偏移量,但失败了:/

我看到其他使用 ImageView 的示例通常使用 Matrix 来转换图像。这可以通过自定义视图和画布来完成吗?如果是,如何获取 x 和 y 偏移量来检查坐标?

另外,如果我的想法完全错误,我会很高兴看到一些关于如何正确完成此操作的示例。

谢谢! ;)

I am working on my first "real" Android application, a graphical workflow editor. The drawing is done in a custom class, that is a subclass of View.At the moment my elements are rectangles, which are drawn on a canvas. To detect actions on elements I compare the coordinates and check for elements on the touch location.

To implement a zoom gesture I tried http://android-developers.blogspot.com/2010/06/making-sense-of-multitouch.html

With the 4 argument canvas.scale(...) function the centered zooming works well, but I lose the ability to calculate the canvas coordinates using the offset with mPosX and mPosY to detect if the touch after a zoom is on an element.

I tried to change the example in the blogpost above to center the canvas on the zoom gesture with:

canvas.save();
canvas.translate(mPosX, mPosY);
canvas.scale(mScaleFactor, mScaleFactor, mScalePivotX, mScalePivotY);
//drawing ....
canvas.restore();

I did not find any examples on how this could be done without losing the reference offset to calculate the coordinates. Is there an easy workaround? I tried to calculate the offset with the gesture center and the scaling factor, but failed :/

I have seen that other examples which use an ImageView often use a Matrix to transform the image. Could this be done with a custom View and a Canvas? If yes, how can I get the x and y offset to check the coordinates?

Also, if my ideas are completely wrong, I would be very happy to see some examples on how this is done properly.

Thx! ;)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

窗影残 2024-10-31 04:22:23

也许下面的代码将帮助您计算手势中心的坐标和缩放因子。我在代表 opengl-sprite 的类中使用此方法。

void zoom(float scale, PointF midPoint) {
    if (zoomFactor == MAX_ZOOM_FACTOR && scale > 1) return;
    if (zoomFactor == MIN_ZOOM_FACTOR && scale < 1) return;

    zoomFactor *= scale;
    x = (x - midPoint.x) * scale + midPoint.x;
    y = (y - height + midPoint.y) * scale + height - midPoint.y;
    if (zoomFactor >= MAX_ZOOM_FACTOR) {
        zoomFactor = MAX_ZOOM_FACTOR;
    } else if (zoomFactor < MIN_ZOOM_FACTOR) {
        zoomFactor = MIN_ZOOM_FACTOR;
        x = 0;
        y = 0;
    }
}

由于opengl坐标系(右上)和midPoint坐标系(右下)方向的区别,X和Y坐标的处理方式不同。 midPoint 取自 MotionEvent 的坐标。

我认为所有其他操作都是可以理解的。

希望它能帮助你。

Perhaps the following code will help you to calculate coordinates with the gesture center and the scaling factor. I use this method in my class representing opengl-sprite.

void zoom(float scale, PointF midPoint) {
    if (zoomFactor == MAX_ZOOM_FACTOR && scale > 1) return;
    if (zoomFactor == MIN_ZOOM_FACTOR && scale < 1) return;

    zoomFactor *= scale;
    x = (x - midPoint.x) * scale + midPoint.x;
    y = (y - height + midPoint.y) * scale + height - midPoint.y;
    if (zoomFactor >= MAX_ZOOM_FACTOR) {
        zoomFactor = MAX_ZOOM_FACTOR;
    } else if (zoomFactor < MIN_ZOOM_FACTOR) {
        zoomFactor = MIN_ZOOM_FACTOR;
        x = 0;
        y = 0;
    }
}

X and Y coordinates are processed in different ways, because of distinction between directions of opengl coordinate system (right and up) and midPoint's coordinate system (right and down). midPoint is taken from MotionEvents coordinates.

All other operations are understandable, i think.

Hope it will help you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文