Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to zoom in and center on an object with fabricjs?

I would like to be able to click on an object, and have it zoomed to its boundingbox in the canvas viewport. How do I accomplish that? See http://jsfiddle.net/tinodb/qv989nzs/8/ for what I would like to get working.

Fabricjs' canvas has the zoomToPoint method (about which the docs say: Sets zoom level of this canvas instance, zoom centered around point), but that does not center to the given point, but it does work for zooming with scrolling. See http://jsfiddle.net/qv989nzs/

I tried several other approaches, like using canvas.setViewportTransform:

// centers a circle positioned at (200, 150)??
canvas.setViewportTransform([2, 0, 0, 2, -250, -150]) 

But I can't find the relation between the last two parameters to setViewportTransform and the position of the object.

(Btw, another problem is with the first example fiddle, that the zooming only works on the first click. Why is that?)

like image 926
Tino Avatar asked Aug 25 '15 15:08

Tino


2 Answers

I found a way to do this, which is composed of:

canvas.setZoom(1)  // reset zoom so pan actions work as expected
vpw = canvas.width / zoom
vph = canvas.height / zoom
x = (object.left - vpw / 2)  // x is the location where the top left of the viewport should be
y = (object.top - vph / 2)  // y idem
canvas.absolutePan({x:x, y:y})
canvas.setZoom(zoom)

See http://jsfiddle.net/tinodb/4Le8n5xd/ for a working example.

I was unable to get it to work with zoomToPoint and setViewportTransform (the latter of which does strange things, see for example http://jsfiddle.net/qv989nzs/9/ and click the blue circle; it is supposed to put the top left viewport at (25, 25), but it does not)

like image 172
Tino Avatar answered Oct 25 '22 16:10

Tino


Here's an example of how to do it with setViewportTransform:

// first set the zoom, x, and y coordinates
var zoomLevel = 2;
var objectLeft = 250;
var objectTop  = 150;

// then calculate the offset based on canvas size
var newLeft = (-objectLeft * zoomLevel) + canvas.width  / 2;
var newTop  = (-objectTop  * zoomLevel) + canvas.height / 2;

// update the canvas viewport
canvas.setViewportTransform([zoomLevel, 0, 0, zoomLevel, newLeft, newTop]);
like image 24
Lauren Avatar answered Oct 25 '22 17:10

Lauren