This is the second time I’ve typed this. For some reason, WordPress musn’t have liked the first attempt, and so trashed it - which is annoying!
I’ve been playing with gestures on HTML5, and encountered a strange problem (this may be peculiar to Windows 8, but I doubt it). Here’s the scenario:
The Problem
You have an app (remember that we’re talking about Windows 8). In the app, you have a particular response to a swipe gesture: say you want to record the swipe distance; and to react to a tap / touch gesture. This works for mouse events, too.
Here’s some code:
[sourcecode language=“html”]
Yeah - I know, you're wondering how I ever managed to get so good at HTML5!
Here's some more interesting code:
[sourcecode language="javascript"]
var canvas;
var canvasContext;
var initialiseApp = function () {
canvas = document.getElementById("mainCanvas");
canvasContext = canvas.getContext("2d");
canvas.width = window.outerWidth;
canvas.height = window.outerHeight;
// define GestureRecognizer
var recognizer = new Windows.UI.Input.GestureRecognizer();
recognizer.gestureSettings = Windows.UI.Input.GestureSettings.manipulationTranslateX
recognizer.addEventListener('manipulationcompleted', function (e) {
var dx = e.cumulative.translation.x
canvasContext.clearRect(0, 0, 1000, 20);
canvasContext.fillStyle = "#2F1BE0";
canvasContext.fillText('manipulationcompleted ' + Date.now(), 10, 10);
});
// actual element which feeds the GestureRecognizer
var processUp = function (evt) {
try {
recognizer.processUpEvent(evt.currentPoint);
canvasContext.clearRect(10, 90, 1000, 50);
canvasContext.fillStyle = "#2F1BE0";
canvasContext.fillText('processUp' + Date.now(), 10, 100);
}
catch (e) { }
}
canvas.addEventListener('MSPointerDown', function (args) {
try {
recognizer.processDownEvent(args.currentPoint);
canvasContext.clearRect(10, 190, 1000, 20);
canvasContext.fillStyle = "#2F1BE0";
canvasContext.fillText('processDown' + Date.now(), 10, 200);
}
catch (e) { }
}, false);
canvas.addEventListener('MSPointerMove', function (args) {
try {
recognizer.processMoveEvents(args.intermediatePoints);
canvasContext.clearRect(10, 250, 1000, 200);
canvasContext.fillStyle = "#2F1BE0";
canvasContext.fillText('processMove' + Date.now(), 10, 300);
}
catch (e) { }
}, false);
canvas.addEventListener('MSPointerUp', processUp, false);
canvas.addEventListener('MSPointerCancel', processUp, false);
}
If you try that, you’ll notice something… or at least you will now I’ve told you to. That is that if you click / touch then you get a mouse up, but if you swipe then you get a mouse up and a manipulationcomplete! Good God - BOTH! But what if you only want to react to one? Say you have a fishing game, and the swipe casts the … err fishing string thingy, and the touch reels the … err… okay, maybe I should have picked an example I know something about, but you get the idea.
The Solution
I don’t like it, but here’s my answer to that particular conundrum:
[sourcecode language=“javascript”] var canvas; var canvasContext; var eventFlag = 0;
var initialiseApp = function () {
canvas = document.getElementById("mainCanvas");
canvasContext = canvas.getContext("2d");
canvas.width = window.outerWidth;
canvas.height = window.outerHeight;
// define GestureRecognizer
var recognizer = new Windows.UI.Input.GestureRecognizer();
recognizer.gestureSettings = Windows.UI.Input.GestureSettings.manipulationTranslateX
recognizer.addEventListener('manipulationcompleted', function (e) {
var dx = e.cumulative.translation.x
canvasContext.clearRect(0, 0, 1000, 20);
canvasContext.fillStyle = "#2F1BE0";
canvasContext.fillText('manipulationcompleted ' + Date.now(), 10, 10);
eventFlag = 1;
});
// actual element which feeds the GestureRecognizer
var processUp = function (evt) {
try {
recognizer.processUpEvent(evt.currentPoint);
if (eventFlag == 0) {
canvasContext.clearRect(10, 90, 1000, 50);
canvasContext.fillStyle = "#2F1BE0";
canvasContext.fillText('processUp' + Date.now(), 10, 100);
} else {
eventFlag = 0;
}
}
catch (e) { } // translateYfails ?!
}
So we have a flag, and only do something based on the flag.
Conclusion
If there's a better way of doing this then I'd like to hear. It would be particularly nice if you could get the return value of processUpEvent, or set some kind of handled flag. Having said that, this does work.