1

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 e.g. 100px to the right, dragOffX gets the value 100.

How do I translate my canvas to the correct coordinates?

Standard
  • 1,450
  • 17
  • 35
  • I think you need to show a bit more code, like how you are translating the canvas in the first place. – Stuart Dec 16 '15 at 19:35
  • Here's a simple zooming technique that does not use translations: http://stackoverflow.com/questions/27339747/zoom-and-pan-in-animated-html5-canvas/27340533#27340533 – markE Dec 16 '15 at 20:12

2 Answers2

1

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

Stuart
  • 9,597
  • 1
  • 21
  • 30
0

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);
 }
Scarecrow
  • 4,057
  • 3
  • 30
  • 56