简体   繁体   中英

Zoom in in a canvas at a certain point

I try to let the user zoom in the canvas with a pinch gesture, it's a Javascript Canvas Game (using Intel XDK)

I got the point coordinates (relativley to the window document, saved in an array) and the scale "strength".

var scale = 1;
function scaleCanvas(sc, point) { //point["x"] == 200
            //sc has value like 0.5, 1, 1.5 and so on                
            x = sc/scale;
            scale = sc;

            ctx.scale(x, x);
 }

I know that I have to translate the canvas to the point coordinates, and then retranslate it again. My problem is, that the canvas is already translated. The translation values are saved in the vars dragOffX and dragOffY . Furthermore, the initial translation may be easy, but when the canvas is already scaled, every coordinate is changed.

This is the translation of the canvas when dragging/shifting the content:

var dragOffX = 0;
var dragOffY = 0;
function dragCanvas(x,y) {      

            dragOffX = dragOffX + x;
            dragOffY = dragOffY + y;

            x = x* 1/scale;
            y = y* 1/scale;
            ctx.translate(x,y);
}

So when the player is dragging the content for eg 100px to the right, dragOffX gets the value 100.

How do I translate my canvas to the correct coordinates?

Simply Use this to scale canvas on pivot point

  function scaleCanvasOnPivotPoint(s, p_x , p_y) { 
            ctx.translate(p_x, p_y);
            ctx.scale(s);
            ctx.translate( -p_x, -p_y);
 }

It will probably be easier if you store the transformation matrix and use setTransform each time you change it - that resets the canvas transformation matrix first before applying the new transformation, so that you have easier control over the way that the different transformations accumulate.

var transform = {x: 0, y: 0, scale: 1}
function scaleCanvas(scale, point) { 
    var oldScale = transform.scale;
    transform.scale = scale / transform.scale;

    // Re-centre the canvas around the zoom point
    // (This may need some adjustment to re-centre correctly)
    transform.x += point.x / transform.scale - point.x / oldScale
    transform.y += point.y / transform.scale - point.y / oldScale;

    setTransform();
}
function dragCanvas(x,y) {
    transform.x += x / transform.scale;
    transform.y += y / transform.scale;
    setTransform();
}
function setTransform() {
    ctx.setTransform(transform.scale, 0, 0, transform.scale, transform.x, transform.y);
}

JSFiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM