开发者

centered zoom in custom view - calculating canvas coordinates

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 t开发者_C百科he 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! ;)


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