Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fabric

Package Overview
Dependencies
Maintainers
2
Versions
304
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fabric - npm Package Compare versions

Comparing version 3.6.1 to 4.0.0-beta1

src/control.class.js

5

build.js

@@ -152,2 +152,5 @@ var fs = require('fs'),

'src/color.class.js',
ifSpecifiedInclude('interaction', 'src/controls.actions.js'),
ifSpecifiedInclude('interaction', 'src/controls.render.js'),
ifSpecifiedInclude('interaction', 'src/control.class.js'),

@@ -232,3 +235,3 @@ ifSpecifiedInclude('gradient', 'src/gradient.class.js'),

ifSpecifiedInclude('textbox', 'src/shapes/textbox.class.js'),
ifSpecifiedInclude('interaction', 'src/mixins/default_controls.js'),
];

@@ -235,0 +238,0 @@

2

HEADER.js
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */
var fabric = fabric || { version: '3.6.1' };
var fabric = fabric || { version: '4.0.0-beta.1' };
if (typeof exports !== 'undefined') {

@@ -5,0 +5,0 @@ exports.fabric = fabric;

@@ -5,4 +5,4 @@ {

"homepage": "http://fabricjs.com/",
"version": "3.6.1",
"authors": "Juriy Zaytsev <kangax@gmail.com>",
"version": "4.0.0-beta1",
"author": "Juriy Zaytsev <kangax@gmail.com>",
"contributors": [

@@ -47,2 +47,3 @@ {

"build:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm run build_export",
"link:watch": "onchange 'src/**/**' 'HEADER.js' 'lib/**/**' -- npm link",
"build_with_gestures": "node build.js modules=ALL exclude=accessors",

@@ -49,0 +50,0 @@ "build_export": "npm run build:fast && npm run export_dist_to_site",

### Fabric
<!-- chat, support -->
[![Gitter](https://badges.gitter.im/JoinChat.svg)](https://gitter.im/kangax/fabric.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
<!-- build/coverage status, climate -->

@@ -8,0 +3,0 @@

@@ -5,7 +5,5 @@ (function() {

degreesToRadians = fabric.util.degreesToRadians,
radiansToDegrees = fabric.util.radiansToDegrees,
atan2 = Math.atan2,
abs = Math.abs,
supportLineDash = fabric.StaticCanvas.supports('setLineDash'),
isTouchEvent = fabric.util.isTouchEvent,
STROKE_OFFSET = 0.5;

@@ -20,14 +18,14 @@

*
* @fires object:modified
* @fires object:rotated
* @fires object:scaled
* @fires object:moved
* @fires object:skewed
* @fires object:rotating
* @fires object:scaling
* @fires object:moving
* @fires object:skewing
* @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
* @fires object:skewing while an object is being skewed from the controls
* @fires object:selected this event is deprecated. use selection:created
*
* @fires before:transform
* @fires before:transform before a transform is is started
* @fires before:selection:cleared

@@ -38,12 +36,12 @@ * @fires selection:cleared

*
* @fires path:created
* @fires path:created after a drawing operation ends and the path is added
* @fires mouse:down
* @fires mouse:move
* @fires mouse:up
* @fires mouse:down:before
* @fires mouse:move:before
* @fires mouse:up:before
* @fires mouse:down:before on mouse down, before the inner fabric logic runs
* @fires mouse:move:before on mouse move, before the inner fabric logic runs
* @fires mouse:up:before on mouse up, before the inner fabric logic runs
* @fires mouse:over
* @fires mouse:out
* @fires mouse:dblclick
* @fires mouse:dblclick whenever a native dbl click event fires on the canvas.
*

@@ -54,2 +52,4 @@ * @fires dragover

* @fires drop
* @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
*

@@ -76,12 +76,17 @@ */

* When true, objects can be transformed by one side (unproportionally)
* when dragged on the corners that normally would not do that.
* @type Boolean
* @default
* @since fabric 4.0 // changed name and default value
*/
uniScaleTransform: false,
uniformScaling: true,
/**
* Indicates which key enable unproportional scaling
* Indicates which key switches uniform scaling.
* values: 'altKey', 'shiftKey', 'ctrlKey'.
* If `null` or 'none' or any other string that is not a modifier key
* feature is disabled feature disabled.
* feature is disabled.
* totally wrong named. this sounds like `uniform scaling`
* if Canvas.uniformScaling is true, pressing this will set it to false
* and viceversa.
* @since 1.6.2

@@ -454,45 +459,2 @@ * @type String

/**
* Resets the current transform to its original values and chooses the type of resizing based on the event
* @private
*/
_resetCurrentTransform: function() {
var t = this._currentTransform;
t.target.set({
scaleX: t.original.scaleX,
scaleY: t.original.scaleY,
skewX: t.original.skewX,
skewY: t.original.skewY,
left: t.original.left,
top: t.original.top
});
if (this._shouldCenterTransform(t.target)) {
if (t.originX !== 'center') {
if (t.originX === 'right') {
t.mouseXSign = -1;
}
else {
t.mouseXSign = 1;
}
}
if (t.originY !== 'center') {
if (t.originY === 'bottom') {
t.mouseYSign = -1;
}
else {
t.mouseYSign = 1;
}
}
t.originX = 'center';
t.originY = 'center';
}
else {
t.originX = t.original.originX;
t.originY = t.original.originY;
}
},
/**
* Checks if point is contained within an area of given object

@@ -507,3 +469,3 @@ * @param {Event} e Event object

pointer = point || this.getPointer(e, ignoreZoom),
xy;
xy, isTouch = e ? isTouchEvent(e) : false;

@@ -518,3 +480,3 @@ if (target.group && target.group === this._activeObject && target.group.type === 'activeSelection') {

// http://idav.ucdavis.edu/~okreylos/TAship/Spring2000/PointInPolygon.html
return (target.containsPoint(xy) || target._findTargetCorner(pointer));
return (target.containsPoint(xy) || !!target._findTargetCorner(pointer, isTouch));
},

@@ -629,6 +591,9 @@

* this should be fixed, since object setting should take precedence over canvas.
* also this should be something that will be migrated in the control properties.
* as ability to define the origin of the transformation that the control provide.
* @private
* @param {fabric.Object} target
* @param {String} action
*/
_shouldCenterTransform: function (target) {
_shouldCenterTransform: function (target, action, altKey) {
if (!target) {

@@ -638,16 +603,16 @@ return;

var t = this._currentTransform,
centerTransform;
var centerTransform;
if (t.action === 'scale' || t.action === 'scaleX' || t.action === 'scaleY') {
if (action === 'scale' || action === 'scaleX' || action === 'scaleY') {
centerTransform = this.centeredScaling || target.centeredScaling;
}
else if (t.action === 'rotate') {
else if (action === 'rotate') {
centerTransform = this.centeredRotation || target.centeredRotation;
}
return centerTransform ? !t.altKey : t.altKey;
return centerTransform ? !altKey : altKey;
},
/**
* should disappear before release 4.0
* @private

@@ -674,3 +639,6 @@ */

}
else if (corner === 'mtr') {
origin.x = 'center';
origin.y = 'center';
}
return origin;

@@ -686,19 +654,8 @@ },

*/
_getActionFromCorner: function(alreadySelected, corner, e /* target */) {
_getActionFromCorner: function(alreadySelected, corner, e, target) {
if (!corner || !alreadySelected) {
return 'drag';
}
switch (corner) {
case 'mtr':
return 'rotate';
case 'ml':
case 'mr':
return e[this.altActionKey] ? 'skewY' : 'scaleX';
case 'mt':
case 'mb':
return e[this.altActionKey] ? 'skewX' : 'scaleY';
default:
return 'scale';
}
var control = target.controls[corner];
return control.getActionName(e, control, target);
},

@@ -716,41 +673,44 @@

var pointer = this.getPointer(e),
corner = target._findTargetCorner(this.getPointer(e, true)),
var pointer = this.getPointer(e), isTouch = isTouchEvent(e),
corner = target._findTargetCorner(this.getPointer(e, true), isTouch),
actionHandler = !!corner && target.controls[corner].getActionHandler(),
action = this._getActionFromCorner(alreadySelected, corner, e, target),
origin = this._getOriginFromCorner(target, corner);
origin = this._getOriginFromCorner(target, corner),
altKey = e[this.centeredKey],
transform = {
target: target,
action: action,
actionHandler: actionHandler,
corner: corner,
scaleX: target.scaleX,
scaleY: target.scaleY,
skewX: target.skewX,
skewY: target.skewY,
// used by transation
offsetX: pointer.x - target.left,
offsetY: pointer.y - target.top,
originX: origin.x,
originY: origin.y,
ex: pointer.x,
ey: pointer.y,
lastX: pointer.x,
lastY: pointer.y,
// unsure they are usefull anymore.
// left: target.left,
// top: target.top,
theta: degreesToRadians(target.angle),
// end of unsure
width: target.width * target.scaleX,
shiftKey: e.shiftKey,
altKey: altKey,
original: fabric.util.saveObjectTransform(target),
};
this._currentTransform = {
target: target,
action: action,
corner: corner,
scaleX: target.scaleX,
scaleY: target.scaleY,
skewX: target.skewX,
skewY: target.skewY,
// used by transation
offsetX: pointer.x - target.left,
offsetY: pointer.y - target.top,
originX: origin.x,
originY: origin.y,
ex: pointer.x,
ey: pointer.y,
lastX: pointer.x,
lastY: pointer.y,
// unsure they are usefull anymore.
// left: target.left,
// top: target.top,
theta: degreesToRadians(target.angle),
// end of unsure
width: target.width * target.scaleX,
mouseXSign: 1,
mouseYSign: 1,
shiftKey: e.shiftKey,
altKey: e[this.centeredKey],
original: fabric.util.saveObjectTransform(target),
};
this._currentTransform.original.originX = origin.x;
this._currentTransform.original.originY = origin.y;
this._resetCurrentTransform();
if (this._shouldCenterTransform(target, action, altKey)) {
transform.originX = 'center';
transform.originY = 'center';
}
transform.original.originX = origin.x;
transform.original.originY = origin.y;
this._currentTransform = transform;
this._beforeTransform(e);

@@ -780,356 +740,2 @@ },

/**
* Check if we are increasing a positive skew or lower it,
* checking mouse direction and pressed corner.
* @private
*/
_changeSkewTransformOrigin: function(mouseMove, t, by) {
var property = 'originX', origins = { 0: 'center' },
skew = t.target.skewX, originA = 'left', originB = 'right',
corner = t.corner === 'mt' || t.corner === 'ml' ? 1 : -1,
flipSign = 1;
mouseMove = mouseMove > 0 ? 1 : -1;
if (by === 'y') {
skew = t.target.skewY;
originA = 'top';
originB = 'bottom';
property = 'originY';
}
origins[-1] = originA;
origins[1] = originB;
t.target.flipX && (flipSign *= -1);
t.target.flipY && (flipSign *= -1);
if (skew === 0) {
t.skewSign = -corner * mouseMove * flipSign;
t[property] = origins[-mouseMove];
}
else {
skew = skew > 0 ? 1 : -1;
t.skewSign = skew;
t[property] = origins[skew * corner * flipSign];
}
},
/**
* Skew object by mouse events
* @private
* @param {Number} x pointer's x coordinate
* @param {Number} y pointer's y coordinate
* @param {String} by Either 'x' or 'y'
* @return {Boolean} true if the skewing occurred
*/
_skewObject: function (x, y, by) {
var t = this._currentTransform,
target = t.target, skewed = false,
lockSkewingX = target.get('lockSkewingX'),
lockSkewingY = target.get('lockSkewingY');
if ((lockSkewingX && by === 'x') || (lockSkewingY && by === 'y')) {
return false;
}
// Get the constraint point
var center = target.getCenterPoint(),
actualMouseByCenter = target.toLocalPoint(new fabric.Point(x, y), 'center', 'center')[by],
lastMouseByCenter = target.toLocalPoint(new fabric.Point(t.lastX, t.lastY), 'center', 'center')[by],
actualMouseByOrigin, constraintPosition, dim = target._getTransformedDimensions();
this._changeSkewTransformOrigin(actualMouseByCenter - lastMouseByCenter, t, by);
actualMouseByOrigin = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY)[by];
constraintPosition = target.translateToOriginPoint(center, t.originX, t.originY);
// Actually skew the object
skewed = this._setObjectSkew(actualMouseByOrigin, t, by, dim);
t.lastX = x;
t.lastY = y;
// Make sure the constraints apply
target.setPositionByOrigin(constraintPosition, t.originX, t.originY);
return skewed;
},
/**
* Set object skew
* @private
* @return {Boolean} true if the skewing occurred
*/
_setObjectSkew: function(localMouse, transform, by, _dim) {
var target = transform.target, newValue, skewed = false,
skewSign = transform.skewSign, newDim, dimNoSkew,
otherBy, _otherBy, _by, newDimMouse, skewX, skewY;
if (by === 'x') {
otherBy = 'y';
_otherBy = 'Y';
_by = 'X';
skewX = 0;
skewY = target.skewY;
}
else {
otherBy = 'x';
_otherBy = 'X';
_by = 'Y';
skewX = target.skewX;
skewY = 0;
}
dimNoSkew = target._getTransformedDimensions(skewX, skewY);
newDimMouse = 2 * Math.abs(localMouse) - dimNoSkew[by];
if (newDimMouse <= 2) {
newValue = 0;
}
else {
newValue = skewSign * Math.atan((newDimMouse / target['scale' + _by]) /
(dimNoSkew[otherBy] / target['scale' + _otherBy]));
newValue = fabric.util.radiansToDegrees(newValue);
}
skewed = target['skew' + _by] !== newValue;
target.set('skew' + _by, newValue);
if (target['skew' + _otherBy] !== 0) {
newDim = target._getTransformedDimensions();
newValue = (_dim[otherBy] / newDim[otherBy]) * target['scale' + _otherBy];
target.set('scale' + _otherBy, newValue);
}
return skewed;
},
/**
* Scales object by invoking its scaleX/scaleY methods
* @private
* @param {Number} x pointer's x coordinate
* @param {Number} y pointer's y coordinate
* @param {String} by Either 'x' or 'y' - specifies dimension constraint by which to scale an object.
* When not provided, an object is scaled by both dimensions equally
* @return {Boolean} true if the scaling occurred
*/
_scaleObject: function (x, y, by) {
var t = this._currentTransform,
target = t.target,
lockScalingX = target.lockScalingX,
lockScalingY = target.lockScalingY,
lockScalingFlip = target.lockScalingFlip;
if (lockScalingX && lockScalingY) {
return false;
}
// Get the constraint point
var constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY),
localMouse = target.toLocalPoint(new fabric.Point(x, y), t.originX, t.originY),
dim = target._getTransformedDimensions(), scaled = false;
this._setLocalMouse(localMouse, t);
// Actually scale the object
scaled = this._setObjectScale(localMouse, t, lockScalingX, lockScalingY, by, lockScalingFlip, dim);
// Make sure the constraints apply
target.setPositionByOrigin(constraintPosition, t.originX, t.originY);
return scaled;
},
/**
* @private
* @return {Boolean} true if the scaling occurred
*/
_setObjectScale: function(localMouse, transform, lockScalingX, lockScalingY, by, lockScalingFlip, _dim) {
var target = transform.target, forbidScalingX = false, forbidScalingY = false, scaled = false,
scaleX = localMouse.x * target.scaleX / _dim.x,
scaleY = localMouse.y * target.scaleY / _dim.y,
changeX = target.scaleX !== scaleX,
changeY = target.scaleY !== scaleY;
transform.newScaleX = scaleX;
transform.newScaleY = scaleY;
if (fabric.Textbox && by === 'x' && target instanceof fabric.Textbox) {
var w = target.width * (localMouse.x / _dim.x);
if (w >= target.getMinWidth()) {
scaled = w !== target.width;
target.set('width', w);
return scaled;
}
return false;
}
if (lockScalingFlip && scaleX <= 0 && scaleX < target.scaleX) {
forbidScalingX = true;
localMouse.x = 0;
}
if (lockScalingFlip && scaleY <= 0 && scaleY < target.scaleY) {
forbidScalingY = true;
localMouse.y = 0;
}
if (by === 'equally' && !lockScalingX && !lockScalingY) {
scaled = this._scaleObjectEqually(localMouse, target, transform, _dim);
}
else if (!by) {
forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = scaled || changeX));
forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = scaled || changeY));
}
else if (by === 'x' && !target.get('lockUniScaling')) {
forbidScalingX || lockScalingX || (target.set('scaleX', scaleX) && (scaled = changeX));
}
else if (by === 'y' && !target.get('lockUniScaling')) {
forbidScalingY || lockScalingY || (target.set('scaleY', scaleY) && (scaled = changeY));
}
forbidScalingX || forbidScalingY || this._flipObject(transform, by);
return scaled;
},
/**
* @private
* @return {Boolean} true if the scaling occurred
*/
_scaleObjectEqually: function(localMouse, target, transform, _dim) {
var dist = localMouse.y + localMouse.x,
lastDist = _dim.y * transform.original.scaleY / target.scaleY +
_dim.x * transform.original.scaleX / target.scaleX,
scaled, signX = localMouse.x < 0 ? -1 : 1,
signY = localMouse.y < 0 ? -1 : 1, newScaleX, newScaleY;
// We use transform.scaleX/Y instead of target.scaleX/Y
// because the object may have a min scale and we'll loose the proportions
newScaleX = signX * Math.abs(transform.original.scaleX * dist / lastDist);
newScaleY = signY * Math.abs(transform.original.scaleY * dist / lastDist);
scaled = newScaleX !== target.scaleX || newScaleY !== target.scaleY;
target.set('scaleX', newScaleX);
target.set('scaleY', newScaleY);
return scaled;
},
/**
* @private
*/
_flipObject: function(transform, by) {
if (transform.newScaleX < 0 && by !== 'y') {
if (transform.originX === 'left') {
transform.originX = 'right';
}
else if (transform.originX === 'right') {
transform.originX = 'left';
}
}
if (transform.newScaleY < 0 && by !== 'x') {
if (transform.originY === 'top') {
transform.originY = 'bottom';
}
else if (transform.originY === 'bottom') {
transform.originY = 'top';
}
}
},
/**
* @private
*/
_setLocalMouse: function(localMouse, t) {
var target = t.target, zoom = this.getZoom(),
padding = target.padding / zoom;
if (t.originX === 'right') {
localMouse.x *= -1;
}
else if (t.originX === 'center') {
localMouse.x *= t.mouseXSign * 2;
if (localMouse.x < 0) {
t.mouseXSign = -t.mouseXSign;
}
}
if (t.originY === 'bottom') {
localMouse.y *= -1;
}
else if (t.originY === 'center') {
localMouse.y *= t.mouseYSign * 2;
if (localMouse.y < 0) {
t.mouseYSign = -t.mouseYSign;
}
}
// adjust the mouse coordinates when dealing with padding
if (abs(localMouse.x) > padding) {
if (localMouse.x < 0) {
localMouse.x += padding;
}
else {
localMouse.x -= padding;
}
}
else { // mouse is within the padding, set to 0
localMouse.x = 0;
}
if (abs(localMouse.y) > padding) {
if (localMouse.y < 0) {
localMouse.y += padding;
}
else {
localMouse.y -= padding;
}
}
else {
localMouse.y = 0;
}
},
/**
* Rotates object by invoking its rotate method
* @private
* @param {Number} x pointer's x coordinate
* @param {Number} y pointer's y coordinate
* @return {Boolean} true if the rotation occurred
*/
_rotateObject: function (x, y) {
var t = this._currentTransform,
target = t.target, constraintPosition,
constraintPosition = target.translateToOriginPoint(target.getCenterPoint(), t.originX, t.originY);
if (target.lockRotation) {
return false;
}
var lastAngle = atan2(t.ey - constraintPosition.y, t.ex - constraintPosition.x),
curAngle = atan2(y - constraintPosition.y, x - constraintPosition.x),
angle = radiansToDegrees(curAngle - lastAngle + t.theta),
hasRotated = true;
if (target.snapAngle > 0) {
var snapAngle = target.snapAngle,
snapThreshold = target.snapThreshold || snapAngle,
rightAngleLocked = Math.ceil(angle / snapAngle) * snapAngle,
leftAngleLocked = Math.floor(angle / snapAngle) * snapAngle;
if (Math.abs(angle - leftAngleLocked) < snapThreshold) {
angle = leftAngleLocked;
}
else if (Math.abs(angle - rightAngleLocked) < snapThreshold) {
angle = rightAngleLocked;
}
}
// normalize angle to positive value
if (angle < 0) {
angle = 360 + angle;
}
angle %= 360;
if (target.angle === angle) {
hasRotated = false;
}
else {
// rotation only happen here
target.angle = angle;
// Make sure the constraints apply
target.setPositionByOrigin(constraintPosition, t.originX, t.originY);
}
return hasRotated;
},
/**
* Set the cursor type of the canvas element

@@ -1216,3 +822,4 @@ * @param {String} value Cursor type of the canvas element.

aObjects = this.getActiveObjects(),
activeTarget, activeTargetSubs;
activeTarget, activeTargetSubs,
isTouch = isTouchEvent(e);

@@ -1228,3 +835,3 @@ // first check current group (if one exists)

// if we hit the corner of an activeObject, let's return that.
if (aObjects.length === 1 && activeObject._findTargetCorner(pointer)) {
if (aObjects.length === 1 && activeObject._findTargetCorner(pointer, isTouch)) {
return activeObject;

@@ -1263,3 +870,3 @@ }

obj.evented &&
this.containsPoint(null, obj, pointer)){
this.containsPoint(null, obj, pointer)) {
if ((this.perPixelTargetFind || obj.perPixelTargetFind) && !obj.isEditing) {

@@ -1266,0 +873,0 @@ var isTransparent = this.isTargetTransparent(obj, globalPointer.x, globalPointer.y);

@@ -320,9 +320,6 @@ (function() {

* @param {CanvasRenderingContext2D} ctx Context to render on
* @param {fabric.Object} object the fabric.Object for which the gradient is
* @return {CanvasGradient}
*/
toLive: function(ctx, object) {
var gradient, coords = fabric.util.object.clone(this.coords), i, len,
x1 = coords.x1, y1 = coords.y1, x2 = coords.x2, y2 = coords.y2,
stops = this.colorStops;
toLive: function(ctx) {
var gradient, coords = fabric.util.object.clone(this.coords), i, len;

@@ -333,19 +330,16 @@ if (!this.type) {

if (object instanceof fabric.Text && this.gradientUnits === 'percentage') {
x1 *= object.width;
y1 *= object.height;
x2 *= object.width;
y2 *= object.height;
}
if (this.type === 'linear') {
gradient = ctx.createLinearGradient(x1, y1, x2, y2);
gradient = ctx.createLinearGradient(
coords.x1, coords.y1, coords.x2, coords.y2);
}
else if (this.type === 'radial') {
gradient = ctx.createRadialGradient(x1, y1, coords.r1, x2, y2, coords.r2);
gradient = ctx.createRadialGradient(
coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2);
}
for (i = 0, len = stops.length; i < len; i++) {
var color = stops[i].color,
opacity = stops[i].opacity,
offset = stops[i].offset;
for (i = 0, len = this.colorStops.length; i < len; i++) {
var color = this.colorStops[i].color,
opacity = this.colorStops[i].opacity,
offset = this.colorStops[i].offset;
if (typeof opacity !== 'undefined') {

@@ -352,0 +346,0 @@ color = new fabric.Color(color).setAlpha(opacity).toRgba();

(function() {
var cursorOffset = {
mt: 0, // n
tr: 1, // ne
mr: 2, // e
br: 3, // se
mb: 4, // s
bl: 5, // sw
ml: 6, // w
tl: 7 // nw
},
addListener = fabric.util.addListener,
var addListener = fabric.util.addListener,
removeListener = fabric.util.removeListener,

@@ -25,17 +15,2 @@ RIGHT_CLICK = 3, MIDDLE_CLICK = 2, LEFT_CLICK = 1,

/**
* Map of cursor style values for each of the object controls
* @private
*/
cursorMap: [
'n-resize',
'ne-resize',
'e-resize',
'se-resize',
's-resize',
'sw-resize',
'w-resize',
'nw-resize'
],
/**
* Contains the id of the touch event that owns the fabric transform

@@ -772,6 +747,2 @@ * @type Number

});
// determine if it's a drag or rotate case
if (t.corner) {
this.onBeforeScaleRotate(t.target);
}
},

@@ -934,5 +905,3 @@

this._beforeScaleTransform(e, transform);
this._performTransformAction(e, transform, pointer);
transform.actionPerformed && this.requestRenderAll();

@@ -949,2 +918,3 @@ },

actionPerformed = false,
// this object could be created from the function in the control handlers
options = {

@@ -957,21 +927,3 @@ target: transform.target,

if (action === 'rotate') {
(actionPerformed = this._rotateObject(x, y)) && this._fire('rotating', options);
}
else if (action === 'scale') {
(actionPerformed = this._onScale(e, transform, x, y)) && this._fire('scaling', options);
}
else if (action === 'scaleX') {
(actionPerformed = this._scaleObject(x, y, 'x')) && this._fire('scaling', options);
}
else if (action === 'scaleY') {
(actionPerformed = this._scaleObject(x, y, 'y')) && this._fire('scaling', options);
}
else if (action === 'skewX') {
(actionPerformed = this._skewObject(x, y, 'x')) && this._fire('skewing', options);
}
else if (action === 'skewY') {
(actionPerformed = this._skewObject(x, y, 'y')) && this._fire('skewing', options);
}
else {
if (action === 'drag') {
actionPerformed = this._translateObject(x, y);

@@ -983,53 +935,6 @@ if (actionPerformed) {

}
transform.actionPerformed = transform.actionPerformed || actionPerformed;
},
/**
* @private
*/
_fire: function(eventName, options) {
this.fire('object:' + eventName, options);
options.target.fire(eventName, options);
},
/**
* @private
*/
_beforeScaleTransform: function(e, transform) {
if (transform.action === 'scale' || transform.action === 'scaleX' || transform.action === 'scaleY') {
var centerTransform = this._shouldCenterTransform(transform.target);
// Switch from a normal resize to center-based
if ((centerTransform && (transform.originX !== 'center' || transform.originY !== 'center')) ||
// Switch from center-based resize to normal one
(!centerTransform && transform.originX === 'center' && transform.originY === 'center')
) {
this._resetCurrentTransform();
transform.reset = true;
}
}
},
/**
* @private
* @param {Event} e Event object
* @param {Object} transform current transform
* @param {Number} x mouse position x from origin
* @param {Number} y mouse position y from origin
* @return {Boolean} true if the scaling occurred
*/
_onScale: function(e, transform, x, y) {
if (this._isUniscalePossible(e, transform.target)) {
transform.currentAction = 'scale';
return this._scaleObject(x, y);
}
else {
// Switch from a normal resize to proportional
if (!transform.reset && transform.currentAction === 'scale') {
this._resetCurrentTransform();
}
transform.currentAction = 'scaleEqually';
return this._scaleObject(x, y, 'equally');
(actionPerformed = transform.actionHandler(e, transform, x, y)) && this._fire(action, options);
}
transform.actionPerformed = transform.actionPerformed || actionPerformed;
},

@@ -1039,9 +944,4 @@

* @private
* @param {Event} e Event object
* @param {fabric.Object} target current target
* @return {Boolean} true if unproportional scaling is possible
*/
_isUniscalePossible: function(e, target) {
return (e[this.uniScaleKey] || this.uniScaleTransform) && !target.get('lockUniScaling');
},
_fire: fabric.controlHandlers.fireEvent,

@@ -1064,2 +964,5 @@ /**

corner = (!activeSelection || !activeSelection.contains(target))
// here we call findTargetCorner always with undefined for the touch parameter.
// we assume that if you are using a cursor you do not need to interact with
// the bigger touch area.
&& target._findTargetCorner(this.getPointer(e, true));

@@ -1086,52 +989,6 @@

getCornerCursor: function(corner, target, e) {
if (this.actionIsDisabled(corner, target, e)) {
return this.notAllowedCursor;
}
else if (corner in cursorOffset) {
return this._getRotatedCornerCursor(corner, target, e);
}
else if (corner === 'mtr' && target.hasRotatingPoint) {
return this.rotationCursor;
}
else {
return this.defaultCursor;
}
},
actionIsDisabled: function(corner, target, e) {
if (corner === 'mt' || corner === 'mb') {
return e[this.altActionKey] ? target.lockSkewingX : target.lockScalingY;
}
else if (corner === 'ml' || corner === 'mr') {
return e[this.altActionKey] ? target.lockSkewingY : target.lockScalingX;
}
else if (corner === 'mtr') {
return target.lockRotation;
}
else {
return this._isUniscalePossible(e, target) ?
target.lockScalingX && target.lockScalingY : target.lockScalingX || target.lockScalingY;
}
},
/**
* @private
*/
_getRotatedCornerCursor: function(corner, target, e) {
var n = Math.round((target.angle % 360) / 45);
if (n < 0) {
n += 8; // full circle ahead
}
n += cursorOffset[corner];
if (e[this.altActionKey] && cursorOffset[corner] % 2 === 0) {
//if we are holding shift and we are on a mx corner...
n += 2;
}
// normalize n to be from 0 to 7
n %= 8;
return this.cursorMap[n];
var control = target.controls[corner];
return control.cursorStyleHandler(e, control, target);
}
});
})();

@@ -57,2 +57,8 @@ (function() {

/**
* custom controls interface
* controls are added by default_controls.js
*/
controls: { },
/**
* return correct set of coordinates for intersection

@@ -64,3 +70,3 @@ */

}
var coords = absolute ? this.aCoords : this.oCoords;
var coords = absolute ? this.aCoords : this.lineCoords;
return getCoords(calculate ? this.calcCoords(absolute) : coords);

@@ -114,5 +120,4 @@ },

var points = this.getCoords(absolute, calculate),
i = 0, lines = other._getImageLines(
calculate ? other.calcCoords(absolute) : absolute ? other.aCoords : other.oCoords
);
otherCoords = absolute ? other.aCoords : other.lineCoords,
i = 0, lines = other._getImageLines(otherCoords);
for (; i < 4; i++) {

@@ -154,7 +159,5 @@ if (!other.containsPoint(points[i], lines)) {

containsPoint: function(point, lines, absolute, calculate) {
var lines = lines || this._getImageLines(
calculate ? this.calcCoords(absolute) : absolute ? this.aCoords : this.oCoords
),
var coords = calculate ? this.calcLineCoords(absolute) : absolute ? this.aCoords : this.lineCoords,
lines = lines || this._getImageLines(coords),
xPoints = this._findCrossPoints(point, lines);
// if xPoints is odd then point is inside the object

@@ -229,3 +232,4 @@ return (xPoints !== 0 && xPoints % 2 === 1);

_getImageLines: function(oCoords) {
return {
var lines = {
topline: {

@@ -248,2 +252,19 @@ o: oCoords.tl,

};
// // debugging
// if (this.canvas.contextTop) {
// this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);
// this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);
//
// this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);
// this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);
//
// this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);
// this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);
//
// this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);
// this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);
// }
return lines;
},

@@ -396,2 +417,46 @@

calcCoords: function(absolute) {
// this is a compatibility function to avoid removing calcCoords now.
if (absolute) {
return this.calcACoords();
}
return this.calcOCoords();
},
calcLineCoords: function(ignoreZoom) {
if (!this.aCoords) { this.aCoords = this.calcACoords(); }
var vpt = this.getViewportTransform();
var padding = this.padding, angle = degreesToRadians(this.angle),
cos = fabric.util.cos(angle), sin = fabric.util.sin(angle),
cosP = cos * padding, sinP = sin * padding, cosPSinP = cosP + sinP,
cosPMinusSinP = cosP - sinP, aCoords = this.aCoords;
var lineCoords = {
tl: { x: aCoords.tl.x, y: aCoords.tl.y },
tr: { x: aCoords.tr.x, y: aCoords.tr.y },
bl: { x: aCoords.bl.x, y: aCoords.bl.y },
br: { x: aCoords.br.x, y: aCoords.br.y },
};
if (!ignoreZoom) {
lineCoords.tl = transformPoint(aCoords.tl, vpt);
lineCoords.tr = transformPoint(aCoords.tr, vpt);
lineCoords.bl = transformPoint(aCoords.bl, vpt);
lineCoords.br = transformPoint(aCoords.br, vpt);
}
if (padding) {
lineCoords.tl.x -= cosPMinusSinP;
lineCoords.tl.y -= cosPSinP;
lineCoords.tr.x += cosPSinP;
lineCoords.tr.y -= cosPMinusSinP;
lineCoords.bl.x -= cosPSinP;
lineCoords.bl.y += cosPMinusSinP;
lineCoords.br.x += cosPMinusSinP;
lineCoords.br.y += cosPSinP;
}
return lineCoords;
},
calcOCoords: function() {
var rotateMatrix = this._calcRotateMatrix(),

@@ -401,62 +466,35 @@ translateMatrix = this._calcTranslateMatrix(),

vpt = this.getViewportTransform(),
finalMatrix = absolute ? startMatrix : multiplyMatrices(vpt, startMatrix),
finalMatrix = multiplyMatrices(vpt, startMatrix),
dim = this._getTransformedDimensions(),
w = dim.x / 2, h = dim.y / 2,
tl = transformPoint({ x: -w, y: -h }, finalMatrix),
tr = transformPoint({ x: w, y: -h }, finalMatrix),
bl = transformPoint({ x: -w, y: h }, finalMatrix),
br = transformPoint({ x: w, y: h }, finalMatrix);
if (!absolute) {
var padding = this.padding, angle = degreesToRadians(this.angle),
cos = fabric.util.cos(angle), sin = fabric.util.sin(angle),
cosP = cos * padding, sinP = sin * padding, cosPSinP = cosP + sinP,
cosPMinusSinP = cosP - sinP;
if (padding) {
tl.x -= cosPMinusSinP;
tl.y -= cosPSinP;
tr.x += cosPSinP;
tr.y -= cosPMinusSinP;
bl.x -= cosPSinP;
bl.y += cosPMinusSinP;
br.x += cosPMinusSinP;
br.y += cosPSinP;
}
var ml = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2),
mt = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2),
mr = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2),
mb = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2),
mtr = new fabric.Point(mt.x + sin * this.rotatingPointOffset, mt.y - cos * this.rotatingPointOffset);
}
coords = {};
this.forEachControl(function(control, fabricObject, key) {
coords[key] = control.positionHandler(dim, finalMatrix, fabricObject);
});
// if (!absolute) {
// var canvas = this.canvas;
// setTimeout(function() {
// canvas.contextTop.clearRect(0, 0, 700, 700);
// canvas.contextTop.fillStyle = 'green';
// canvas.contextTop.fillRect(mb.x, mb.y, 3, 3);
// canvas.contextTop.fillRect(bl.x, bl.y, 3, 3);
// canvas.contextTop.fillRect(br.x, br.y, 3, 3);
// canvas.contextTop.fillRect(tl.x, tl.y, 3, 3);
// canvas.contextTop.fillRect(tr.x, tr.y, 3, 3);
// canvas.contextTop.fillRect(ml.x, ml.y, 3, 3);
// canvas.contextTop.fillRect(mr.x, mr.y, 3, 3);
// canvas.contextTop.fillRect(mt.x, mt.y, 3, 3);
// canvas.contextTop.fillRect(mtr.x, mtr.y, 3, 3);
// }, 50);
// }
// debug code
// var canvas = this.canvas;
// setTimeout(function() {
// canvas.contextTop.clearRect(0, 0, 700, 700);
// canvas.contextTop.fillStyle = 'green';
// Object.keys(coords).forEach(function(key) {
// var control = coords[key];
// canvas.contextTop.fillRect(control.x, control.y, 3, 3);
// });
// }, 50);
return coords;
},
var coords = {
calcACoords: function() {
var rotateMatrix = this._calcRotateMatrix(),
translateMatrix = this._calcTranslateMatrix(),
finalMatrix = multiplyMatrices(translateMatrix, rotateMatrix),
dim = this._getTransformedDimensions(),
w = dim.x / 2, h = dim.y / 2;
return {
// corners
tl: tl, tr: tr, br: br, bl: bl,
tl: transformPoint({ x: -w, y: -h }, finalMatrix),
tr: transformPoint({ x: w, y: -h }, finalMatrix),
bl: transformPoint({ x: -w, y: h }, finalMatrix),
br: transformPoint({ x: w, y: h }, finalMatrix)
};
if (!absolute) {
// middle
coords.ml = ml;
coords.mt = mt;
coords.mr = mr;
coords.mb = mb;
// rotating point
coords.mtr = mtr;
}
return coords;
},

@@ -473,7 +511,8 @@

setCoords: function(ignoreZoom, skipAbsolute) {
this.oCoords = this.calcCoords(ignoreZoom);
// this.oCoords = this.calcCoords(ignoreZoom);
if (!skipAbsolute) {
this.aCoords = this.calcCoords(true);
this.aCoords = this.calcACoords();
}
this.oCoords = this.calcOCoords();
this.lineCoords = this.calcLineCoords(ignoreZoom);
// set coordinates of the draggable boxes in the corners used to scale/rotate the image

@@ -585,6 +624,4 @@ ignoreZoom || (this._setCornerCoords && this._setCornerCoords());

* Calculate object bounding box dimensions from its properties scale, skew.
* The skewX and skewY parameters are used in the skewing logic path and
* do not provide something useful to common use cases.
* @param {Number} [skewX], a value to override current skewX
* @param {Number} [skewY], a value to override current skewY
* @param {Number} skewX, a value to override current skewX
* @param {Number} skewY, a value to override current skewY
* @private

@@ -667,3 +704,3 @@ * @return {Object} .x width dimension

dim = this._getTransformedDimensions(),
p = fabric.util.transformPoint(dim, vpt, true);
p = transformPoint(dim, vpt, true);

@@ -670,0 +707,0 @@ return p.scalarAdd(2 * this.padding);

@@ -8,8 +8,2 @@ (function() {

/**
* The object interactivity controls.
* @private
*/
_controlsVisibility: null,
/**
* Determines which corner has been clicked

@@ -20,3 +14,3 @@ * @private

*/
_findTargetCorner: function(pointer) {
_findTargetCorner: function(pointer, forTouch) {
// objects in group, anykind, are not self modificable,

@@ -31,6 +25,9 @@ // must not return an hovered corner.

xPoints,
lines;
lines, keys = Object.keys(this.oCoords),
j = keys.length - 1, i;
this.__corner = 0;
for (var i in this.oCoords) {
// cycle in reverse order so we pick first the one on top
for (; j >= 0; j--) {
i = keys[j];
if (!this.isControlVisible(i)) {

@@ -40,27 +37,17 @@ continue;

if (i === 'mtr' && !this.hasRotatingPoint) {
continue;
}
if (this.get('lockUniScaling') &&
(i === 'mt' || i === 'mr' || i === 'mb' || i === 'ml')) {
continue;
}
lines = this._getImageLines(this.oCoords[i].corner);
lines = this._getImageLines(forTouch ? this.oCoords[i].touchCorner : this.oCoords[i].corner);
// debugging
// canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);
// canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);
// this.canvas.contextTop.fillRect(lines.bottomline.d.x, lines.bottomline.d.y, 2, 2);
// this.canvas.contextTop.fillRect(lines.bottomline.o.x, lines.bottomline.o.y, 2, 2);
//
// this.canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);
// this.canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);
//
// this.canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);
// this.canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);
//
// this.canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);
// this.canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);
// canvas.contextTop.fillRect(lines.leftline.d.x, lines.leftline.d.y, 2, 2);
// canvas.contextTop.fillRect(lines.leftline.o.x, lines.leftline.o.y, 2, 2);
// canvas.contextTop.fillRect(lines.topline.d.x, lines.topline.d.y, 2, 2);
// canvas.contextTop.fillRect(lines.topline.o.x, lines.topline.o.y, 2, 2);
// canvas.contextTop.fillRect(lines.rightline.d.x, lines.rightline.d.y, 2, 2);
// canvas.contextTop.fillRect(lines.rightline.o.x, lines.rightline.o.y, 2, 2);
xPoints = this._findCrossPoints({ x: ex, y: ey }, lines);

@@ -76,4 +63,17 @@ if (xPoints !== 0 && xPoints % 2 === 1) {

/**
* Calls a function for each control. The function gets called,
* with the control, the object that is calling the iterator and the control's key
* @param {Function} fn function to iterate over the controls over
*/
forEachControl: function(fn) {
for (var i in this.controls) {
fn(this.controls[i], this, i);
};
},
/**
* Sets the coordinates of the draggable boxes in the corners of
* the image used to scale/rotate it.
* note: if we would switch to ROUND corner area, all of this would disappear.
* everything would resolve to a single point and a pythagorean theorem for the distance
* @private

@@ -84,13 +84,18 @@ */

newTheta = degreesToRadians(45 - this.angle),
cosTheta = fabric.util.cos(newTheta),
sinTheta = fabric.util.sin(newTheta),
/* Math.sqrt(2 * Math.pow(this.cornerSize, 2)) / 2, */
/* 0.707106 stands for sqrt(2)/2 */
cornerHypotenuse = this.cornerSize * 0.707106,
cosHalfOffset = cornerHypotenuse * fabric.util.cos(newTheta),
sinHalfOffset = cornerHypotenuse * fabric.util.sin(newTheta),
touchHypotenuse = this.touchCornerSize * 0.707106,
cosHalfOffset = cornerHypotenuse * cosTheta,
sinHalfOffset = cornerHypotenuse * sinTheta,
touchCosHalfOffset = touchHypotenuse * cosTheta,
touchSinHalfOffset = touchHypotenuse * sinTheta,
x, y;
for (var point in coords) {
x = coords[point].x;
y = coords[point].y;
coords[point].corner = {
for (var control in coords) {
x = coords[control].x;
y = coords[control].y;
coords[control].corner = {
tl: {

@@ -113,2 +118,20 @@ x: x - sinHalfOffset,

};
coords[control].touchCorner = {
tl: {
x: x - touchSinHalfOffset,
y: y - touchCosHalfOffset
},
tr: {
x: x + touchCosHalfOffset,
y: y - touchSinHalfOffset
},
bl: {
x: x - touchCosHalfOffset,
y: y + touchSinHalfOffset
},
br: {
x: x + touchSinHalfOffset,
y: y + touchCosHalfOffset
}
};
}

@@ -160,8 +183,5 @@ },

height = wh.y + strokeWidth,
drawRotatingPoint = typeof styleOverride.hasRotatingPoint !== 'undefined' ?
styleOverride.hasRotatingPoint : this.hasRotatingPoint,
hasControls = typeof styleOverride.hasControls !== 'undefined' ?
styleOverride.hasControls : this.hasControls,
rotatingPointOffset = typeof styleOverride.rotatingPointOffset !== 'undefined' ?
styleOverride.rotatingPointOffset : this.rotatingPointOffset;
shouldStroke = false;

@@ -179,12 +199,21 @@ ctx.save();

if (drawRotatingPoint && this.isControlVisible('mtr') && hasControls) {
var rotateHeight = -height / 2;
ctx.beginPath();
ctx.moveTo(0, rotateHeight);
ctx.lineTo(0, rotateHeight - rotatingPointOffset);
ctx.stroke();
if (hasControls) {
this.forEachControl(function(control) {
// in this moment, the ctx is centered on the object.
// width and height of the above function are the size of the bbox.
ctx.beginPath();
if (control.withConnection && control.getVisibility()) {
// reset movement for each control
shouldStroke = true;
ctx.moveTo(control.x * width, control.y * height);
ctx.lineTo(
control.x * width + control.offsetX,
control.y * height + control.offsetY
);
}
});
if (shouldStroke) {
ctx.stroke();
}
}
ctx.restore();

@@ -243,15 +272,4 @@ return this;

styleOverride = styleOverride || {};
var wh = this._calculateCurrentDimensions(),
width = wh.x,
height = wh.y,
scaleOffset = styleOverride.cornerSize || this.cornerSize,
left = -(width + scaleOffset) / 2,
top = -(height + scaleOffset) / 2,
transparentCorners = typeof styleOverride.transparentCorners !== 'undefined' ?
styleOverride.transparentCorners : this.transparentCorners,
hasRotatingPoint = typeof styleOverride.hasRotatingPoint !== 'undefined' ?
styleOverride.hasRotatingPoint : this.hasRotatingPoint,
methodName = transparentCorners ? 'stroke' : 'fill';
ctx.save();
ctx.setTransform(this.canvas.getRetinaScaling(), 0, 0, this.canvas.getRetinaScaling(), 0, 0);
ctx.strokeStyle = ctx.fillStyle = styleOverride.cornerColor || this.cornerColor;

@@ -262,53 +280,9 @@ if (!this.transparentCorners) {

this._setLineDash(ctx, styleOverride.cornerDashArray || this.cornerDashArray, null);
// top-left
this._drawControl('tl', ctx, methodName,
left,
top, styleOverride);
// top-right
this._drawControl('tr', ctx, methodName,
left + width,
top, styleOverride);
// bottom-left
this._drawControl('bl', ctx, methodName,
left,
top + height, styleOverride);
// bottom-right
this._drawControl('br', ctx, methodName,
left + width,
top + height, styleOverride);
if (!this.get('lockUniScaling')) {
// middle-top
this._drawControl('mt', ctx, methodName,
left + width / 2,
top, styleOverride);
// middle-bottom
this._drawControl('mb', ctx, methodName,
left + width / 2,
top + height, styleOverride);
// middle-right
this._drawControl('mr', ctx, methodName,
left + width,
top + height / 2, styleOverride);
// middle-left
this._drawControl('ml', ctx, methodName,
left,
top + height / 2, styleOverride);
this.setCoords(false);
for (var c in this.controls) {
this.controls[c].render(ctx,
this.oCoords[c].x,
this.oCoords[c].y, styleOverride, this);
}
// middle-top-rotate
if (hasRotatingPoint) {
this._drawControl('mtr', ctx, methodName,
left + width / 2,
top - this.rotatingPointOffset, styleOverride);
}
ctx.restore();

@@ -320,35 +294,8 @@

/**
* @private
*/
_drawControl: function(control, ctx, methodName, left, top, styleOverride) {
styleOverride = styleOverride || {};
if (!this.isControlVisible(control)) {
return;
}
var size = this.cornerSize, stroke = !this.transparentCorners && this.cornerStrokeColor;
switch (styleOverride.cornerStyle || this.cornerStyle) {
case 'circle':
ctx.beginPath();
ctx.arc(left + size / 2, top + size / 2, size / 2, 0, 2 * Math.PI, false);
ctx[methodName]();
if (stroke) {
ctx.stroke();
}
break;
default:
this.transparentCorners || ctx.clearRect(left, top, size, size);
ctx[methodName + 'Rect'](left, top, size, size);
if (stroke) {
ctx.strokeRect(left, top, size, size);
}
}
},
/**
* Returns true if the specified control is visible, false otherwise.
* @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.
* @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.
* @returns {Boolean} true if the specified control is visible, false otherwise
*/
isControlVisible: function(controlName) {
return this._getControlsVisibility()[controlName];
isControlVisible: function(controlKey) {
return this.controls[controlKey] && this.controls[controlKey].getVisibility(this, controlKey);
},

@@ -358,3 +305,3 @@

* Sets the visibility of the specified control.
* @param {String} controlName The name of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.
* @param {String} controlKey The key of the control. Possible values are 'tl', 'tr', 'br', 'bl', 'ml', 'mt', 'mr', 'mb', 'mtr'.
* @param {Boolean} visible true to set the specified control visible, false otherwise

@@ -364,4 +311,4 @@ * @return {fabric.Object} thisArg

*/
setControlVisible: function(controlName, visible) {
this._getControlsVisibility()[controlName] = visible;
setControlVisible: function(controlKey, visible) {
this.controls[controlKey].setVisibility(visible, this, controlKey);
return this;

@@ -400,16 +347,7 @@ },

_getControlsVisibility: function() {
if (!this._controlsVisibility) {
this._controlsVisibility = {
tl: true,
tr: true,
br: true,
bl: true,
ml: true,
mt: true,
mr: true,
mb: true,
mtr: true
};
}
return this._controlsVisibility;
var visibility = {};
this.forEachControl(function(control, fabricObject, key) {
visibility[key] = control.getVisibility(fabricObject, key);
});
return visibility;
},

@@ -416,0 +354,0 @@

@@ -133,5 +133,2 @@ (function(global) {

}
if (typeof childrenOverride.hasRotatingPoint === 'undefined') {
childrenOverride.hasRotatingPoint = false;
}
childrenOverride.forActiveSelection = true;

@@ -138,0 +135,0 @@ for (var i = 0, len = this._objects.length; i < len; i++) {

@@ -110,5 +110,5 @@ (function(global) {

_updateObjectsACoords: function() {
var ignoreZoom = true, skipAbsolute = true;
var ignoreZoom = true;
for (var i = this._objects.length; i--; ){
this._objects[i].setCoords(ignoreZoom, skipAbsolute);
this._objects[i].setCoords(ignoreZoom);
}

@@ -136,3 +136,3 @@ },

objectTop = object.top,
ignoreZoom = true, skipAbsolute = true;
ignoreZoom = true;

@@ -144,3 +144,3 @@ object.set({

object.group = this;
object.setCoords(ignoreZoom, skipAbsolute);
object.setCoords(ignoreZoom);
},

@@ -492,4 +492,4 @@

prop = props[j];
aX.push(o.oCoords[prop].x);
aY.push(o.oCoords[prop].y);
aX.push(o.aCoords[prop].x);
aY.push(o.aCoords[prop].y);
}

@@ -496,0 +496,0 @@ }

@@ -823,20 +823,2 @@ (function(global) {

* @param {CanvasRenderingContext2D} ctx Context to render on
* @param {Object} filler fabric.Pattern or fabric.Gradient
* @return {Object} offset.offsetX offset for text rendering
* @return {Object} offset.offsetY offset for text rendering
*/
_applyPatternGradientTransform: function(ctx, filler) {
if (!filler || !filler.toLive) {
return { offsetX: 0, offsetY: 0 };
}
var offsetX = -this.width / 2 + filler.offsetX || 0,
offsetY = -this.height / 2 + filler.offsetY || 0;
ctx.transform(1, 0, 0, 1, offsetX, offsetY);
return { offsetX: offsetX, offsetY: offsetY };
},
/**
* @private
* @param {CanvasRenderingContext2D} ctx Context to render on
* @param {String} method Method name ("fillText" or "strokeText")

@@ -843,0 +825,0 @@ */

@@ -179,11 +179,2 @@ (function () {

/**
* Callback; invoked right before object is about to be scaled/rotated
* @deprecated since 2.3.0
* Use before:transform event
*/
onBeforeScaleRotate: function () {
/* NOOP */
},
/**
* When true, canvas is scaled by devicePixelRatio for better rendering on retina screens

@@ -1865,3 +1856,3 @@ * @type Boolean

* @example <caption>JSON with additional properties included</caption>
* var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY', 'lockUniScaling']);
* var json = canvas.toJSON(['lockMovementX', 'lockMovementY', 'lockRotation', 'lockScalingX', 'lockScalingY']);
* @example <caption>JSON without default values</caption>

@@ -1868,0 +1859,0 @@ * canvas.includeDefaultValues = false;

@@ -30,4 +30,5 @@ (function() {

var startColor = new fabric.Color(fromColor).getSource(),
endColor = new fabric.Color(toColor).getSource();
endColor = new fabric.Color(toColor).getSource(),
originalOnComplete = options.onComplete,
originalOnChange = options.onChange;
options = options || {};

@@ -45,2 +46,24 @@

return calculateColor(startValue, byValue, posValue);
},
// has to take in account for color restoring;
onComplete: function(current, valuePerc, timePerc) {
if (originalOnComplete) {
return originalOnComplete(
calculateColor(endColor, endColor, 0),
valuePerc,
timePerc
);
}
},
onChange: function(current, valuePerc, timePerc) {
if (originalOnChange) {
if (Array.isArray(current)) {
return originalOnChange(
calculateColor(current, current, 0),
valuePerc,
timePerc
);
}
originalOnChange(current, valuePerc, timePerc);
}
}

@@ -47,0 +70,0 @@ }));

(function () {
// since ie10 or ie9 can use addEventListener but they do not support options, i need to check
var couldUseAttachEvent = !!fabric.document.createElement('div').attachEvent;
// since ie10 can use addEventListener but they do not support options, i need to check
var couldUseAttachEvent = !!fabric.document.createElement('div').attachEvent,
touchEvents = ['touchstart', 'touchmove', 'touchend'];
/**

@@ -45,2 +46,6 @@ * Adds an event listener to an element

};
fabric.util.isTouchEvent = function(event) {
return touchEvents.indexOf(event.type) > -1 || event.pointerType === 'touch';
};
})();

@@ -777,3 +777,4 @@ (function(global) {

}
if (options.scaleX || options.scaleY || options.skewX || options.skewY || options.flipX || options.flipY) {
if (options.scaleX !== 1 || options.scaleY !== 1 ||
options.skewX || options.skewY || options.flipX || options.flipY) {
matrix = multiply(matrix, fabric.util.calcDimensionsMatrix(options));

@@ -780,0 +781,0 @@ }

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc