-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Events in grouped object #2729
Events in grouped object #2729
Changes from all commits
7b1e7ba
6fd4082
2a6b2c3
4a4f42b
b38c385
07a2df8
84a5376
b3fb4c2
e374828
51482e3
42beee7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -261,10 +261,15 @@ | |
* @param {fabric.Object} target Object to test against | ||
* @return {Boolean} true if point is contained within an area of given object | ||
*/ | ||
containsPoint: function (e, target) { | ||
var pointer = this.getPointer(e, true), | ||
xy = this._normalizePointer(target, pointer); | ||
containsPoint: function (pointer, target) { | ||
|
||
var xy; | ||
if (target.group && target.group === this.getActiveGroup()) { | ||
xy = this._normalizePointer(target.group, pointer); | ||
} | ||
else { | ||
xy = { x: pointer.x, y: pointer.y }; | ||
} | ||
// http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html | ||
// http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html | ||
return (target.containsPoint(xy) || target._findTargetCorner(pointer)); | ||
|
@@ -274,24 +279,17 @@ | |
* @private | ||
*/ | ||
_normalizePointer: function (object, pointer) { | ||
var activeGroup = this.getActiveGroup(), | ||
isObjectInGroup = ( | ||
activeGroup && | ||
object.type !== 'group' && | ||
activeGroup.contains(object)), | ||
lt, m; | ||
|
||
if (isObjectInGroup) { | ||
m = fabric.util.multiplyTransformMatrices( | ||
this.viewportTransform, | ||
activeGroup.calcTransformMatrix()); | ||
|
||
m = fabric.util.invertTransform(m); | ||
pointer = fabric.util.transformPoint(pointer, m , false); | ||
lt = fabric.util.transformPoint(activeGroup.getCenterPoint(), m , false); | ||
pointer.x -= lt.x; | ||
pointer.y -= lt.y; | ||
} | ||
var lt, m; | ||
|
||
m = fabric.util.multiplyTransformMatrices( | ||
this.viewportTransform, | ||
object.calcTransformMatrix()); | ||
|
||
m = fabric.util.invertTransform(m); | ||
pointer = fabric.util.transformPoint(pointer, m , false); | ||
lt = fabric.util.transformPoint(object.getCenterPoint(), m , false); | ||
pointer.x -= lt.x; | ||
pointer.y -= lt.y; | ||
return { x: pointer.x, y: pointer.y }; | ||
}, | ||
|
||
|
@@ -860,38 +858,37 @@ | |
/** | ||
* @private | ||
*/ | ||
_isLastRenderedObject: function(e) { | ||
_isLastRenderedObject: function(pointer) { | ||
var lastRendered = this.lastRenderedObjectWithControlsAboveOverlay; | ||
return ( | ||
this.controlsAboveOverlay && | ||
this.lastRenderedObjectWithControlsAboveOverlay && | ||
this.lastRenderedObjectWithControlsAboveOverlay.visible && | ||
this.containsPoint(e, this.lastRenderedObjectWithControlsAboveOverlay) && | ||
this.lastRenderedObjectWithControlsAboveOverlay._findTargetCorner(this.getPointer(e, true))); | ||
lastRendered && | ||
lastRendered.visible && | ||
(this.containsPoint(pointer, lastRendered) || | ||
lastRendered._findTargetCorner(pointer))); | ||
}, | ||
|
||
/** | ||
* Method that determines what object we are clicking on | ||
* @param {Event} e mouse event | ||
* @param {Boolean} skipGroup when true, group is skipped and only objects are traversed through | ||
* @param {Boolean} skipGroup when true, ActiveGroup is skipped and only objects are traversed through | ||
*/ | ||
findTarget: function (e, skipGroup) { | ||
if (this.skipTargetFind) { | ||
return; | ||
} | ||
|
||
if (this._isLastRenderedObject(e)) { | ||
this.targets = [ ]; | ||
var pointer = this.getPointer(e, true); | ||
if (this._isLastRenderedObject(pointer)) { | ||
return this.lastRenderedObjectWithControlsAboveOverlay; | ||
} | ||
|
||
// first check current group (if one exists) | ||
var activeGroup = this.getActiveGroup(); | ||
if (activeGroup && !skipGroup && this.containsPoint(e, activeGroup)) { | ||
if (activeGroup && !skipGroup && this.containsPoint(pointer, activeGroup)) { | ||
return activeGroup; | ||
} | ||
|
||
var target = this._searchPossibleTargets(e, skipGroup); | ||
this._fireOverOutEvents(target, e); | ||
|
||
var target = this._searchPossibleTargets(e, pointer, this._objects); | ||
return target; | ||
}, | ||
|
||
|
@@ -920,11 +917,11 @@ | |
/** | ||
* @private | ||
*/ | ||
_checkTarget: function(e, obj, pointer) { | ||
_checkTarget: function(pointer, obj) { | ||
if (obj && | ||
obj.visible && | ||
obj.evented && | ||
this.containsPoint(e, obj)){ | ||
this.containsPoint(pointer, obj)){ | ||
if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) { | ||
var isTransparent = this.isTargetTransparent(obj, pointer.x, pointer.y); | ||
if (!isTransparent) { | ||
|
@@ -940,22 +937,24 @@ | |
/** | ||
* @private | ||
*/ | ||
_searchPossibleTargets: function(e, skipGroup) { | ||
_searchPossibleTargets: function(e, pointer, objects) { | ||
|
||
// Cache all targets where their bounding box contains point. | ||
var target, | ||
pointer = this.getPointer(e, true), | ||
i = this._objects.length; | ||
var target, i = objects.length, normalizedPointer; | ||
// Do not check for currently grouped objects, since we check the parent group itself. | ||
// untill we call this function specifically to search inside the activeGroup | ||
while (i--) { | ||
if ((!this._objects[i].group || skipGroup) && this._checkTarget(e, this._objects[i], pointer)){ | ||
this.relatedTarget = this._objects[i]; | ||
target = this._objects[i]; | ||
if (this._checkTarget(pointer, objects[i])) { | ||
target = objects[i]; | ||
this.targets.push(target); | ||
if (target.type === 'group') { | ||
normalizedPointer = this._normalizePointer(target, pointer); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i made normalizePointer callable explicity, outside the scope of an activeGroup |
||
this._searchPossibleTargets(e, normalizedPointer, target._objects); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this.relatedTarget was here, but undocumented as i can see. It gets override by canvas.targets that now will keep the list last found targets |
||
break; | ||
} | ||
} | ||
|
||
this._fireOverOutEvents(target, e); | ||
return target; | ||
}, | ||
|
||
|
@@ -1293,3 +1292,4 @@ | |
*/ | ||
fabric.Element = fabric.Canvas; | ||
})(); | ||
s | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should probably not be here :) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -271,10 +271,8 @@ | |
if (target) { | ||
target.isMoving = false; | ||
} | ||
|
||
shouldRender && this.renderAll(); | ||
|
||
this._handleCursorAndEvent(e, target); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why mouseup is managed different from other events? it gets its own function to fire the events. |
||
shouldRender && this.renderAll(); | ||
}, | ||
|
||
_handleCursorAndEvent: function(e, target) { | ||
|
@@ -287,7 +285,9 @@ | |
}, 50); | ||
|
||
this.fire('mouse:up', { target: target, e: e }); | ||
target && target.fire('mouseup', { e: e }); | ||
for (var i = 0; i < this.targets.length; i++) { | ||
this.targets[i].fire('mouseup', { e: e }) | ||
} | ||
}, | ||
|
||
/** | ||
|
@@ -352,8 +352,8 @@ | |
this.fire('mouse:down', { e: e }); | ||
|
||
var target = this.findTarget(e); | ||
if (typeof target !== 'undefined') { | ||
target.fire('mousedown', { e: e, target: target }); | ||
for (var i = 0; i < this.targets.length; i++) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is the only way i could come out to manage one-click-many-targets events firing. Does it looks ok for you? |
||
this.targets[i].fire('mousedown', { e: e }) | ||
} | ||
}, | ||
|
||
|
@@ -371,8 +371,8 @@ | |
this.fire('mouse:move', { e: e }); | ||
|
||
var target = this.findTarget(e); | ||
if (typeof target !== 'undefined') { | ||
target.fire('mousemove', { e: e, target: target }); | ||
for (var i = 0; i < this.targets.length; i++) { | ||
this.targets[i].fire('mousemove', { e: e }) | ||
} | ||
}, | ||
|
||
|
@@ -389,8 +389,8 @@ | |
this.fire('mouse:up', { e: e }); | ||
|
||
var target = this.findTarget(e); | ||
if (typeof target !== 'undefined') { | ||
target.fire('mouseup', { e: e, target: target }); | ||
for (var i = 0; i < this.targets.length; i++) { | ||
this.targets[i].fire('mouseup', { e: e }) | ||
} | ||
}, | ||
|
||
|
@@ -422,7 +422,6 @@ | |
|
||
var target = this.findTarget(e), | ||
pointer = this.getPointer(e, true); | ||
|
||
// save pointer for check in __onMouseUp event | ||
this._previousPointer = pointer; | ||
|
||
|
@@ -441,11 +440,12 @@ | |
this._beforeTransform(e, target); | ||
this._setupCurrentTransform(e, target); | ||
} | ||
// we must renderAll so that active image is placed on the top canvas | ||
shouldRender && this.renderAll(); | ||
|
||
this.fire('mouse:down', { target: target, e: e }); | ||
target && target.fire('mousedown', { e: e }); | ||
for (var i = 0; i < this.targets.length; i++) { | ||
this.targets[i].fire('mousedown', { e: e }) | ||
} | ||
shouldRender && this.renderAll(); | ||
}, | ||
|
||
/** | ||
|
@@ -572,7 +572,9 @@ | |
} | ||
|
||
this.fire('mouse:move', { target: target, e: e }); | ||
target && target.fire('mousemove', { e: e }); | ||
for (var i = 0; i < this.targets.length; i++) { | ||
this.targets[i].fire('mousemove', { e: e }) | ||
} | ||
}, | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function is a shortcut to check last selected target before all. But why just with controls above overaly? i think it should be checked always.