When you have a canvas and you fill it with a drawing, you may want to view that drawing at a different zoom/scales (using scroll wheel) (such as if you were on a device with a lower screen resolution). A user may also want to pan around the screen (using middle mouse button and moving mouse).
Searching online provides no clear way of handling this gracefully and it seems to me like an obvious use case of paper.js so I expected to see some event handling for it baked into paper.js, am I missing something obvious and being blind here?
Cheers
Also curious
I've had success using the implementation described here - http://matthiasberth.com/articles/stable-zoom-and-pan-in-paperjs/
this would be a useful feature
You can inspect the main.js of http://sketch.paperjs.org/ to see how I've handled it there. Here the crucial part, especially the mousedrag handler, but the rest may be of use too:
js
var lastPoint;
var body = $('body');
zoomTool = new Tool({
buttonClass: 'icon-zoom'
}).on({
mousedown: function(event) {
if (event.modifiers.space) {
lastPoint = paper.view.projectToView(event.point);
return;
}
var factor = 1.25;
if (event.modifiers.alt)
factor = 1 / factor;
paper.view.zoom *= factor;
paper.view.center = event.point;
},
keydown: function(event) {
if (event.key === 'alt') {
body.addClass('zoom-out');
} else if (event.key === 'space') {
body.addClass('zoom-move');
}
},
keyup: function(event) {
if (event.key === 'alt') {
body.removeClass('zoom-out');
} else if (event.key === 'space') {
body.removeClass('zoom-move');
}
},
mousedrag: function(event) {
if (event.modifiers.space) {
body.addClass('zoom-grab');
// In order to have coordinate changes not mess up the
// dragging, we need to convert coordinates to view space,
// and then back to project space after the view space has
// changed.
var point = paper.view.projectToView(event.point),
last = paper.view.viewToProject(lastPoint);
paper.view.scrollBy(last.subtract(event.point));
lastPoint = point;
}
},
mouseup: function(event) {
body.removeClass('zoom-grab');
},
activate: function() {
body.addClass('zoom');
},
deactivate: function() {
body.removeClass('zoom');
}
});
Well, I got to know about Paper.js, and Sketch today - and I like it!
But literally the first thing I noticed is the very odd zoom behaviour in Sketch!
The intuitive thing, IMHO, is that it zooms into and out of the cursor - what else?!
Or, to put it mathematically: to have the fixpoint of the zoom exactly at the cursor location.
Btw.: in the current Sketch using 0.11.8 it's scope.view.xyz rather than paper.view.xyz as above.
So: in the mousedown handler replace
scope.view.center = event.point;
by
var c = scope.view.center,
p = event.point,
d = p.substract(c); // distance in project coords
scope.view.center = c.add(d.multiply((factor - 1) / factor));
Hmm, maybe I should make a sketch to demonstrate and explain...?
Most helpful comment
You can inspect the main.js of http://sketch.paperjs.org/ to see how I've handled it there. Here the crucial part, especially the
mousedraghandler, but the rest may be of use too:js var lastPoint; var body = $('body'); zoomTool = new Tool({ buttonClass: 'icon-zoom' }).on({ mousedown: function(event) { if (event.modifiers.space) { lastPoint = paper.view.projectToView(event.point); return; } var factor = 1.25; if (event.modifiers.alt) factor = 1 / factor; paper.view.zoom *= factor; paper.view.center = event.point; }, keydown: function(event) { if (event.key === 'alt') { body.addClass('zoom-out'); } else if (event.key === 'space') { body.addClass('zoom-move'); } }, keyup: function(event) { if (event.key === 'alt') { body.removeClass('zoom-out'); } else if (event.key === 'space') { body.removeClass('zoom-move'); } }, mousedrag: function(event) { if (event.modifiers.space) { body.addClass('zoom-grab'); // In order to have coordinate changes not mess up the // dragging, we need to convert coordinates to view space, // and then back to project space after the view space has // changed. var point = paper.view.projectToView(event.point), last = paper.view.viewToProject(lastPoint); paper.view.scrollBy(last.subtract(event.point)); lastPoint = point; } }, mouseup: function(event) { body.removeClass('zoom-grab'); }, activate: function() { body.addClass('zoom'); }, deactivate: function() { body.removeClass('zoom'); } });