Skip to content
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

Misc changes #3614

Merged
merged 9 commits into from
Jan 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions HEADER.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ fabric.SHARED_ATTRIBUTES = [
fabric.DPI = 96;
fabric.reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:e[-+]?\\d+)?)';
fabric.fontPaths = { };
fabric.iMatrix = [1, 0, 0, 1, 0, 0];

/**
* Cache Object for widths of chars in text rendering.
Expand Down
170 changes: 117 additions & 53 deletions src/mixins/object_geometry.mixin.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
(function() {

function getCoords(oCoords) {
function getCoords(coords) {
return [
new fabric.Point(oCoords.tl.x, oCoords.tl.y),
new fabric.Point(oCoords.tr.x, oCoords.tr.y),
new fabric.Point(oCoords.br.x, oCoords.br.y),
new fabric.Point(oCoords.bl.x, oCoords.bl.y)
new fabric.Point(coords.tl.x, coords.tl.y),
new fabric.Point(coords.tr.x, coords.tr.y),
new fabric.Point(coords.br.x, coords.br.y),
new fabric.Point(coords.bl.x, coords.bl.y)
];
}

Expand All @@ -15,22 +15,56 @@
fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {

/**
* Object containing coordinates of object's controls
* @type Object
* @default
* Describe object's corner position in canvas element coordinates.
* properties are tl,mt,tr,ml,mr,bl,mb,br,mtr for the main controls.
* each property is an object with x, y and corner.
* The `corner` property contains in a similar manner the 4 points of the
* interactive area of the corner.
* The coordinates depends from this properties: width, height, scaleX, scaleY
* skewX, skewY, angle, strokeWidth, viewportTransform, top, left, padding.
* The coordinates get updated with @method setCoords.
* You can calculate them without updating with @method calcCoords;
* @memberOf fabric.Object.prototype
*/
oCoords: null,

/**
* Describe object's corner position in canvas object absolute coordinates
* properties are tl,tr,bl,br and describe the four main corner.
* each property is an object with x, y, instance of Fabric.Point.
* The coordinates depends from this properties: width, height, scaleX, scaleY
* skewX, skewY, angle, strokeWidth, top, left.
* Those coordinates are usefull to understand where an object is. They get updated
* with oCoords but they do not need to be updated when zoom or panning change.
* The coordinates get updated with @method setCoords.
* You can calculate them without updating with @method calcCoords(true);
* @memberOf fabric.Object.prototype
*/
aCoords: null,

/**
* return correct set of coordinates for intersection
*/
getCoords: function(absolute, calculate) {
if (!this.oCoords) {
this.setCoords();
}
var coords = absolute ? this.aCoords : this.oCoords;
return getCoords(calculate ? this.calcCoords(absolute) : coords);
},

