2

I am using setTransform to scale my background pattern image. The scale starts from 1, and every time the scale decreases 0.01, until it reaches 0.5.

So here is the scaling code:

context.setTransform(scale, 0, 0, scale, position.x, position.y);

In the update:

scale -= 0.01;

Using the above code, when I animate the changes the background pattern image is replaced with the scaled pattern image correctly. However the transition isn't very smooth. It works like the image suddenly flashed to another image in a short time but noticeable. I want the replacement to be smoother and unnoticeable but I have no idea how to achieve that effect.

Gruber
  • 2,196
  • 5
  • 28
  • 50
newguy
  • 5,668
  • 12
  • 55
  • 95

2 Answers2

0

You can use translate() instead of setTransform()

ctx.translate(pt.x,pt.y);
ctx.scale(factor,factor);
ctx.translate(-pt.x,-pt.y);

In short, you want to translate() the canvas context by your offset, scale() it to zoom in or out, and then translate() back by the opposite of the mouse offset. Note that you need to transform the cursor position from screen space into the transformed canvas context.

Check this question for more information and live examples.

Community
  • 1
  • 1
semanser
  • 2,310
  • 2
  • 15
  • 33
  • What is the difference between `translate` and `setTransform`? If I use translate don't I need to save and restore the context? – newguy Jul 12 '16 at 17:17
  • @newguy You don't need to save and restore context. What you need it's to transform the cursor position from screen space into the transformed canvas context and after that redraw all canvas context. See how it smoothly work in example: http://phrogz.net/tmp/canvas_zoom_to_cursor.html Try to check code of this example. It's really simple. – semanser Jul 12 '16 at 17:20
  • I have tried using `translate` but it gave me the same effect. I can notice a sudden move. Maybe I haven't put the correct position? – newguy Jul 12 '16 at 17:28
  • how do you calculate position? – semanser Jul 12 '16 at 17:32
0

You can use setTransform

The first two numbers are the direction and length (scale) of the x axis, the next two are the direction and length of the y axis and the last two are the location of the origin.

The quickest way to set translation, scale, and rotation

var scale = ?
var originX = ?
var originY = ?
var rotation = ?
ctx.setTransform(scale,0,0,scale,originX,originY);
ctx.rotate(rotation);

or you can set the rotation in the setTransform by calculating the axis directions

var scale = ?
var originX = ?
var originY = ?
var rotation = ?
// get the x axis direction and length
var xdx = Math.cos(rotation) * scale;
var xdy = Math.sin(rotation) * scale;
// if you are not skewing then the y axis is at 90deg so x is neg y and y is x
ctx.setTransform(xdx,xdy,-xdy,xdx,originX,originY);

Then if you need to restore to the default transform

ctx.setTransform(1,0,0,1,0,0); // restore default transform

All the values for setTransform are in pixels and set transform basically describes where and what shape the renderer will create the pixel at 0,0

Smoothing out the pan and zoom.

This answer goes into more depth and gives a working example of using the mouse to scale and zoom a image using the mouse via setTransform (no need to use save restore) It also shows how to smooth the zoom and pan Pan and Zoom

Community
  • 1
  • 1
Blindman67
  • 51,134
  • 11
  • 73
  • 136