Permalink
Browse files

* move generation of hold, holdpulse, release, flick to drag module.

* release occurs only if a small hysterisis is satisfied
* flick event coordinates are now the location where the pointer went down rather than up.
* track drags with clientX/Y rather than pageX/Y for IE8 compatibility.
  • Loading branch information...
1 parent ad92d37 commit c078fdda6272b6da8ec36649f8cdc235add621b7 Steve Orvell committed Mar 21, 2012
Showing with 99 additions and 98 deletions.
  1. +97 −9 source/dom/drag.js
  2. +2 −89 source/dom/gesture.js
View
@@ -5,7 +5,14 @@
* "dragstart", "dragfinish" - sent for pointer moves that exceed a certain threshhold
* "drag", "drop" - sent to the original target of the pointer move to inform it about the item being moved over or released over another element
* "dragover", "dragout" - sent in addition to over and out when there is an active drag
- *
+
+ * "hold" - generated when the pointer is held down without moving for a short period (about 200ms).
+ * "release" - generated when the pointer is released after being held down, or the pointer is moved off of the node while still held down. The target is the same as the hold event.
+ * "holdpulse" - generated when the pointer is held down without moving for a short period and periodically thereafter about every 200ms.
+ Use this event to trigger an action after an arbitrary period of time. The holdTime property provides the elapsed time.
+ * "flick" - generated when the user flicks the pointer quickly. This event provides flick velocity data: xVelocity is the velocity in the horizontal and
+ yVelocity is the vertical velocity.
+
* Note: on Android, touchmove event must be prevented via inEvent.preventDefault() or will not fire more than once and enyo dragging system
* will not function correctly.
*/
@@ -24,24 +31,24 @@ enyo.dispatcher.features.push(
enyo.gesture.drag = {
//* @protected
hysteresis: 4,
+ holdPulseDelay: 200,
+ minFlick: 0.1,
+ minTrack: 8,
down: function(e) {
// tracking if the mouse is down
//console.log("tracking ON");
// Note: 'tracking' flag indicates interest in mousemove, it's turned off
// on mouseup
// make sure to stop dragging in case the up event was not received.
this.stopDragging(e);
- this.tracking = true;
+ this.cancelHold();
this.target = e.target;
- this.dispatchTarget = e.dispatchTarget;
- this.targetEvent = e;
- this.px0 = e.pageX;
- this.py0 = e.pageY;
+ this.startTracking(e);
+ this.beginHold(e);
},
move: function(e) {
if (this.tracking) {
- this.dx = e.pageX - this.px0;
- this.dy = e.pageY - this.py0;
+ this.track(e);
// If the mouse is not down and we're tracking a drag, abort.
// this error condition can occur on IE/Webkit after interaction with a scrollbar.
if (!e.which) {
@@ -54,12 +61,14 @@ enyo.gesture.drag = {
this.sendDrag(e);
} else if (Math.sqrt(this.dy*this.dy + this.dx*this.dx) >= this.hysteresis) {
this.sendDragStart(e);
+ this.cancelHold();
}
}
},
up: function(e) {
- this.tracking = false;
+ this.endTracking(e);
this.stopDragging(e);
+ this.cancelHold();
},
leave: function(e) {
if (this.dragEvent) {
@@ -85,6 +94,8 @@ enyo.gesture.drag = {
dy: this.dy,
pageX: inEvent.pageX,
pageY: inEvent.pageY,
+ clientX: inEvent.clientX,
+ clientY: inEvent.clientY,
horizontal: h,
vertical: !h,
lockable: l,
@@ -132,5 +143,82 @@ enyo.gesture.drag = {
e.preventTap && e.preventTap();
};
enyo.dispatch(synth);
+ },
+ startTracking: function(e) {
+ this.tracking = true;
+ // note: use clientX/Y to be compatible with ie8
+ this.px0 = e.clientX;
+ this.py0 = e.clientY;
+ this.flickInfo = {startEvent: e};
+ this.track(e);
+ },
+ track: function(e) {
+ this.dx = e.clientX - this.px0;
+ this.dy = e.clientY - this.py0;
+ //
+ var ti = this.flickInfo;
+ if (ti.d1) {
+ ti.d0 = ti.d1;
+ }
+ ti.d1 = {
+ x: e.clientX,
+ y: e.clientY,
+ t: enyo.now()
+ };
+ },
+ endTracking: function(e) {
+ this.tracking = false;
+ var ti = this.flickInfo;
+ if (ti && ti.d1 && ti.d0) {
+ var d1 = ti.d1, d0 = ti.d0;
+ // note: important to use up time to reduce flick
+ // velocity based on time between move and up.
+ var dt = enyo.now() - d0.t;
+ var x = (d1.x - d0.x) / dt;
+ var y = (d1.y - d0.y) / dt;
+ var v = Math.sqrt(x*x + y*y);
+ if (v > this.minFlick) {
+ // generate the flick using the start event so it has those coordinates
+ this.sendFlick(ti.startEvent, x, y, v);
+ }
+ }
+ this.flickInfo = null;
+ },
+ beginHold: function(e) {
+ this.holdStart = enyo.now();
+ this.holdJob = setInterval(enyo.bind(this, "sendHoldPulse", e), this.holdPulseDelay);
+ },
+ cancelHold: function() {
+ clearInterval(this.holdJob);
+ this.holdJob = null;
+ if (this.sentHold) {
+ this.sentHold = false;
+ this.sendRelease(this.holdEvent);
+ }
+ },
+ sendHoldPulse: function(inEvent) {
+ if (!this.sentHold) {
+ this.sentHold = true;
+ this.sendHold(inEvent);
+ }
+ var e = enyo.gesture.makeEvent("holdpulse", inEvent);
+ e.holdTime = enyo.now() - this.holdStart;
+ enyo.dispatch(e);
+ },
+ sendHold: function(inEvent) {
+ this.holdEvent = inEvent;
+ var e = enyo.gesture.makeEvent("hold", inEvent);
+ enyo.dispatch(e);
+ },
+ sendRelease: function(inEvent) {
+ var e = enyo.gesture.makeEvent("release", inEvent);
+ enyo.dispatch(e);
+ },
+ sendFlick: function(inEvent, inX, inY, inV) {
+ var e = enyo.gesture.makeEvent("flick", inEvent);
+ e.xVelocity = inX;
+ e.yVelocity = inY;
+ e.velocity = inV;
+ enyo.dispatch(e);
}
};
View
@@ -15,12 +15,6 @@
* "move" - generated when the pointer moves.
* "enter" - generated when the pointer enters a dom node.
* "leave" - generated when the pointer leaves a dom node.
- * "hold" - generated when the pointer is held down without moving for a short period (about 200ms).
- * "release" - generated when the pointer is released after being held down, or the pointer is moved off of the node while still held down. The target is the same as the hold event.
- * "holdpulse" - generated when the pointer is held down without moving for a short period and periodically thereafter about every 200ms.
- Use this event to trigger an action after an arbitrary period of time. The holdTime property provides the elapsed time.
- * "flick" - generated when the user flicks the pointer quickly. This event provides flick velocity data: xVelocity is the velocity in the horizontal and
- yVelocity is the vertical velocity.
These events are synthesized from the available dom events and contain these common properties, when available: "target",
relatedTarget", "clientX", "clientY", "pageX", "pageY", "screenX", "screenY", "altKey", "ctrlKey", "metaKey", "shiftKey",
@@ -31,11 +25,6 @@
*/
enyo.gesture = {
//* @protected
- // FIXME: we browser sniff to normalize event mouse button information;
- // need a module for browser info.
- holdPulseDelay: 200,
- minFlick: 0.1,
- minTrack: 8,
eventProps: ["target", "relatedTarget", "clientX", "clientY", "pageX", "pageY", "screenX", "screenY", "altKey", "ctrlKey", "metaKey", "shiftKey",
"detail", "identifier", "dispatchTarget", "which", "srcEvent"],
makeEvent: function(inType, inEvent) {
@@ -58,103 +47,35 @@ enyo.gesture = {
return e;
},
down: function(inEvent) {
+ // cancel any hold since it's possible in corner cases to get a down without an up
var e = this.makeEvent("down", inEvent);
enyo.dispatch(e);
- this.startTracking(e);
this.target = e.target;
- this.dispatchTarget = e.dispatchTarget;
- this.beginHold(e);
+
},
move: function(inEvent) {
- this.cancelHold();
var e = this.makeEvent("move", inEvent);
enyo.dispatch(e);
// ad hoc: propagate setting to source event.
inEvent.requireTouchmove = e.requireTouchmove;
- if (this.trackInfo) {
- this.track(e);
- }
},
up: function(inEvent) {
- this.cancelHold();
var e = this.makeEvent("up", inEvent);
var tapPrevented = false;
e.preventTap = function() {
tapPrevented = true;
};
- this.endTracking(e);
enyo.dispatch(e);
if (!tapPrevented) {
this.sendTap(e);
}
},
- startTracking: function(e) {
- this.trackInfo = {};
- this.track(e);
- },
- track: function(inEvent) {
- var ti = this.trackInfo;
- if (ti.d1) {
- ti.d0 = ti.d1;
- }
- ti.d1 = {
- x: inEvent.pageX,
- y: inEvent.pageY,
- t: enyo.now()
- };
- },
- endTracking: function(e) {
- var ti = this.trackInfo;
- if (ti && ti.d1 && ti.d0) {
- var d1 = ti.d1, d0 = ti.d0;
- // note: important to use up time to reduce flick
- // velocity based on time between move and up.
- var dt = enyo.now() - d0.t;
- var x = (d1.x - d0.x) / dt;
- var y = (d1.y - d0.y) / dt;
- var v = Math.sqrt(x*x + y*y);
- if (v > this.minFlick) {
- this.sendFlick(e, x, y, v);
- }
- }
- this.trackInfo = null;
- },
over: function(inEvent) {
enyo.dispatch(this.makeEvent("enter", inEvent));
},
out: function(inEvent) {
enyo.dispatch(this.makeEvent("leave", inEvent));
},
- beginHold: function(inEvent) {
- this.holdStart = enyo.now();
- this.holdJob = setInterval(enyo.bind(this, "sendHoldPulse", inEvent), this.holdPulseDelay);
- },
- cancelHold: function() {
- clearInterval(this.holdJob);
- this.holdJob = null;
- if (this.sentHold) {
- this.sentHold = false;
- this.sendRelease(this.holdEvent);
- }
- },
- sendHoldPulse: function(inEvent) {
- if (!this.sentHold) {
- this.sentHold = true;
- this.sendHold(inEvent);
- }
- var e = this.makeEvent("holdpulse", inEvent);
- e.holdTime = enyo.now() - this.holdStart;
- enyo.dispatch(e);
- },
- sendHold: function(inEvent) {
- this.holdEvent = inEvent;
- var e = this.makeEvent("hold", inEvent);
- enyo.dispatch(e);
- },
- sendRelease: function(inEvent) {
- var e = this.makeEvent("release", inEvent);
- enyo.dispatch(e);
- },
sendTap: function(inEvent) {
// The common ancestor for the down/up pair is the origin for the tap event
var t = this.findCommonAncestor(this.target, inEvent.target);
@@ -181,14 +102,6 @@ enyo.gesture = {
}
c = c.parentNode;
}
- },
- sendFlick: function(inEvent, inX, inY, inV) {
- var e = this.makeEvent("flick", inEvent);
- e.xVelocity = inX;
- e.yVelocity = inY;
- e.velocity = inV;
- e.target = this.target;
- enyo.dispatch(e);
}
};

0 comments on commit c078fdd

Please sign in to comment.