/**
* Checks if object intersects with an area formed by 2 points
* @param {Object} pointTL top-left point of area
* @param {Object} pointBR bottom-right point of area
* @param {Boolean} [absolute] use coordinates without viewportTransform
* @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
* @return {Boolean} true if object intersects with an area formed by 2 points
*/
intersectsWithRect: function(pointTL, pointBR) {
var oCoords = getCoords(this.oCoords),
intersectsWithRect: function(pointTL, pointBR, absolute, calculate) {
var coords = this.getCoords(absolute, calculate),
intersection = fabric.Intersection.intersectPolygonRectangle(
oCoords,
coords,
pointTL,
pointBR
);
Expand All @@ -40,29 +74,35 @@
/**
* Checks if object intersects with another object
* @param {Object} other Object to test
* @param {Boolean} [absolute] use coordinates without viewportTransform
* @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
* @return {Boolean} true if object intersects with another object
*/
intersectsWithObject: function(other) {
intersectsWithObject: function(other, absolute, calculate) {
var intersection = fabric.Intersection.intersectPolygonPolygon(
getCoords(this.oCoords),
getCoords(other.oCoords)
this.getCoords(absolute, calculate),
other.getCoords(absolute, calculate)
);

return intersection.status === 'Intersection'
|| other.isContainedWithinObject(this)
|| this.isContainedWithinObject(other);
|| other.isContainedWithinObject(this, absolute, calculate)
|| this.isContainedWithinObject(other, absolute, calculate);
},

/**
* Checks if object is fully contained within area of another object
* @param {Object} other Object to test
* @param {Boolean} [absolute] use coordinates without viewportTransform
* @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
* @return {Boolean} true if object is fully contained within area of another object
*/
isContainedWithinObject: function(other) {
var points = getCoords(this.oCoords),
i = 0;
isContainedWithinObject: function(other, absolute, calculate) {
var points = this.getCoords(absolute, calculate),
i = 0, lines = other._getImageLines(
calculate ? other.calcCoords(absolute) : absolute ? other.aCoords : other.oCoords
);
for (; i < 4; i++) {
if (!other.containsPoint(points[i])) {
if (!other.containsPoint(points[i], lines)) {
return false;
}
}
Expand All @@ -73,10 +113,12 @@
* Checks if object is fully contained within area formed by 2 points
* @param {Object} pointTL top-left point of area
* @param {Object} pointBR bottom-right point of area
* @param {Boolean} [absolute] use coordinates without viewportTransform
* @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
* @return {Boolean} true if object is fully contained within area formed by 2 points
*/
isContainedWithinRect: function(pointTL, pointBR) {
var boundingRect = this.getBoundingRect();
isContainedWithinRect: function(pointTL, pointBR, absolute, calculate) {
var boundingRect = this.getBoundingRect(absolute, calculate);

return (
boundingRect.left >= pointTL.x &&
Expand All @@ -89,19 +131,42 @@
/**
* Checks if point is inside the object
* @param {fabric.Point} point Point to check against
* @param {Object} [lines] object returned from @method _getImageLines
* @param {Boolean} [absolute] use coordinates without viewportTransform
* @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
* @return {Boolean} true if point is inside the object
*/
containsPoint: function(point) {
if (!this.oCoords) {
this.setCoords();
}
var lines = this._getImageLines(this.oCoords),
containsPoint: function(point, lines, absolute, calculate) {
var lines = lines || this._getImageLines(
calculate ? this.calcCoords(absolute) : absolute ? this.aCoords : this.oCoords
),
xPoints = this._findCrossPoints(point, lines);

// if xPoints is odd then point is inside the object
return (xPoints !== 0 && xPoints % 2 === 1);
},

/**
* Checks if object is contained within the canvas with current viewportTransform
* the check is done stopping at first point that appear on screen
* @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
* @return {Boolean} true if object is fully contained within canvas
*/
isOnScreen: function(calculate) {
if (!this.canvas) {
return false;
}
var pointTL = this.canvas.vptCoords.tl, pointBR = this.canvas.vptCoords.br;
var points = this.getCoords(true, calculate), point;
for (var i = 0; i < 4; i++) {
point = points[i];
if (point.x <= pointBR.x && point.x >= pointTL.x && point.y <= pointBR.y && point.y >= pointTL.y) {
return true;
}
}
return false;
},

/**
* Method that returns an object with the object edges in it, given the coordinates of the corners
* @private
Expand Down Expand Up @@ -133,16 +198,16 @@
* and the horizontal line determined by a point on canvas
* @private
* @param {fabric.Point} point Point to check
* @param {Object} oCoords Coordinates of the object being evaluated
* @param {Object} lines Coordinates of the object being evaluated
*/
// remove yi, not used but left code here just in case.
_findCrossPoints: function(point, oCoords) {
_findCrossPoints: function(point, lines) {
var b1, b2, a1, a2, xi, // yi,
xcount = 0,
iLine;

for (var lineKey in oCoords) {
iLine = oCoords[lineKey];
for (var lineKey in lines) {
iLine = lines[lineKey];
// optimisation 1: line below point. no cross
if ((iLine.o.y < point.y) && (iLine.d.y < point.y)) {
continue;
Expand Down Expand Up @@ -199,17 +264,13 @@
/**
* Returns coordinates of object's bounding rectangle (left, top, width, height)
* the box is intented as aligned to axis of canvas.
* @param {Boolean} ignoreVpt bounding box will not be affected by viewportTransform
* @param {Boolean} [absolute] use coordinates without viewportTransform
* @param {Boolean} [calculate] use coordinates of current position instead of .oCoords
* @return {Object} Object with left, top, width, height properties
*/
getBoundingRect: function(ignoreVpt) {
var coords = this.calcCoords(ignoreVpt);
return fabric.util.makeBoundingBoxFromPoints([
coords.tl,
coords.tr,
coords.br,
coords.bl
]);
getBoundingRect: function(absolute, calculate) {
var coords = this.getCoords(absolute, calculate);
return fabric.util.makeBoundingBoxFromPoints(coords);
},

/**
Expand Down Expand Up @@ -296,10 +357,10 @@
* @return {Object} Object with tl, tr, br, bl ....
* @chainable
*/
calcCoords: function(ignoreVpt) {
calcCoords: function(absolute) {
var theta = degreesToRadians(this.angle),
vpt = this.getViewportTransform(),
dim = ignoreVpt ? this._getTransformedDimensions() : this._calculateCurrentDimensions(),
dim = absolute ? this._getTransformedDimensions() : this._calculateCurrentDimensions(),
currentWidth = dim.x, currentHeight = dim.y,
sinTh = Math.sin(theta),
cosTh = Math.cos(theta),
Expand All @@ -309,12 +370,12 @@
offsetY = Math.sin(_angle + theta) * _hypotenuse,
center = this.getCenterPoint(),
// offset added for rotate and scale actions
coords = ignoreVpt ? center : fabric.util.transformPoint(center, vpt),
coords = absolute ? center : fabric.util.transformPoint(center, vpt),
tl = new fabric.Point(coords.x - offsetX, coords.y - offsetY),
tr = new fabric.Point(tl.x + (currentWidth * cosTh), tl.y + (currentWidth * sinTh)),
bl = new fabric.Point(tl.x - (currentHeight * sinTh), tl.y + (currentHeight * cosTh)),
br = new fabric.Point(coords.x + offsetX, coords.y + offsetY);
if (!ignoreVpt) {
if (!absolute) {
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),
Expand All @@ -341,7 +402,7 @@
// corners
tl: tl, tr: tr, br: br, bl: bl,
};
if (!ignoreVpt) {
if (!absolute) {
// middle
coords.ml = ml;
coords.mt = mt;
Expand All @@ -356,22 +417,24 @@
/**
* Sets corner position coordinates based on current angle, width and height
* See https://github.com/kangax/fabric.js/wiki/When-to-call-setCoords
* @param {Boolean} [ignoreZoom] set oCoords with or without the viewport transform.
* @param {Boolean} [skipAbsolute] skip calculation of aCoords, usefull in setViewportTransform
* @return {fabric.Object} thisArg
* @chainable
*/
setCoords: function(ignoreZoom, skipAbsolute) {
this.oCoords = this.calcCoords(ignoreZoom);
if (!skipAbsolute && !ignoreZoom) {
this.absoluteCoords = this.calcCoords(true);
if (!skipAbsolute) {
this.aCoords = this.calcCoords(true);
}

// set coordinates of the draggable boxes in the corners used to scale/rotate the image
ignoreZoom || this._setCornerCoords && this._setCornerCoords();
ignoreZoom || (this._setCornerCoords && this._setCornerCoords());

return this;
},

/*
/**
* calculate rotation matrix of an object
* @return {Array} rotation matrix for the object
*/
Expand All @@ -380,20 +443,21 @@
var theta = degreesToRadians(this.angle), cos = Math.cos(theta), sin = Math.sin(theta);
return [cos, sin, -sin, cos, 0, 0];
}
return [1, 0, 0, 1, 0, 0];
return fabric.iMatrix.concat();
},

/*
/**
* calculate trasform Matrix that represent current transformation from
* object properties.
* @param {Boolean} [skipGroup] return transformMatrix for object and not go upward with parents
* @return {Array} matrix Transform Matrix for the object
*/
calcTransformMatrix: function() {
calcTransformMatrix: function(skipGroup) {
var center = this.getCenterPoint(),
translateMatrix = [1, 0, 0, 1, center.x, center.y],
rotateMatrix = this._calcRotateMatrix(),
dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true),
matrix = this.group ? this.group.calcTransformMatrix() : [1, 0, 0, 1, 0, 0];
matrix = this.group && !skipGroup ? this.group.calcTransformMatrix() : fabric.iMatrix.concat();
matrix = multiplyMatrices(matrix, translateMatrix);
matrix = multiplyMatrices(matrix, rotateMatrix);
matrix = multiplyMatrices(matrix, dimensionMatrix);
Expand Down
8 changes: 0 additions & 8 deletions src/shapes/circle.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,6 @@
this.radius = value;
return this.set('width', value * 2).set('height', value * 2);
},

/**
* Returns complexity of an instance
* @return {Number} complexity of this instance
*/
complexity: function() {
return 1;
}
});

/* _FROM_SVG_START_ */
Expand Down
8 changes: 0 additions & 8 deletions src/shapes/ellipse.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,6 @@
this._renderFill(ctx);
this._renderStroke(ctx);
},

/**
* Returns complexity of an instance
* @return {Number} complexity
*/
complexity: function() {
return 1;
}
});

/* _FROM_SVG_START_ */
Expand Down
12 changes: 5 additions & 7 deletions src/shapes/group.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,13 @@

var objectLeft = object.getLeft(),
objectTop = object.getTop(),
ignoreZoom = true;
ignoreZoom = true, skipAbsolute = true;

object.set({
originalLeft: objectLeft,
originalTop: objectTop,
left: objectLeft - center.x,
top: objectTop - center.y
});
object.setCoords(ignoreZoom);
object.setCoords(ignoreZoom, skipAbsolute);
},

/**
Expand Down Expand Up @@ -423,14 +421,14 @@
},

/**
* Sets coordinates of all group objects
* Sets coordinates of all objects inside group
* @return {fabric.Group} thisArg
* @chainable
*/
setObjectsCoords: function() {
var ignoreZoom = true;
var ignoreZoom = true, skipAbsolute = true;
this.forEachObject(function(object) {
object.setCoords(ignoreZoom);
object.setCoords(ignoreZoom, skipAbsolute);
});
return this;
},
Expand Down
Loading