diff --git a/src/canvas.class.js b/src/canvas.class.js index 0a4f8a04..e6fef510 100644 --- a/src/canvas.class.js +++ b/src/canvas.class.js @@ -474,7 +474,8 @@ var t = this._currentTransform, target = t.target, lockScalingX = target.get('lockScalingX'), - lockScalingY = target.get('lockScalingY'); + lockScalingY = target.get('lockScalingY'), + lockScalingFlip = target.get('lockScalingFlip'); if (lockScalingX && lockScalingY) { return; @@ -487,7 +488,7 @@ this._setLocalMouse(localMouse, t); // Actually scale the object - this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by); + this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip); // Make sure the constraints apply target.setPositionByOrigin(constraintPosition, t.originX, t.originY); @@ -496,32 +497,36 @@ /** * @private */ - _setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by) { - var target = transform.target; + _setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip) { + var target = transform.target, forbidScalingX = false, forbidScalingY = false; - transform.newScaleX = target.scaleX; - transform.newScaleY = target.scaleY; + transform.newScaleX = localMouse.x / (target.width + target.strokeWidth); + transform.newScaleY = localMouse.y / (target.height + target.strokeWidth); + + if (lockScalingFlip && transform.newScaleX <= 0 && transform.newScaleX < target.scaleX) { + forbidScalingX = true; + } + + if (lockScalingFlip && transform.newScaleY <= 0 && transform.newScaleY < target.scaleY) { + forbidScalingY = true; + } if (by === 'equally' && !lockScalingX && !lockScalingY) { - this._scaleObjectEqually(localMouse, target, transform); + forbidScalingX || forbidScalingY || this._scaleObjectEqually(localMouse, target, transform); } else if (!by) { - transform.newScaleX = localMouse.x / (target.width + target.strokeWidth); - transform.newScaleY = localMouse.y / (target.height + target.strokeWidth); - - lockScalingX || target.set('scaleX', transform.newScaleX); - lockScalingY || target.set('scaleY', transform.newScaleY); + forbidScalingX || lockScalingX || target.set('scaleX', transform.newScaleX); + forbidScalingY || lockScalingY || target.set('scaleY', transform.newScaleY); } else if (by === 'x' && !target.get('lockUniScaling')) { - transform.newScaleX = localMouse.x / (target.width + target.strokeWidth); - lockScalingX || target.set('scaleX', transform.newScaleX); + forbidScalingX || lockScalingX || target.set('scaleX', transform.newScaleX); } else if (by === 'y' && !target.get('lockUniScaling')) { - transform.newScaleY = localMouse.y / (target.height + target.strokeWidth); - lockScalingY || target.set('scaleY', transform.newScaleY); + forbidScalingY || lockScalingY || target.set('scaleY', transform.newScaleY); } - this._flipObject(transform); + forbidScalingX || forbidScalingY || this._flipObject(transform); + }, /** diff --git a/src/shapes/object.class.js b/src/shapes/object.class.js index 7c433305..97671aa3 100644 --- a/src/shapes/object.class.js +++ b/src/shapes/object.class.js @@ -658,6 +658,13 @@ */ lockUniScaling: false, + /** + * When `true`, object cannot be flipped by scaling into negative values + * @type Boolean + * @default + */ + + lockScalingFlip: false, /** * List of properties to consider when checking if state * of an object is changed (fabric.Object#hasStateChanged)