Skip to content

Commit

Permalink
Misc changes (#3614)
Browse files Browse the repository at this point in the history
* misc changes
  • Loading branch information
asturur authored Jan 30, 2017
1 parent 6a30d81 commit c378fa5
Show file tree
Hide file tree
Showing 16 changed files with 629 additions and 495 deletions.
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

0 comments on commit c378fa5

Please sign in to comment.