mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-20 22:39:50 -05:00
A lot of fine-tuning and fixing to better handle touch scrolling.
Relates to #686
This commit is contained in:
parent
d5f2ff479d
commit
1a6bf972d5
2 changed files with 42 additions and 27 deletions
|
@ -286,7 +286,7 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{
|
||||||
* least one event handler was called and none of the called handlers
|
* least one event handler was called and none of the called handlers
|
||||||
* wants to enforce the default.
|
* wants to enforce the default.
|
||||||
*/
|
*/
|
||||||
_handleEvent: function(type, event, point) {
|
_handleEvent: function(type, event, point, mouse) {
|
||||||
// Update global reference to this scope.
|
// Update global reference to this scope.
|
||||||
paper = this._scope;
|
paper = this._scope;
|
||||||
var minDistance = this.minDistance,
|
var minDistance = this.minDistance,
|
||||||
|
@ -303,11 +303,7 @@ var Tool = PaperScopeItem.extend(/** @lends Tool# */{
|
||||||
matchMaxDistance = false,
|
matchMaxDistance = false,
|
||||||
called = false, // Has at least one handler been called?
|
called = false, // Has at least one handler been called?
|
||||||
enforced = false, // Does a handler want to enforce the default?
|
enforced = false, // Does a handler want to enforce the default?
|
||||||
tool = this,
|
tool = this;
|
||||||
mouse = {};
|
|
||||||
// Create a simple lookup object to quickly check for different
|
|
||||||
// mouse event types.
|
|
||||||
mouse[type.substr(5)] = true;
|
|
||||||
|
|
||||||
function update(start, minDistance, maxDistance) {
|
function update(start, minDistance, maxDistance) {
|
||||||
var toolPoint = tool._point,
|
var toolPoint = tool._point,
|
||||||
|
|
|
@ -698,7 +698,8 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
|
|
||||||
var prevFocus,
|
var prevFocus,
|
||||||
tempFocus,
|
tempFocus,
|
||||||
mouseDown = false;
|
dragging = false, // mousedown that started on a view.
|
||||||
|
mouseDown = false; // mouesdown anywhere.
|
||||||
|
|
||||||
function getView(event) {
|
function getView(event) {
|
||||||
// Get the view from the current event target.
|
// Get the view from the current event target.
|
||||||
|
@ -782,7 +783,7 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
// Get the view from the event, and store a reference to the view that
|
// Get the view from the event, and store a reference to the view that
|
||||||
// should receive keyboard input.
|
// should receive keyboard input.
|
||||||
var view = View._focused = getView(event);
|
var view = View._focused = getView(event);
|
||||||
mouseDown = true;
|
dragging = true;
|
||||||
view._handleEvent('mousedown', event);
|
view._handleEvent('mousedown', event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -792,13 +793,12 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
// See if we can get the view from the current event target, and
|
// See if we can get the view from the current event target, and
|
||||||
// handle the mouse move over it.
|
// handle the mouse move over it.
|
||||||
var target = getView(event);
|
var target = getView(event);
|
||||||
if (target) {
|
if (target && view !== target) {
|
||||||
// Temporarily focus this view without making it sticky, so Key
|
// Temporarily focus this view without making it sticky, so Key
|
||||||
// events are handled too during the mouse over.
|
// events are handled too during the mouse over.
|
||||||
// If we switch view, fire one last mousemove in the old view,
|
// As we switch view, fire one last mousemove in the old view,
|
||||||
// to give items the change to receive a mouseleave, etc.
|
// to give items the change to receive a mouseleave, etc.
|
||||||
if (view !== target)
|
handleMouseMove(view, event);
|
||||||
handleMouseMove(view, event);
|
|
||||||
prevFocus = view;
|
prevFocus = view;
|
||||||
view = View._focused = tempFocus = target;
|
view = View._focused = tempFocus = target;
|
||||||
} else if (tempFocus && tempFocus === view) {
|
} else if (tempFocus && tempFocus === view) {
|
||||||
|
@ -811,11 +811,18 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
handleMouseMove(view, event);
|
handleMouseMove(view, event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
docEvents[mousedown] = function(event) {
|
||||||
|
// In order to not switch views during scroll dragging on touch devices,
|
||||||
|
// we need to know if the mouse was clicked anywhere on the document
|
||||||
|
// (see docEvents[mousemove]) The rest happens in viewEvents[mousedown].
|
||||||
|
mouseDown = true;
|
||||||
|
};
|
||||||
|
|
||||||
docEvents[mouseup] = function(event) {
|
docEvents[mouseup] = function(event) {
|
||||||
var view = View._focused;
|
var view = View._focused;
|
||||||
if (view && mouseDown)
|
if (view && dragging)
|
||||||
view._handleEvent('mouseup', event);
|
view._handleEvent('mouseup', event);
|
||||||
mouseDown = false;
|
mouseDown = dragging = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
DomEvent.add(document, docEvents);
|
DomEvent.add(document, docEvents);
|
||||||
|
@ -938,7 +945,8 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
clickItem,
|
clickItem,
|
||||||
clickTime,
|
clickTime,
|
||||||
dblClick,
|
dblClick,
|
||||||
overView;
|
overView,
|
||||||
|
wasInView = false;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_viewEvents: viewEvents,
|
_viewEvents: viewEvents,
|
||||||
|
@ -954,7 +962,7 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
// it to a mousedrag.
|
// it to a mousedrag.
|
||||||
// NOTE: emitEvent(), as well as Tool#_handleEvent() fall back to
|
// NOTE: emitEvent(), as well as Tool#_handleEvent() fall back to
|
||||||
// mousemove if the objects don't respond to mousedrag.
|
// mousemove if the objects don't respond to mousedrag.
|
||||||
if (type === 'mousemove' && mouseDown)
|
if (type === 'mousemove' && dragging)
|
||||||
type = 'mousedrag';
|
type = 'mousedrag';
|
||||||
// Before handling events, process removeOn() calls for cleanup.
|
// Before handling events, process removeOn() calls for cleanup.
|
||||||
if (project)
|
if (project)
|
||||||
|
@ -963,14 +971,16 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
point = this.getEventPoint(event);
|
point = this.getEventPoint(event);
|
||||||
// Run the hit-test on items first, but only if we're required to do
|
// Run the hit-test on items first, but only if we're required to do
|
||||||
// so for this given mouse event, see #_countItemEvent().
|
// so for this given mouse event, see #_countItemEvent().
|
||||||
var hit = handleItems && this._project.hitTest(point, {
|
var inView = this.getBounds().contains(point),
|
||||||
|
hit = inView && handleItems && this._project.hitTest(point, {
|
||||||
tolerance: 0,
|
tolerance: 0,
|
||||||
fill: true,
|
fill: true,
|
||||||
stroke: true
|
stroke: true
|
||||||
}),
|
}),
|
||||||
item = hit && hit.item || undefined,
|
item = hit && hit.item || undefined,
|
||||||
inView = this.getBounds().contains(point),
|
// Keep track if view event should be handled, so we can use it
|
||||||
wasInView = this === overView,
|
// to decide if tool._handleEvent() shall be called after.
|
||||||
|
handle = false,
|
||||||
stopped = false,
|
stopped = false,
|
||||||
mouse = {};
|
mouse = {};
|
||||||
// Create a simple lookup object to quickly check for different
|
// Create a simple lookup object to quickly check for different
|
||||||
|
@ -981,9 +991,8 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
// Handle mousemove first, even if this is not actually a mousemove
|
// Handle mousemove first, even if this is not actually a mousemove
|
||||||
// event but the mouse has moved since the last event, but do not
|
// event but the mouse has moved since the last event, but do not
|
||||||
// allow it to stop the other events in that case.
|
// allow it to stop the other events in that case.
|
||||||
var nativeMove = mouse.move || mouse.drag;
|
var nativeMove = mouse.move || mouse.drag,
|
||||||
moveType = nativeMove && type
|
moveType = nativeMove && type || 'mousemove';
|
||||||
|| lastPoint && !lastPoint.equals(point) && 'mousemove';
|
|
||||||
if (moveType) {
|
if (moveType) {
|
||||||
// Handle mouseenter / leave between items, as well as views.
|
// Handle mouseenter / leave between items, as well as views.
|
||||||
if (item !== overItem) {
|
if (item !== overItem) {
|
||||||
|
@ -997,14 +1006,25 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
emitEvent(this, inView ? 'mouseenter' : 'mouseleave', event,
|
emitEvent(this, inView ? 'mouseenter' : 'mouseleave', event,
|
||||||
point);
|
point);
|
||||||
overView = inView ? this : null;
|
overView = inView ? this : null;
|
||||||
|
handle = nativeMove; // To include the leaving move.
|
||||||
}
|
}
|
||||||
if (inView || mouse.drag && !lastPoint.equals(point))
|
if (inView || mouse.drag && !lastPoint.equals(point)) {
|
||||||
stopped = emitEvents(this, item, moveType, event, point,
|
stopped = emitEvents(this, item, moveType, event, point,
|
||||||
lastPoint);
|
lastPoint);
|
||||||
|
handle = nativeMove;
|
||||||
|
}
|
||||||
|
wasInView = inView;
|
||||||
}
|
}
|
||||||
if (!nativeMove) {
|
// Now handle mousedown / mouseup
|
||||||
// Now handle mousedown / mouseup
|
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)) {
|
||||||
stopped = emitEvents(this, item, type, event, point, 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) {
|
if (mouse.down) {
|
||||||
// See if we're clicking again on the same item, within the
|
// See if we're clicking again on the same item, within the
|
||||||
// double-click time. Firefox uses 300ms as the max time
|
// double-click time. Firefox uses 300ms as the max time
|
||||||
|
@ -1034,8 +1054,7 @@ new function() { // Injection scope for mouse events on the browser
|
||||||
// to only be fired if we're inside the view or if we just left it.
|
// to only be fired if we're inside the view or if we just left it.
|
||||||
// Prevent default if at least one handler was called, and none of
|
// Prevent default if at least one handler was called, and none of
|
||||||
// them enforces default, to prevent scrolling on touch devices.
|
// them enforces default, to prevent scrolling on touch devices.
|
||||||
if (tool && (mouse.move || inView || wasInView)
|
if (handle && tool && tool._handleEvent(type, event, point, mouse)
|
||||||
&& tool._handleEvent(type, event, point)
|
|
||||||
|| called && !enforced)
|
|| called && !enforced)
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
// In the end we always call update(), which only updates the view
|
// In the end we always call update(), which only updates the view
|
||||||
|
|
Loading…
Reference in a new issue