Looking for iTransit? Check two posts down.
–
Been playing with touches in Safari, specifically trying to track certain gestures.
If you haven’t read it, a good primer on touches/gestures in Mobile Safari can be found here. Its a great starting point.
So now that the its been established as to how to do Drag and Drop and rotating/scaling what about the other one finger gestures that apple employs?
Specifically, I’m trying to replicate the swipe left and right functionality of the photo browser (show previous/next photos), and I’ve been able to do so.
The trick here is to catch the initial touch event, and the ending touch event and work out where our finger has gone. A key thing to remember is that the touches are passed around and updated by reference, so your original copy of the touch will be updated with a new position.
What I’ve ended up with is a small class that watches the touchstart and touchend events on the document level, and when it detects a swipe it fires a gesture:swipe event.
How?
The following is the code that I used, you’ll need Prototype to make this work.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
var GestureClass = Class.create
({
// Fired when a new instance of this object is made
initialize: function ()
{
// listen for start/stop events
document.observe('touchstart', this.start.bind(this));
document.observe('touchend', this.end.bind(this));
// touch storage
this.gestures = [];
},
start: function (e)
{
// currently only support one finger on the viewport
if (e.touches.length == 1)
{
var touch = e.touches[0];
// store the touch for later
this.gestures[touch.identifier] = Object.clone(touch);
this.gestures[touch.identifier].date = new Date();
}
},
end: function (e)
{
// still only one finger
if (e.changedTouches.length == 1)
{
// get the most recent touch
var end = e.changedTouches[0];
end.date = new Date();
// get the position that we started at
var start = this.gestures[end.identifier];
// and the duration of our swipe? number of milliseconds the gesture took
var duration = end.date.getTime() - start.date.getTime();
// calculate offsets
var horizontalMovement = start.clientX - end.clientX;
var verticalMovement = start.clientY - end.clientY;
// big enoug to count as a swipe? and quick enough
var viewport = document.viewport.getDimensions();
if (Math.abs(horizontalMovement) >= (viewport.width/2) && duration <= 800)
{
// this object is passed to the new event under the 'memo' property
var gesture =
{
start: start,
end: end,
gesture: 'swipe',
direction: (horizontalMovement >= 0 ? 'left' : 'right')
};
// Fire the gesture, listen with document.observe('gesture:swipe', <function>);
document.fire('gesture:swipe', gesture);
}
}
},
});
var Gestures = new GestureClass(); |
Is that documented enough to make sense? Drop me a line in the comments if not and I’ll see what I can do to explain better
You’ll see this gesture used in the new version of iTransit, naturally – and there’s more gestures to come!
Cheers,
-bok