多点触控,平移,放大HTML 5画布

时间:2012-09-24 22:58:11

标签: javascript javascript-events mobile-safari

我编写了大部分模块来处理HTML 5 canvas元素上的多点触控,平移和缩放。我将在下面分享。我已经用JavaScript开发了一段时间了,这个继续困扰我。如果有人有任何见解,我会在堆栈上发布最终版本,以便每个人在我的iPad上确认工作后分享。

这是我正在做的事情:

touchmove个事件会触发变量的更改。我使用这些变量来改变我的图像绘制到画布上的方式。我有八个变量,每个变量对应于可以放入 drawImage()函数的选项。这八个变量通过增加/减少其值并将它们保持在一定范围内的函数进行更新。变量是闭包变量,因此它们在我的模块中是全局的。为了防止过度处理,我每隔40ms调用一次此 drawImage()函数,同时用户用 setInterval()将手指按到屏幕上。 这是问题所在:

touchmove事件似乎导致竞争条件,其中我的变量由同一事件的许多不同实例更新。我可以通过我的控制台输出来确认这一点,它跟踪一个限制为永远不会低于20的变量。当我快速向一个方向滑动时,该变量下降到远低于20.然后当我松开手指时,慢慢地滑动,它另一件事指向了这个方向,当我在单步执行程序时查看这些变量时,它们与我的console.log()抽出的不同。

注意:代码第一次成功绘制图像,但之后不再成功。我的代码的基本演绎如下......完整版本位于Scripts文件夹中的GitHub。它是一款Sencha Touch v1.1应用程序

function PinchPanZoomFile(config)
{
    /*
     * Closure variable declaration here...
     * Canvas Declaration here...
    */

    function handleTouchStart(e) {
        whatDown.oneDown = (e.originalEvent.targetTouches.length == 1) ? true : false;
        whatDown.twoDown = (e.originalEvent.targetTouches.length >= 2) ? true : false;

        drawInterval = setInterval(draw, 100);
    }

    function handleTouchEnd(e) {
        whatDown.oneDown = (e.originalEvent.targetTouches.length == 1) ? true : false;
        whatDown.twoDown = (e.originalEvent.targetTouches.length >= 2) ? true : false;
        clearInterval(drawInterval);
    }

    function handleTouchMove(e) {
        if(whatDown.twoDown) {
            /*
             * Do Panning & Zooming
            */  
            changeWindowXBy(deltaDistance); //deltaDistance
            changeWindowYBy(deltaDistance); //deltaDistance
            changeCanvasXBy(deltaX); //Pan
            changeCanvasYBy(deltaY); //Pan
            changeWindowDimsBy(deltaDistance*-1,deltaDistance*-1); //(deltaDistance)*-1 -- get smaller when zooming in.
            changeCanvasWindowDimsBy(deltaDistance,deltaDistance); //deltaDistance -- get bigger when zooming in

        } else if(whatDown.oneDown) {
            /*
             * Do Panning
            */
            changeWindowXBy(0);
            changeWindowYBy(0);
            changeCanvasXBy(deltaX);
            changeCanvasYBy(deltaY);
            changeWindowDimsBy(0,0);
            changeCanvasWindowDimsBy(0,0);
        }
    }

    function draw() {
        //Draw Image Off Screen
        var offScreenCtx = offScreenCanvas[0].getContext('2d');
        offScreenCtx.save();
        offScreenCtx.clearRect(0, 0, canvasWidth, canvasHeight);
        offScreenCtx.restore();
        offScreenCtx.drawImage(base64Image, 
            parseInt(windowX), 
            parseInt(windowY), 
            parseInt(windowWidth), 
            parseInt(windowHeight), 
            parseInt(canvasX), 
            parseInt(canvasY), 
            parseInt(canvasWindowWidth), 
            parseInt(canvasWindowHeight)
        );

        //Draw Image On Screen
        var offScreenImageData = offScreenCtx.getImageData(0, 0, canvasWidth, canvasHeight);
        var onScreenCtx = canvas[0].getContext('2d');
        onScreenCtx.putImageData(offScreenImageData, 0, 0);
    }
}

1 个答案:

答案 0 :(得分:2)

我强烈建议使用Sencha Touch 2.0.1,因为它支持您需要的许多触摸事件。有关示例,请参阅http://dev.sencha.com/deploy/touch/examples/production/kitchensink/#demo/touchevents