我编写了大部分模块来处理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);
}
}
答案 0 :(得分:2)
我强烈建议使用Sencha Touch 2.0.1,因为它支持您需要的许多触摸事件。有关示例,请参阅http://dev.sencha.com/deploy/touch/examples/production/kitchensink/#demo/touchevents。