1

我编写了大部分模块来处理 HTML 5 画布元素上的多点触控捏合、平移和缩放。我将在下面分享。我已经用 JavaScript 开发了一段时间了,而这个仍然让我感到困惑。如果有人有任何见解,一旦确认在我的 iPad 上工作,我会将最终版本发布到堆栈上供大家分享。

这是我正在做的事情:

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

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

注意:代码第一次成功绘制了图像,但之后的任何时候都没有。下面是我的代码的基本版本......完整版本在GitHub 上的 Scripts 文件夹中。它本质上是一个 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);
    }
}
4

1 回答 1

2

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

于 2012-10-18T01:09:13.417 回答