Search code examples
paperjs

Zoom and Pan fix


I'm trying to implement this solution that is in coffescript: https://matthiasberth.com/tech/stable-zoom-and-pan-in-paperjs.

I currently have:

var toolPan = new paper.Tool();
toolPan.onMouseDrag = function(event) {
    var a = event.downPoint.subtract(event.point);
    a = a.add(paper.view.center);
    paper.view.center = a;
};

window.addEventListener("wheel", function(e) {
    var dir = Math.sign(e.deltaY),
        factor = 1.05;

    if ( dir < 0 ) {
        paper.view.zoom *= factor;

    } else if ( dir > 0 ) {
        paper.view.zoom /= factor;
    }

    offset = new paper.Point(e.deltaX,-e.deltaY);
    offset = offset.multiply(factor);
    a = paper.view.center.add(offset);
    paper.view.center = a; 
});

The pan is working fine. The issue is with the zooming. It zooms but doesn't translate to the center. Is the math formula wrong?


Solution

  • It seemed to me that I already posted an answer to this question but I couldn't find it.
    Here is a discussion about the solution implemented in http://sketch.paperjs.org (about the zoom tool).
    And here is a fiddle demonstrating my implementation of the stable pan/zoom.

    // This controls the zoom intensity.
    var ZOOM_FACTOR = 1.5;
    
    // Draw a circle.
    new Path.Circle({
        center: view.center,
        radius: 50,
        fillColor: 'orange'
    });
    
    // On mouse drag...
    function onMouseDrag(event) {
        // ...update view center.
        paper.view.center = event.downPoint.subtract(event.point).add(paper.view.center);
    };
    
    // On mouse scroll...
    $('canvas').mousewheel(function(event) {
        // Store previous view state.
        var oldZoom = view.zoom;
        var oldCenter = view.center;
    
        // Get mouse position.
        // It needs to be converted into project coordinates system.
        var mousePosition = view.viewToProject(new Point(event.offsetX, event.offsetY));
    
        // Update view zoom.
        var newZoom = event.deltaY > 0
            ? oldZoom * ZOOM_FACTOR
            : oldZoom / ZOOM_FACTOR;
        view.zoom = newZoom;
    
        // Update view position.
        view.center += (mousePosition - oldCenter) * (1 - (oldZoom / newZoom));
    });