Skip to content

Commit

Permalink
feat(fabric.controlsUtils) Move drag to actions to control handlers (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
asturur authored Sep 26, 2020
1 parent dd08a36 commit f80dffc
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 44 deletions.
32 changes: 7 additions & 25 deletions src/canvas.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
* @see {@link fabric.Canvas#initialize} for constructor definition
*
* @fires object:modified at the end of a transform or any change when statefull is true
* @fires object:rotated at the end of a rotation transform
* @fires object:scaled at the end of a scale transform
* @fires object:moved at the end of translation transform
* @fires object:skewed at the end of a skew transform
* @fires object:rotating while an object is being rotated from the control
* @fires object:scaling while an object is being scaled by controls
* @fires object:moving while an object is being dragged
Expand Down Expand Up @@ -48,6 +44,11 @@
* @fires after:render at the end of the render process, receives the context in the callback
* @fires before:render at start the render process, receives the context in the callback
*
* the following events are deprecated:
* @fires object:rotated at the end of a rotation transform
* @fires object:scaled at the end of a scale transform
* @fires object:moved at the end of translation transform
* @fires object:skewed at the end of a skew transform
*/
fabric.Canvas = fabric.util.createClass(fabric.StaticCanvas, /** @lends fabric.Canvas.prototype */ {

Expand Down Expand Up @@ -640,7 +641,8 @@
}

var pointer = this.getPointer(e), corner = target.__corner,
actionHandler = !!corner && target.controls[corner].getActionHandler(),
actionHandler = (alreadySelected && corner) ?
target.controls[corner].getActionHandler() : fabric.controlsUtils.dragHandler,
action = this._getActionFromCorner(alreadySelected, corner, e, target),
origin = this._getOriginFromCorner(target, corner),
altKey = e[this.centeredKey],
Expand Down Expand Up @@ -683,26 +685,6 @@
this._beforeTransform(e);
},

/**
* Translates object by "setting" its left/top
* @private
* @param {Number} x pointer's x coordinate
* @param {Number} y pointer's y coordinate
* @return {Boolean} true if the translation occurred
*/
_translateObject: function (x, y) {
var transform = this._currentTransform,
target = transform.target,
newLeft = x - transform.offsetX,
newTop = y - transform.offsetY,
moveX = !target.get('lockMovementX') && target.left !== newLeft,
moveY = !target.get('lockMovementY') && target.top !== newTop;

moveX && target.set('left', newLeft);
moveY && target.set('top', newTop);
return moveX || moveY;
},

/**
* Set the cursor type of the canvas element
* @param {String} value Cursor type of the canvas element.
Expand Down
27 changes: 26 additions & 1 deletion src/controls.actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
function fireEvent(eventName, options) {
var target = options.transform.target,
canvas = target.canvas,
canvasOptions = Object.assign({}, options, { target: target });
canvasOptions = fabric.util.object.clone(options);
canvasOptions.target = target;
canvas && canvas.fire('object:' + eventName, canvasOptions);
target.fire(eventName, options);
}
Expand Down Expand Up @@ -690,6 +691,29 @@
return hasResized;
}

/**
* Action handler
* @private
* @param {Event} eventData javascript event that is doing the transform
* @param {Object} transform javascript object containing a series of information around the current transform
* @param {number} x current mouse x position, canvas normalized
* @param {number} y current mouse y position, canvas normalized
* @return {Boolean} true if the translation occurred
*/
function dragHandler(eventData, transform, x, y) {
var target = transform.target,
newLeft = x - transform.offsetX,
newTop = y - transform.offsetY,
moveX = !target.get('lockMovementX') && target.left !== newLeft,
moveY = !target.get('lockMovementY') && target.top !== newTop;
moveX && target.set('left', newLeft);
moveY && target.set('top', newTop);
if (moveX || moveY) {
fireEvent('moving', commonEventInfo(eventData, transform, x, y));
}
return moveX || moveY;
}

controls.scaleCursorStyleHandler = scaleCursorStyleHandler;
controls.skewCursorStyleHandler = skewCursorStyleHandler;
controls.scaleSkewCursorStyleHandler = scaleSkewCursorStyleHandler;
Expand All @@ -702,6 +726,7 @@
controls.changeWidth = wrapWithFixedAnchor(changeWidth);
controls.skewHandlerX = skewHandlerX;
controls.skewHandlerY = skewHandlerY;
controls.dragHandler = dragHandler;
controls.scaleOrSkewActionName = scaleOrSkewActionName;
controls.rotationStyleHandler = rotationStyleHandler;
controls.fireEvent = fireEvent;
Expand Down
27 changes: 11 additions & 16 deletions src/mixins/canvas_events.mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@
// as a short term fix we are not firing this if we are currently transforming.
// as a long term fix we need to separate the action of finding a target with the
// side effects we added to it.
if (!this.currentTransform && !this.findTarget(e)) {
if (!this._currentTransform && !this.findTarget(e)) {
this.fire('mouse:over', { target: null, e: e });
this._hoveredTarget = null;
this._hoveredTargets = [];
Expand Down Expand Up @@ -548,6 +548,7 @@
e: e,
target: target,
transform: transform,
action: transform.action,
};

if (target._scaling) {
Expand All @@ -558,6 +559,8 @@

if (transform.actionPerformed || (this.stateful && target.hasStateChanged())) {
if (transform.actionPerformed) {
// this is not friendly to the new control api.
// is deprecated.
eventName = this._addEventOptions(options, transform);
this._fire(eventName, options);
}
Expand All @@ -568,6 +571,7 @@
/**
* Mutate option object in order to add by property and give back the event name.
* @private
* @deprecated since 4.2.0
* @param {Object} options to mutate
* @param {Object} transform to inspect action from
*/
Expand Down Expand Up @@ -934,24 +938,15 @@
y = pointer.y,
action = transform.action,
actionPerformed = false,
actionHandler = transform.actionHandler,
actionHandler = transform.actionHandler;
// this object could be created from the function in the control handlers
options = {
target: transform.target,
e: e,
transform: transform,
pointer: pointer
};

if (action === 'drag') {
actionPerformed = this._translateObject(x, y);
if (actionPerformed) {
this._fire('moving', options);
this.setCursor(options.target.moveCursor || this.moveCursor);
}

if (actionHandler) {
actionPerformed = actionHandler(e, transform, x, y);
}
else if (actionHandler) {
(actionPerformed = actionHandler(e, transform, x, y)) && this._fire(action, options);
if (action === 'drag' && actionPerformed) {
this.setCursor(transform.target.moveCursor || this.moveCursor);
}
transform.actionPerformed = transform.actionPerformed || actionPerformed;
},
Expand Down
4 changes: 2 additions & 2 deletions test/unit/canvas_events.js
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@
var c = new fabric.Canvas();
var obj = new fabric.Object();
c._hoveredTarget = obj;
c.currentTransform = {};
c._currentTransform = {};
c.upperCanvasEl.dispatchEvent(event);
assert.equal(c._hoveredTarget, obj, '_hoveredTarget has been not removed');
});
Expand All @@ -728,7 +728,7 @@
event.initEvent('mouseenter', true, true);
var c = new fabric.Canvas();
var obj = new fabric.Object();
c.currentTransform = {};
c._currentTransform = {};
c.setActiveObject(obj);
obj.__corner = 'test';
c.upperCanvasEl.dispatchEvent(event);
Expand Down
18 changes: 18 additions & 0 deletions test/unit/controls_handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@
fabric.controlsUtils.changeWidth(eventData, transform, 200, 300);
assert.equal(Math.floor(transform.target.width), 51);
});
QUnit.test('changeWidth will fire events on canvas and target resizing', function(assert) {
var done = assert.async();
transform.target.canvas.on('object:resizing', function(options) {
assert.equal(options.target, transform.target);
});
transform.target.on('resizing', function(options) {
assert.deepEqual(options, {
e: eventData,
transform: transform,
pointer: {
x: 200,
y: 300,
},
});
done();
});
fabric.controlsUtils.changeWidth(eventData, transform, 200, 300);
});
QUnit.test('scalingXOrSkewingY changes scaleX', function(assert) {
transform.target.scaleX = 1;
transform.target.strokeWidth = 0;
Expand Down

0 comments on commit f80dffc

Please sign in to comment.