Search code examples
createjs

Is pinch zoom supported in CreateJS?


Is the pinch zoom touch gesture supported in CreateJS? I can not find anything in the docs.

Thanks


Solution

  • There is no native support for gestures but once you enable it touch events are translated into mouse events and identified by pointerID property. Based on this I have been able implemented the pinch zoom gesture in my project (though I have not tested it beyond latest Android.)

    This is a snippet from my project:

    stage.on("mousedown", function (evt : createjs.MouseEvent) {
        if (evt.pointerID == 0 || evt.pointerID == -1) { //touch 1 or mouse
            touch1 = new createjs.Point(stage.globalToLocal(evt.stageX, 0).x, stage.globalToLocal(0, evt.stageY).y);
        } else if (evt.pointerID == 1) { //touch 2
            touch2 = new createjs.Point(stage.globalToLocal(evt.stageX, 0).x, stage.globalToLocal(0, evt.stageY).y);
        }
    });
    
    stage.on("pressup", function (evt : createjs.MouseEvent) {
        if (evt.pointerID == 0 || evt.pointerID == -1) { //touch 1 or mouse
            touch1 = null;
        } else if (evt.pointerID == 1) { //touch 2
            touch2 = null;
        }
    });
    
    stage.on("pressmove", function(evt : createjs.MouseEvent) {
        if (evt.pointerID == -1 || evt.pointerID == 0) {
            var touch = touch1;
        } else if (evt.pointerID == 1) {
            var touch = touch2;
        }
    
        var dX = stage.globalToLocal(evt.stageX, 0).x - touch.x;
        var dY = stage.globalToLocal(0, evt.stageY).y - touch.y;
    
        if (touch1 && touch2) var oldDist = distanceP(touch1, touch2);
    
        touch.x += dX;
        touch.y += dY;
    
        //if both fingers are used zoom and move the canvas
        if (touch1 && touch2) {
            var newDist = distanceP(touch1, touch2);
            var newZoom = zoom * newDist / oldDist;
            zoomMap(newZoom, new createjs.Point((touch1.x+touch2.x)/2, (touch1.y + touch2.y)/2))
    
            //if both fingers are used apply only half of the motion to each of them
            dX /= 2;
            dY /= 2;
        }
    
        map.x += dX;
        map.y += dY;
    
        stage.update();
    });
    
    function distanceP(p1 : createjs.Point, p2 : createjs.Point) : number {
        return Math.sqrt((p2.x-p1.x)*(p2.x-p1.x) + (p2.y-p1.y)*(p2.y-p1.y));
    }
    
    function zoomMap(newZoom : number, zoomCenter : createjs.Point) {
        ....
    }
    

    NOTE: I am moving and zooming DO called Map. The stage itself is zoomed due to various devicePixelRatio's (retina display etc), that's why the use of globalToLocal functions.