![](/img/trans.png)
[英]Drawing on HTML5 Canvas with support for multitouch pinch, pan, and zoom
[英]Multitouch Pinch, Pan, Zoom in HTML 5 Canvas
我編寫了大部分模塊來處理 HTML 5 畫布元素上的多點觸控捏合、平移和縮放。 下面我來分享一下。 我已經用 JavaScript 開發一段時間了,這個問題繼續讓我感到困惑。 如果有人有任何見解,一旦確認可以在我的 iPad 上運行,我會將最終版本發布到堆棧上供大家分享。
這是我在做什么:
touchmove
事件觸發變量的變化。 我使用這些變量來改變我的圖像在畫布上的繪制方式。 我有八個變量,每個變量對應於可以放入drawImage()
函數的選項。 這八個變量通過增加/減少它們的值並將它們保持在一定范圍內的函數進行更新。 變量是閉包變量,因此它們在我的模塊中是全局的。 為了防止過度處理,我每 40 毫秒調用一次drawImage()
函數,同時用戶使用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);
}
}
我強烈推薦使用 Sencha Touch 2.0.1,因為它支持很多你需要的觸摸事件。 有關示例,請參閱http://dev.sencha.com/deploy/touch/examples/production/kitchensink/#demo/touchevents 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.