mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-19 06:00:56 -05:00
Further streamline and improve tool mouse-event handling.
This commit is contained in:
parent
e2723f0312
commit
cf924512c0
3 changed files with 51 additions and 65 deletions
|
@ -119,7 +119,7 @@ var Segment = Base.extend(/** @lends Segment# */{
|
|||
// Nothing
|
||||
} else if (count === 1) {
|
||||
// NOTE: This copies from existing segments through accessors.
|
||||
if ('point' in arg0) {
|
||||
if (arg0 && 'point' in arg0) {
|
||||
point = arg0.point;
|
||||
handleIn = arg0.handleIn;
|
||||
handleOut = arg0.handleOut;
|
||||
|
|
100
src/tool/Tool.js
100
src/tool/Tool.js
|
@ -55,7 +55,7 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{
|
|||
PaperScopeItem.call(this);
|
||||
this._firstMove = true;
|
||||
this._count = 0;
|
||||
this._downCount = 0;
|
||||
this._downCount = -1; // So first is 0
|
||||
this._set(props);
|
||||
},
|
||||
|
||||
|
@ -278,7 +278,6 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{
|
|||
* }
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Private method to handle tool-events.
|
||||
*
|
||||
|
@ -287,28 +286,30 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{
|
|||
_handleEvent: function(type, event, point, mouse) {
|
||||
// Update global reference to this scope.
|
||||
paper = this._scope;
|
||||
var minDistance = this.minDistance,
|
||||
// If there is no mousedrag event installed, fall back to mousemove,
|
||||
// with which we share the actual event handling code anyhow.
|
||||
var move = mouse.move || mouse.drag && !this.responds(type);
|
||||
// Make sure type is not 'mousedrag' if we fell back.
|
||||
if (move)
|
||||
type = 'mousemove';
|
||||
var responds = this.responds(type),
|
||||
minDistance = this.minDistance,
|
||||
maxDistance = this.maxDistance,
|
||||
// In order for idleInterval drag events to work, we need to not
|
||||
// check the first call for a change of position. Subsequent calls
|
||||
// required by min/maxDistance functionality will require it,
|
||||
// otherwise this might loop endlessly.
|
||||
needsChange = false,
|
||||
// If the mouse is moving faster than maxDistance, do not produce
|
||||
// events for what is left after the first event is generated in
|
||||
// case it is shorter than maxDistance, as this would produce weird
|
||||
// results. matchMaxDistance controls this.
|
||||
matchMaxDistance = false,
|
||||
called = false,
|
||||
tool = this;
|
||||
|
||||
// Updates the internal tool state, taking into account minDistance and
|
||||
// maxDistance and interpolating "fake" events along the moved distance
|
||||
// to respect their settings, if necessary.
|
||||
// Returns true as long as events should be fired, false when the target
|
||||
// is reached.
|
||||
function update(start, minDistance, maxDistance) {
|
||||
var toolPoint = tool._point,
|
||||
pt = point;
|
||||
if (start) {
|
||||
tool._count = 0;
|
||||
} else {
|
||||
tool._count++;
|
||||
if (pt.equals(toolPoint))
|
||||
return false;
|
||||
if (minDistance != null || maxDistance != null) {
|
||||
var vector = pt.subtract(toolPoint),
|
||||
distance = vector.getLength();
|
||||
|
@ -317,63 +318,48 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{
|
|||
// Produce a new point on the way to point if point is
|
||||
// further away than maxDistance
|
||||
if (maxDistance) {
|
||||
if (distance > maxDistance) {
|
||||
pt = toolPoint.add(vector.normalize(maxDistance));
|
||||
} else if (matchMaxDistance) {
|
||||
return false;
|
||||
}
|
||||
pt = toolPoint.add(vector.normalize(
|
||||
Math.min(distance, maxDistance)));
|
||||
}
|
||||
}
|
||||
if (needsChange && pt.equals(toolPoint))
|
||||
return false;
|
||||
tool._count++;
|
||||
}
|
||||
// Make sure mousemove events have lastPoint set even for the first
|
||||
// move so event.delta is always defined for them.
|
||||
// TODO: Decide whether mousedown also should always have delta set.
|
||||
tool._lastPoint = start && mouse.move ? pt : toolPoint;
|
||||
tool._point = pt;
|
||||
if (responds) {
|
||||
tool._point = pt;
|
||||
tool._lastPoint = move || mouse.drag
|
||||
// Make sure mousemove events have lastPoint set even for
|
||||
// the first move so event.delta is always defined for them.
|
||||
? start && move ? pt : toolPoint
|
||||
// Set lastPoint to previous downPoint, or current point if
|
||||
// this is the first mousedown, so there's always a delta.
|
||||
// This way mouseup has a delta spanning over the full drag.
|
||||
: tool._downPoint || pt;
|
||||
}
|
||||
// Keep track of downPoint regardless of the value of response
|
||||
if (mouse.down) {
|
||||
tool._lastPoint = tool._downPoint;
|
||||
tool._downPoint = pt;
|
||||
tool._downCount++;
|
||||
} else if (mouse.up) {
|
||||
// Mouse up events return the down point for last point, so
|
||||
// delta is spanning over the whole drag.
|
||||
tool._lastPoint = tool._downPoint;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function emit() {
|
||||
called = tool.responds(type)
|
||||
&& tool.emit(type, new ToolEvent(tool, type, event))
|
||||
|| called;
|
||||
function emit(firstMove) {
|
||||
if (responds) {
|
||||
called = tool.emit(type, new ToolEvent(tool, type, event))
|
||||
|| called;
|
||||
tool._firstMove = firstMove;
|
||||
}
|
||||
}
|
||||
|
||||
if (mouse.down) {
|
||||
update(true);
|
||||
emit();
|
||||
update(responds);
|
||||
emit(false);
|
||||
} else if (mouse.up) {
|
||||
update(false, null, maxDistance);
|
||||
emit();
|
||||
// Start with new values for 'mousemove'
|
||||
update(true);
|
||||
this._firstMove = true;
|
||||
} else {
|
||||
// If there is no mousedrag event installed, fall back to mousemove,
|
||||
// with which we share the actual event handling code anyhow.
|
||||
var drag = mouse.drag && this.responds(type);
|
||||
if (!drag)
|
||||
type = 'mousemove';
|
||||
needsChange = !drag;
|
||||
while (update(!drag && this._firstMove, minDistance, maxDistance)) {
|
||||
emit();
|
||||
if (drag) {
|
||||
needsChange = matchMaxDistance = true;
|
||||
} else {
|
||||
this._firstMove = false;
|
||||
}
|
||||
}
|
||||
emit(true);
|
||||
} else if (responds) {
|
||||
while (update(this._firstMove, minDistance, maxDistance))
|
||||
emit(false);
|
||||
}
|
||||
return called;
|
||||
}
|
||||
|
|
|
@ -1018,12 +1018,12 @@ new function() { // Injection scope for mouse events on the browser
|
|||
emitEvent(this, inView ? 'mouseenter' : 'mouseleave', event,
|
||||
point);
|
||||
overView = inView ? this : null;
|
||||
handle = nativeMove; // To include the leaving move.
|
||||
handle = true; // To include the leaving move.
|
||||
}
|
||||
if (inView || mouse.drag && !lastPoint.equals(point)) {
|
||||
stopped = emitEvents(this, item, moveType, event, point,
|
||||
lastPoint);
|
||||
handle = nativeMove;
|
||||
handle = true;
|
||||
}
|
||||
wasInView = inView;
|
||||
}
|
||||
|
@ -1031,12 +1031,8 @@ new function() { // Injection scope for mouse events on the browser
|
|||
if (!nativeMove &&
|
||||
// We emit mousedown only when in the view, and mouseup
|
||||
// regardless, as long as the mousedown event was inside.
|
||||
(handle = mouse.down && inView || mouse.up && !!downPoint)) {
|
||||
(handle = mouse.down && inView || mouse.up && downPoint)) {
|
||||
stopped = emitEvents(this, item, type, event, point, downPoint);
|
||||
// Clear wasInView so we're not accidentally handling mousedrag
|
||||
// events that started outside the view as mousemove events on
|
||||
// the view (needed to handle touch scrolling correctly).
|
||||
wasInView = false;
|
||||
if (mouse.down) {
|
||||
// See if we're clicking again on the same item, within the
|
||||
// double-click time. Firefox uses 300ms as the max time
|
||||
|
@ -1060,6 +1056,10 @@ new function() { // Injection scope for mouse events on the browser
|
|||
}
|
||||
downItem = dragItem = null;
|
||||
}
|
||||
// Clear wasInView so we're not accidentally handling mousedrag
|
||||
// events that started outside the view as mousemove events on
|
||||
// the view (needed to handle touch scrolling correctly).
|
||||
wasInView = false;
|
||||
}
|
||||
lastPoint = point;
|
||||
// Now finally call the tool events, but filter mouse move events
|
||||
|
|
Loading…
Reference in a new issue