mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-05-22 12:21:51 +00:00
parent
6a30d81fdb
commit
c378fa5b04
16 changed files with 629 additions and 495 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
);
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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 &&
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -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),
|
||||
|
|
@ -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),
|
||||
|
|
@ -341,7 +402,7 @@
|
|||
// corners
|
||||
tl: tl, tr: tr, br: br, bl: bl,
|
||||
};
|
||||
if (!ignoreVpt) {
|
||||
if (!absolute) {
|
||||
// middle
|
||||
coords.ml = ml;
|
||||
coords.mt = mt;
|
||||
|
|
@ -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
|
||||
*/
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -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;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -597,14 +597,6 @@
|
|||
? this.getElement().height || 0
|
||||
: 0);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns complexity of an instance
|
||||
* @return {Number} complexity of this instance
|
||||
*/
|
||||
complexity: function() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -280,14 +280,6 @@
|
|||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
|
||||
/**
|
||||
* Returns complexity of an instance
|
||||
* @return {Number} complexity
|
||||
*/
|
||||
complexity: function() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
/* _FROM_SVG_START_ */
|
||||
|
|
|
|||
|
|
@ -1111,7 +1111,7 @@
|
|||
if (this.canvas && this.canvas.viewportTransform) {
|
||||
return this.canvas.viewportTransform;
|
||||
}
|
||||
return [1, 0, 0, 1, 0, 0];
|
||||
return fabric.iMatrix.concat();
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -1497,10 +1497,10 @@
|
|||
|
||||
/**
|
||||
* Returns complexity of an instance
|
||||
* @return {Number} complexity of this instance
|
||||
* @return {Number} complexity of this instance (is 1 unless subclassed)
|
||||
*/
|
||||
complexity: function() {
|
||||
return 0;
|
||||
return 1;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,26 +3,20 @@
|
|||
'use strict';
|
||||
|
||||
var fabric = global.fabric || (global.fabric = { }),
|
||||
extend = fabric.util.object.extend,
|
||||
min = fabric.util.array.min,
|
||||
max = fabric.util.array.max,
|
||||
toFixed = fabric.util.toFixed;
|
||||
extend = fabric.util.object.extend;
|
||||
|
||||
if (fabric.Polygon) {
|
||||
fabric.warn('fabric.Polygon is already defined');
|
||||
return;
|
||||
}
|
||||
|
||||
var cacheProperties = fabric.Object.prototype.cacheProperties.concat();
|
||||
cacheProperties.push('points');
|
||||
|
||||
/**
|
||||
* Polygon class
|
||||
* @class fabric.Polygon
|
||||
* @extends fabric.Object
|
||||
* @extends fabric.Polyline
|
||||
* @see {@link fabric.Polygon#initialize} for constructor definition
|
||||
*/
|
||||
fabric.Polygon = fabric.util.createClass(fabric.Object, /** @lends fabric.Polygon.prototype */ {
|
||||
fabric.Polygon = fabric.util.createClass(fabric.Polyline, /** @lends fabric.Polygon.prototype */ {
|
||||
|
||||
/**
|
||||
* Type of an object
|
||||
|
|
@ -31,109 +25,6 @@
|
|||
*/
|
||||
type: 'polygon',
|
||||
|
||||
/**
|
||||
* Points array
|
||||
* @type Array
|
||||
* @default
|
||||
*/
|
||||
points: null,
|
||||
|
||||
/**
|
||||
* Minimum X from points values, necessary to offset points
|
||||
* @type Number
|
||||
* @default
|
||||
*/
|
||||
minX: 0,
|
||||
|
||||
/**
|
||||
* Minimum Y from points values, necessary to offset points
|
||||
* @type Number
|
||||
* @default
|
||||
*/
|
||||
minY: 0,
|
||||
|
||||
cacheProperties: cacheProperties,
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param {Array} points Array of points
|
||||
* @param {Object} [options] Options object
|
||||
* @return {fabric.Polygon} thisArg
|
||||
*/
|
||||
initialize: function(points, options) {
|
||||
options = options || {};
|
||||
this.points = points || [];
|
||||
this.callSuper('initialize', options);
|
||||
this._calcDimensions();
|
||||
if (!('top' in options)) {
|
||||
this.top = this.minY;
|
||||
}
|
||||
if (!('left' in options)) {
|
||||
this.left = this.minX;
|
||||
}
|
||||
this.pathOffset = {
|
||||
x: this.minX + this.width / 2,
|
||||
y: this.minY + this.height / 2
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_calcDimensions: function() {
|
||||
|
||||
var points = this.points,
|
||||
minX = min(points, 'x'),
|
||||
minY = min(points, 'y'),
|
||||
maxX = max(points, 'x'),
|
||||
maxY = max(points, 'y');
|
||||
|
||||
this.width = (maxX - minX) || 0;
|
||||
this.height = (maxY - minY) || 0;
|
||||
this.minX = minX || 0;
|
||||
this.minY = minY || 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns object representation of an instance
|
||||
* @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
|
||||
* @return {Object} Object representation of an instance
|
||||
*/
|
||||
toObject: function(propertiesToInclude) {
|
||||
return extend(this.callSuper('toObject', propertiesToInclude), {
|
||||
points: this.points.concat()
|
||||
});
|
||||
},
|
||||
|
||||
/* _TO_SVG_START_ */
|
||||
/**
|
||||
* Returns svg representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
var points = [], addTransform,
|
||||
markup = this._createBaseSVGMarkup();
|
||||
|
||||
for (var i = 0, len = this.points.length; i < len; i++) {
|
||||
points.push(toFixed(this.points[i].x, 2), ',', toFixed(this.points[i].y, 2), ' ');
|
||||
}
|
||||
if (!(this.group && this.group.type === 'path-group')) {
|
||||
addTransform = ' translate(' + (-this.pathOffset.x) + ', ' + (-this.pathOffset.y) + ') ';
|
||||
}
|
||||
markup.push(
|
||||
'<', this.type, ' ', this.getSvgId(),
|
||||
'points="', points.join(''),
|
||||
'" style="', this.getSvgStyles(),
|
||||
'" transform="', this.getSvgTransform(), addTransform,
|
||||
' ', this.getSvgTransformMatrix(),
|
||||
'"/>\n'
|
||||
);
|
||||
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {CanvasRenderingContext2D} ctx Context to render on
|
||||
|
|
@ -143,35 +34,9 @@
|
|||
if (!this.commonRender(ctx, noTransform)) {
|
||||
return;
|
||||
}
|
||||
ctx.closePath();
|
||||
this._renderFill(ctx);
|
||||
if (this.stroke || this.strokeDashArray) {
|
||||
ctx.closePath();
|
||||
this._renderStroke(ctx);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {CanvasRenderingContext2D} ctx Context to render on
|
||||
* @param {Boolean} noTransform
|
||||
*/
|
||||
commonRender: function(ctx, noTransform) {
|
||||
var point, len = this.points.length,
|
||||
x = noTransform ? 0 : this.pathOffset.x,
|
||||
y = noTransform ? 0 : this.pathOffset.y;
|
||||
|
||||
if (!len || isNaN(this.points[len - 1].y)) {
|
||||
// do not draw if no points or odd points
|
||||
// NaN comes from parseFloat of a empty string in parser
|
||||
return false;
|
||||
}
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.points[0].x - x, this.points[0].y - y);
|
||||
for (var i = 0; i < len; i++) {
|
||||
point = this.points[i];
|
||||
ctx.lineTo(point.x - x, point.y - y);
|
||||
}
|
||||
return true;
|
||||
this._renderStroke(ctx);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -179,17 +44,9 @@
|
|||
* @param {CanvasRenderingContext2D} ctx Context to render on
|
||||
*/
|
||||
_renderDashedStroke: function(ctx) {
|
||||
fabric.Polyline.prototype._renderDashedStroke.call(this, ctx);
|
||||
this.callSuper('_renderDashedStroke', ctx);
|
||||
ctx.closePath();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns complexity of an instance
|
||||
* @return {Number} complexity of this instance
|
||||
*/
|
||||
complexity: function() {
|
||||
return this.points.length;
|
||||
}
|
||||
});
|
||||
|
||||
/* _FROM_SVG_START_ */
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
var fabric = global.fabric || (global.fabric = { });
|
||||
var fabric = global.fabric || (global.fabric = { }),
|
||||
extend = fabric.util.object.extend,
|
||||
min = fabric.util.array.min,
|
||||
max = fabric.util.array.max,
|
||||
toFixed = fabric.util.toFixed;
|
||||
|
||||
if (fabric.Polyline) {
|
||||
fabric.warn('fabric.Polyline is already defined');
|
||||
|
|
@ -70,14 +74,37 @@
|
|||
* });
|
||||
*/
|
||||
initialize: function(points, options) {
|
||||
return fabric.Polygon.prototype.initialize.call(this, points, options);
|
||||
options = options || {};
|
||||
this.points = points || [];
|
||||
this.callSuper('initialize', options);
|
||||
this._calcDimensions();
|
||||
if (!('top' in options)) {
|
||||
this.top = this.minY;
|
||||
}
|
||||
if (!('left' in options)) {
|
||||
this.left = this.minX;
|
||||
}
|
||||
this.pathOffset = {
|
||||
x: this.minX + this.width / 2,
|
||||
y: this.minY + this.height / 2
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_calcDimensions: function() {
|
||||
return fabric.Polygon.prototype._calcDimensions.call(this);
|
||||
|
||||
var points = this.points,
|
||||
minX = min(points, 'x'),
|
||||
minY = min(points, 'y'),
|
||||
maxX = max(points, 'x'),
|
||||
maxY = max(points, 'y');
|
||||
|
||||
this.width = (maxX - minX) || 0;
|
||||
this.height = (maxY - minY) || 0;
|
||||
this.minX = minX || 0;
|
||||
this.minY = minY || 0;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -86,27 +113,72 @@
|
|||
* @return {Object} Object representation of an instance
|
||||
*/
|
||||
toObject: function(propertiesToInclude) {
|
||||
return fabric.Polygon.prototype.toObject.call(this, propertiesToInclude);
|
||||
return extend(this.callSuper('toObject', propertiesToInclude), {
|
||||
points: this.points.concat()
|
||||
});
|
||||
},
|
||||
|
||||
/* _TO_SVG_START_ */
|
||||
/**
|
||||
* Returns SVG representation of an instance
|
||||
* Returns svg representation of an instance
|
||||
* @param {Function} [reviver] Method for further parsing of svg representation.
|
||||
* @return {String} svg representation of an instance
|
||||
*/
|
||||
toSVG: function(reviver) {
|
||||
return fabric.Polygon.prototype.toSVG.call(this, reviver);
|
||||
var points = [], addTransform,
|
||||
markup = this._createBaseSVGMarkup();
|
||||
|
||||
for (var i = 0, len = this.points.length; i < len; i++) {
|
||||
points.push(toFixed(this.points[i].x, 2), ',', toFixed(this.points[i].y, 2), ' ');
|
||||
}
|
||||
if (!(this.group && this.group.type === 'path-group')) {
|
||||
addTransform = ' translate(' + (-this.pathOffset.x) + ', ' + (-this.pathOffset.y) + ') ';
|
||||
}
|
||||
markup.push(
|
||||
'<', this.type, ' ', this.getSvgId(),
|
||||
'points="', points.join(''),
|
||||
'" style="', this.getSvgStyles(),
|
||||
'" transform="', this.getSvgTransform(), addTransform,
|
||||
' ', this.getSvgTransformMatrix(),
|
||||
'"/>\n'
|
||||
);
|
||||
|
||||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {CanvasRenderingContext2D} ctx Context to render on
|
||||
* @param {Boolean} noTransform
|
||||
*/
|
||||
commonRender: function(ctx, noTransform) {
|
||||
var point, len = this.points.length,
|
||||
x = noTransform ? 0 : this.pathOffset.x,
|
||||
y = noTransform ? 0 : this.pathOffset.y;
|
||||
|
||||
if (!len || isNaN(this.points[len - 1].y)) {
|
||||
// do not draw if no points or odd points
|
||||
// NaN comes from parseFloat of a empty string in parser
|
||||
return false;
|
||||
}
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.points[0].x - x, this.points[0].y - y);
|
||||
for (var i = 0; i < len; i++) {
|
||||
point = this.points[i];
|
||||
ctx.lineTo(point.x - x, point.y - y);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {CanvasRenderingContext2D} ctx Context to render on
|
||||
* @param {Boolean} noTransform
|
||||
*/
|
||||
_render: function(ctx, noTransform) {
|
||||
if (!fabric.Polygon.prototype.commonRender.call(this, ctx, noTransform)) {
|
||||
if (!this.commonRender(ctx, noTransform)) {
|
||||
return;
|
||||
}
|
||||
this._renderFill(ctx);
|
||||
|
|
|
|||
|
|
@ -175,14 +175,6 @@
|
|||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
|
||||
/**
|
||||
* Returns complexity of an instance
|
||||
* @return {Number} complexity
|
||||
*/
|
||||
complexity: function() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
/* _FROM_SVG_START_ */
|
||||
|
|
|
|||
|
|
@ -97,14 +97,6 @@
|
|||
return reviver ? reviver(markup.join('')) : markup.join('');
|
||||
},
|
||||
/* _TO_SVG_END_ */
|
||||
|
||||
/**
|
||||
* Returns complexity of an instance
|
||||
* @return {Number} complexity of this instance
|
||||
*/
|
||||
complexity: function() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
getElementOffset = fabric.util.getElementOffset,
|
||||
removeFromArray = fabric.util.removeFromArray,
|
||||
toFixed = fabric.util.toFixed,
|
||||
transformPoint = fabric.util.transformPoint,
|
||||
invertTransform = fabric.util.invertTransform,
|
||||
|
||||
CANVAS_INIT_ERROR = new Error('Could not initialize `canvas` element');
|
||||
|
||||
|
|
@ -138,7 +140,7 @@
|
|||
* @type Array
|
||||
* @default
|
||||
*/
|
||||
viewportTransform: [1, 0, 0, 1, 0, 0],
|
||||
viewportTransform: fabric.iMatrix.concat(),
|
||||
|
||||
/**
|
||||
* if set to false background image is not affected by viewport transform
|
||||
|
|
@ -168,6 +170,17 @@
|
|||
*/
|
||||
enableRetinaScaling: true,
|
||||
|
||||
/**
|
||||
* Describe canvas element extension over design
|
||||
* properties are tl,tr,bl,br.
|
||||
* if canvas is not zoomed/panned those points are the four corner of canvas
|
||||
* if canvas is viewportTransformed you those points indicate the extension
|
||||
* of canvas element in plain untrasformed coordinates
|
||||
* The coordinates get updated with @method calcViewportBoundaries.
|
||||
* @memberOf fabric.StaticCanvas.prototype
|
||||
*/
|
||||
vptCoords: { },
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {HTMLElement | String} el <canvas> element to initialize instance on
|
||||
|
|
@ -648,6 +661,7 @@
|
|||
if (activeGroup) {
|
||||
activeGroup.setCoords(ingoreVpt, skipAbsolute);
|
||||
}
|
||||
this.calcViewportBoundaries();
|
||||
this.renderAll();
|
||||
return this;
|
||||
},
|
||||
|
|
@ -662,10 +676,10 @@
|
|||
zoomToPoint: function (point, value) {
|
||||
// TODO: just change the scale, preserve other transformations
|
||||
var before = point, vpt = this.viewportTransform.slice(0);
|
||||
point = fabric.util.transformPoint(point, fabric.util.invertTransform(this.viewportTransform));
|
||||
point = transformPoint(point, invertTransform(this.viewportTransform));
|
||||
vpt[0] = value;
|
||||
vpt[3] = value;
|
||||
var after = fabric.util.transformPoint(point, vpt);
|
||||
var after = transformPoint(point, vpt);
|
||||
vpt[4] += before.x - after.x;
|
||||
vpt[5] += before.y - after.y;
|
||||
return this.setViewportTransform(vpt);
|
||||
|
|
@ -782,7 +796,7 @@
|
|||
},
|
||||
|
||||
/**
|
||||
* Renders both the canvas.
|
||||
* Renders the canvas
|
||||
* @return {fabric.Canvas} instance
|
||||
* @chainable
|
||||
*/
|
||||
|
|
@ -792,6 +806,24 @@
|
|||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculate the position of the 4 corner of canvas with current viewportTransform.
|
||||
* helps to determinate when an object is in the current rendering viewport using
|
||||
* object absolute coordinates ( aCoords )
|
||||
* @return {Object} points.tl
|
||||
* @chainable
|
||||
*/
|
||||
calcViewportBoundaries: function() {
|
||||
var points = { }, width = this.getWidth(), height = this.getHeight(),
|
||||
iVpt = invertTransform(this.viewportTransform);
|
||||
points.tl = transformPoint({ x: 0, y: 0 }, iVpt);
|
||||
points.br = transformPoint({ x: width, y: height }, iVpt);
|
||||
points.tr = new fabric.Point(points.br.x, points.tl.y);
|
||||
points.bl = new fabric.Point(points.tl.x, points.br.y);
|
||||
this.vptCoords = points;
|
||||
return points;
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders background, objects, overlay and controls.
|
||||
* @param {CanvasRenderingContext2D} ctx
|
||||
|
|
@ -800,6 +832,7 @@
|
|||
* @chainable
|
||||
*/
|
||||
renderCanvas: function(ctx, objects) {
|
||||
this.calcViewportBoundaries();
|
||||
this.clearContext(ctx);
|
||||
this.fire('before:render');
|
||||
if (this.clipTo) {
|
||||
|
|
@ -973,8 +1006,8 @@
|
|||
*/
|
||||
getVpCenter: function() {
|
||||
var center = this.getCenter(),
|
||||
iVpt = fabric.util.invertTransform(this.viewportTransform);
|
||||
return fabric.util.transformPoint({ x: center.left, y: center.top }, iVpt);
|
||||
iVpt = invertTransform(this.viewportTransform);
|
||||
return transformPoint({ x: center.left, y: center.top }, iVpt);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1399,7 +1399,7 @@
|
|||
});
|
||||
|
||||
test('relativePan', function() {
|
||||
ok(typeof canvas.relativePan == 'function');
|
||||
ok(typeof canvas.relativePan === 'function');
|
||||
deepEqual(canvas.viewportTransform, [1, 0, 0, 1, 0, 0], 'initial viewport is identity matrix');
|
||||
var point = new fabric.Point(-50, -50);
|
||||
canvas.relativePan(point);
|
||||
|
|
@ -1410,11 +1410,38 @@
|
|||
});
|
||||
|
||||
test('getContext', function() {
|
||||
ok(typeof canvas.getContext == 'function');
|
||||
ok(typeof canvas.getContext === 'function');
|
||||
var context = canvas.getContext();
|
||||
equal(context, canvas.contextContainer, 'should return the context container');
|
||||
});
|
||||
|
||||
test('calcViewportBoundaries', function() {
|
||||
ok(typeof canvas.calcViewportBoundaries === 'function');
|
||||
canvas.calcViewportBoundaries();
|
||||
deepEqual(canvas.vptCoords.tl, new fabric.Point(0, 0), 'tl is 0,0');
|
||||
deepEqual(canvas.vptCoords.tr, new fabric.Point(canvas.getWidth(), 0), 'tr is width, 0');
|
||||
deepEqual(canvas.vptCoords.bl, new fabric.Point(0, canvas.getHeight()), 'bl is 0, height');
|
||||
deepEqual(canvas.vptCoords.br, new fabric.Point(canvas.getWidth(), canvas.getHeight()), 'tl is width, height');
|
||||
});
|
||||
|
||||
test('calcViewportBoundaries with zoom', function() {
|
||||
ok(typeof canvas.calcViewportBoundaries === 'function');
|
||||
canvas.setViewportTransform([2, 0, 0, 2, 0, 0]);
|
||||
deepEqual(canvas.vptCoords.tl, new fabric.Point(0, 0), 'tl is 0,0');
|
||||
deepEqual(canvas.vptCoords.tr, new fabric.Point(canvas.getWidth() / 2, 0), 'tl is 0,0');
|
||||
deepEqual(canvas.vptCoords.bl, new fabric.Point(0, canvas.getHeight() / 2), 'tl is 0,0');
|
||||
deepEqual(canvas.vptCoords.br, new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2), 'tl is 0,0');
|
||||
});
|
||||
|
||||
test('calcViewportBoundaries with zoom and translation', function() {
|
||||
ok(typeof canvas.calcViewportBoundaries === 'function');
|
||||
canvas.setViewportTransform([2, 0, 0, 2, -60, 60]);
|
||||
deepEqual(canvas.vptCoords.tl, new fabric.Point(30, -30), 'tl is 0,0');
|
||||
deepEqual(canvas.vptCoords.tr, new fabric.Point(30 + canvas.getWidth() / 2, -30), 'tl is 0,0');
|
||||
deepEqual(canvas.vptCoords.bl, new fabric.Point(30, canvas.getHeight() / 2 - 30), 'tl is 0,0');
|
||||
deepEqual(canvas.vptCoords.br, new fabric.Point(30 + canvas.getWidth() / 2, canvas.getHeight() / 2 - 30), 'tl is 0,0');
|
||||
});
|
||||
|
||||
//how to test with an exception?
|
||||
/*asyncTest('options in setBackgroundImage from invalid URL', function() {
|
||||
canvas.backgroundImage = null;
|
||||
|
|
|
|||
|
|
@ -578,17 +578,11 @@
|
|||
start();
|
||||
}
|
||||
else {
|
||||
var image;
|
||||
|
||||
setTimeout(function() {
|
||||
cObj.cloneAsImage(function(image) {
|
||||
ok(image);
|
||||
ok(image instanceof fabric.Image);
|
||||
equal(image.width, 100, 'the image has same dimension of object');
|
||||
start();
|
||||
}, 500);
|
||||
|
||||
cObj.cloneAsImage(function(i) {
|
||||
image = i;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -601,18 +595,12 @@
|
|||
start();
|
||||
}
|
||||
else {
|
||||
var image;
|
||||
|
||||
setTimeout(function() {
|
||||
cObj.cloneAsImage(function(image) {
|
||||
ok(image);
|
||||
ok(image instanceof fabric.Image);
|
||||
equal(image.width, 200, 'the image has been scaled by retina');
|
||||
fabric.devicePixelRatio = 1;
|
||||
start();
|
||||
}, 500);
|
||||
|
||||
cObj.cloneAsImage(function(i) {
|
||||
image = i;
|
||||
}, { enableRetinaScaling: true });
|
||||
}
|
||||
});
|
||||
|
|
@ -679,54 +667,6 @@
|
|||
}
|
||||
});
|
||||
|
||||
test('intersectsWithRectangle', function() {
|
||||
var cObj = new fabric.Object({ left: 50, top: 50, width: 100, height: 100 });
|
||||
cObj.setCoords();
|
||||
ok(typeof cObj.intersectsWithRect == 'function');
|
||||
|
||||
var point1 = new fabric.Point(110, 100),
|
||||
point2 = new fabric.Point(210, 200),
|
||||
point3 = new fabric.Point(0, 0),
|
||||
point4 = new fabric.Point(10, 10);
|
||||
|
||||
ok(cObj.intersectsWithRect(point1, point2));
|
||||
ok(!cObj.intersectsWithRect(point3, point4));
|
||||
});
|
||||
|
||||
test('intersectsWithObject', function() {
|
||||
var cObj = new fabric.Object({ left: 50, top: 50, width: 100, height: 100 });
|
||||
cObj.setCoords();
|
||||
ok(typeof cObj.intersectsWithObject == 'function', 'has intersectsWithObject method');
|
||||
|
||||
var cObj2 = new fabric.Object({ left: -150, top: -150, width: 200, height: 200 });
|
||||
cObj2.setCoords();
|
||||
ok(cObj.intersectsWithObject(cObj2), 'cobj2 does intersect with cobj');
|
||||
ok(cObj2.intersectsWithObject(cObj), 'cobj2 does intersect with cobj');
|
||||
|
||||
var cObj3 = new fabric.Object({ left: 392.5, top: 339.5, width: 13, height: 33 });
|
||||
cObj3.setCoords();
|
||||
ok(!cObj.intersectsWithObject(cObj3), 'cobj3 does not intersect with cobj (external)');
|
||||
ok(!cObj3.intersectsWithObject(cObj), 'cobj3 does not intersect with cobj (external)');
|
||||
|
||||
var cObj4 = new fabric.Object({ left: 0, top: 0, width: 200, height: 200 });
|
||||
cObj4.setCoords();
|
||||
ok(cObj4.intersectsWithObject(cObj), 'overlapping objects are considered intersecting');
|
||||
ok(cObj.intersectsWithObject(cObj4), 'overlapping objects are considered intersecting');
|
||||
});
|
||||
|
||||
test('isContainedWithinRect', function() {
|
||||
var cObj = new fabric.Object({ left: 20, top: 20, width: 10, height: 10 });
|
||||
cObj.setCoords();
|
||||
ok(typeof cObj.isContainedWithinRect == 'function');
|
||||
|
||||
// fully contained
|
||||
ok(cObj.isContainedWithinRect(new fabric.Point(10,10), new fabric.Point(100,100)));
|
||||
// only intersects
|
||||
ok(!cObj.isContainedWithinRect(new fabric.Point(10,10), new fabric.Point(25, 25)));
|
||||
// doesn't intersect
|
||||
ok(!cObj.isContainedWithinRect(new fabric.Point(100,100), new fabric.Point(110, 110)));
|
||||
});
|
||||
|
||||
test('isType', function() {
|
||||
var cObj = new fabric.Object();
|
||||
ok(typeof cObj.isType == 'function');
|
||||
|
|
@ -1274,163 +1214,6 @@
|
|||
equal(object.get('fill'), '123456');
|
||||
});
|
||||
|
||||
test('intersectsWithRect', function() {
|
||||
var object = new fabric.Object({ left: 0, top: 0, width: 40, height: 50, angle: 160 }),
|
||||
point1 = new fabric.Point(-10, -10),
|
||||
point2 = new fabric.Point(20, 30),
|
||||
point3 = new fabric.Point(10, 15),
|
||||
point4 = new fabric.Point(30, 35),
|
||||
point5 = new fabric.Point(50, 60),
|
||||
point6 = new fabric.Point(70, 80);
|
||||
|
||||
object.setCoords();
|
||||
|
||||
// object and area intersects
|
||||
equal(object.intersectsWithRect(point1, point2), true);
|
||||
// area is contained in object (no intersection)
|
||||
equal(object.intersectsWithRect(point3, point4), false);
|
||||
// area is outside of object (no intersection)
|
||||
equal(object.intersectsWithRect(point5, point6), false);
|
||||
});
|
||||
|
||||
test('intersectsWithObject', function() {
|
||||
var object = new fabric.Object({ left: 20, top: 30, width: 40, height: 50, angle: 230, strokeWidth: 0 }),
|
||||
object1 = new fabric.Object({ left: 20, top: 30, width: 60, height: 30, angle: 10, strokeWidth: 0 }),
|
||||
object2 = new fabric.Object({ left: 25, top: 35, width: 20, height: 20, angle: 50, strokeWidth: 0 }),
|
||||
object3 = new fabric.Object({ left: 50, top: 50, width: 20, height: 20, angle: 0, strokeWidth: 0 });
|
||||
|
||||
object.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
object1.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
object2.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
object3.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
|
||||
equal(object.intersectsWithObject(object1), true, 'object and object1 intersects');
|
||||
equal(object.intersectsWithObject(object2), true, 'object2 is contained in object');
|
||||
equal(object.intersectsWithObject(object3), false, 'object3 is outside of object (no intersection)');
|
||||
});
|
||||
|
||||
test('isContainedWithinObject', function() {
|
||||
var object = new fabric.Object({ left: 0, top: 0, width: 40, height: 40, angle: 0 }),
|
||||
object1 = new fabric.Object({ left: 1, top: 1, width: 38, height: 38, angle: 0 }),
|
||||
object2 = new fabric.Object({ left: 20, top: 20, width: 40, height: 40, angle: 0 }),
|
||||
object3 = new fabric.Object({ left: 50, top: 50, width: 40, height: 40, angle: 0 });
|
||||
|
||||
object.setCoords();
|
||||
object1.setCoords();
|
||||
object2.setCoords();
|
||||
object3.setCoords();
|
||||
|
||||
equal(object1.isContainedWithinObject(object), true, 'object1 is fully contained within object');
|
||||
equal(object2.isContainedWithinObject(object), false, 'object2 intersects object (not fully contained)');
|
||||
equal(object3.isContainedWithinObject(object), false, 'object3 is outside of object (not fully contained)');
|
||||
object1.angle = 45;
|
||||
object1.setCoords();
|
||||
equal(object1.isContainedWithinObject(object), false, 'object1 rotated is not contained within object');
|
||||
|
||||
var rect1 = new fabric.Rect({
|
||||
width: 50,
|
||||
height: 50,
|
||||
left: 50,
|
||||
top: 50
|
||||
});
|
||||
|
||||
var rect2 = new fabric.Rect({
|
||||
width: 100,
|
||||
height: 100,
|
||||
left: 100,
|
||||
top: 0,
|
||||
angle: 45,
|
||||
});
|
||||
rect1.setCoords();
|
||||
rect2.setCoords();
|
||||
equal(rect1.isContainedWithinObject(rect2), false, 'rect1 rotated is not contained within rect2');
|
||||
});
|
||||
|
||||
test('isContainedWithinRect', function() {
|
||||
var object = new fabric.Object({ left: 40, top: 40, width: 40, height: 50, angle: 160 }),
|
||||
point1 = new fabric.Point(0, 0),
|
||||
point2 = new fabric.Point(80, 80),
|
||||
point3 = new fabric.Point(0, 0),
|
||||
point4 = new fabric.Point(80, 60),
|
||||
point5 = new fabric.Point(80, 80),
|
||||
point6 = new fabric.Point(90, 90);
|
||||
|
||||
object.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
|
||||
// area is contained in object (no intersection)
|
||||
equal(object.isContainedWithinRect(point1, point2), true);
|
||||
// object and area intersects
|
||||
equal(object.isContainedWithinRect(point3, point4), false);
|
||||
// area is outside of object (no intersection)
|
||||
equal(object.isContainedWithinRect(point5, point6), false);
|
||||
});
|
||||
|
||||
test('isContainedWithinRect', function() {
|
||||
var object = new fabric.Object({ left: 40, top: 40, width: 40, height: 50, angle: 160 }),
|
||||
point1 = new fabric.Point(0, 0),
|
||||
point2 = new fabric.Point(80, 80),
|
||||
point3 = new fabric.Point(0, 0),
|
||||
point4 = new fabric.Point(80, 60),
|
||||
point5 = new fabric.Point(80, 80),
|
||||
point6 = new fabric.Point(90, 90);
|
||||
|
||||
object.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
|
||||
// area is contained in object (no intersection)
|
||||
equal(object.isContainedWithinRect(point1, point2), true);
|
||||
// object and area intersects
|
||||
equal(object.isContainedWithinRect(point3, point4), false);
|
||||
// area is outside of object (no intersection)
|
||||
equal(object.isContainedWithinRect(point5, point6), false);
|
||||
});
|
||||
|
||||
test('containsPoint', function() {
|
||||
var object = new fabric.Object({ left: 40, top: 40, width: 40, height: 50, angle: 160, strokeWidth: 0 }),
|
||||
point1 = new fabric.Point(30, 30),
|
||||
point2 = new fabric.Point(60, 30),
|
||||
point3 = new fabric.Point(45, 65),
|
||||
point4 = new fabric.Point(15, 40),
|
||||
point5 = new fabric.Point(30, 15);
|
||||
|
||||
object.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
|
||||
// point1 is contained in object
|
||||
equal(object.containsPoint(point1), true);
|
||||
// point2 is outside of object (right)
|
||||
equal(object.containsPoint(point2), false);
|
||||
// point3 is outside of object (bottom)
|
||||
equal(object.containsPoint(point3), false);
|
||||
// point4 is outside of object (left)
|
||||
equal(object.containsPoint(point4), false);
|
||||
// point5 is outside of object (top)
|
||||
equal(object.containsPoint(point5), false);
|
||||
});
|
||||
|
||||
test('containsPoint with padding', function() {
|
||||
var object = new fabric.Object({ left: 40, top: 40, width: 40, height: 50, angle: 160, padding: 5 }),
|
||||
point1 = new fabric.Point(30, 30),
|
||||
point2 = new fabric.Point(10, 20),
|
||||
point3 = new fabric.Point(65, 30),
|
||||
point4 = new fabric.Point(45, 75),
|
||||
point5 = new fabric.Point(10, 40),
|
||||
point6 = new fabric.Point(30, 5);
|
||||
|
||||
object.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
|
||||
// point1 is contained in object
|
||||
equal(object.containsPoint(point1), true);
|
||||
// point2 is contained in object (padding area)
|
||||
equal(object.containsPoint(point2), true);
|
||||
// point2 is outside of object (right)
|
||||
equal(object.containsPoint(point3), false);
|
||||
// point3 is outside of object (bottom)
|
||||
equal(object.containsPoint(point4), false);
|
||||
// point4 is outside of object (left)
|
||||
equal(object.containsPoint(point5), false);
|
||||
// point5 is outside of object (top)
|
||||
equal(object.containsPoint(point6), false);
|
||||
});
|
||||
|
||||
test('clipTo', function() {
|
||||
var object = new fabric.Object({
|
||||
left: 40,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,264 @@
|
|||
(function() {
|
||||
|
||||
var canvas = this.canvas = fabric.isLikelyNode ? fabric.createCanvasForNode() : new fabric.StaticCanvas();
|
||||
QUnit.module('fabric.ObjectGeometry');
|
||||
|
||||
test('intersectsWithRectangle', function() {
|
||||
var cObj = new fabric.Object({ left: 50, top: 50, width: 100, height: 100 });
|
||||
cObj.setCoords();
|
||||
ok(typeof cObj.intersectsWithRect == 'function');
|
||||
|
||||
var point1 = new fabric.Point(110, 100),
|
||||
point2 = new fabric.Point(210, 200),
|
||||
point3 = new fabric.Point(0, 0),
|
||||
point4 = new fabric.Point(10, 10);
|
||||
|
||||
ok(cObj.intersectsWithRect(point1, point2));
|
||||
ok(!cObj.intersectsWithRect(point3, point4));
|
||||
});
|
||||
|
||||
test('intersectsWithRectangle absolute', function() {
|
||||
var cObj = new fabric.Rect({ left: 10, top: 10, width: 20, height: 20 });
|
||||
var absolute = true;
|
||||
canvas.add(cObj);
|
||||
canvas.viewportTransform = [2, 0, 0, 2, 0, 0];
|
||||
cObj.setCoords();
|
||||
canvas.calcViewportBoundaries();
|
||||
|
||||
var point1 = new fabric.Point(5, 5),
|
||||
point2 = new fabric.Point(15, 15),
|
||||
point3 = new fabric.Point(25, 25),
|
||||
point4 = new fabric.Point(35, 35);
|
||||
|
||||
ok(!cObj.intersectsWithRect(point1, point2), 'Does not intersect because there is a 2x zoom');
|
||||
ok(!cObj.intersectsWithRect(point3, point4), 'Does not intersect because there is a 2x zoom');
|
||||
ok(cObj.intersectsWithRect(point1, point2, absolute), 'absolute coordinates intersect');
|
||||
ok(cObj.intersectsWithRect(point3, point4, absolute), 'absolute coordinates intersect');
|
||||
});
|
||||
|
||||
test('intersectsWithObject', function() {
|
||||
var cObj = new fabric.Object({ left: 50, top: 50, width: 100, height: 100 });
|
||||
cObj.setCoords();
|
||||
ok(typeof cObj.intersectsWithObject == 'function', 'has intersectsWithObject method');
|
||||
|
||||
var cObj2 = new fabric.Object({ left: -150, top: -150, width: 200, height: 200 });
|
||||
cObj2.setCoords();
|
||||
ok(cObj.intersectsWithObject(cObj2), 'cobj2 does intersect with cobj');
|
||||
ok(cObj2.intersectsWithObject(cObj), 'cobj2 does intersect with cobj');
|
||||
|
||||
var cObj3 = new fabric.Object({ left: 392.5, top: 339.5, width: 13, height: 33 });
|
||||
cObj3.setCoords();
|
||||
ok(!cObj.intersectsWithObject(cObj3), 'cobj3 does not intersect with cobj (external)');
|
||||
ok(!cObj3.intersectsWithObject(cObj), 'cobj3 does not intersect with cobj (external)');
|
||||
|
||||
var cObj4 = new fabric.Object({ left: 0, top: 0, width: 200, height: 200 });
|
||||
cObj4.setCoords();
|
||||
ok(cObj4.intersectsWithObject(cObj), 'overlapping objects are considered intersecting');
|
||||
ok(cObj.intersectsWithObject(cObj4), 'overlapping objects are considered intersecting');
|
||||
});
|
||||
|
||||
test('isContainedWithinRect', function() {
|
||||
var cObj = new fabric.Object({ left: 20, top: 20, width: 10, height: 10 });
|
||||
cObj.setCoords();
|
||||
ok(typeof cObj.isContainedWithinRect == 'function');
|
||||
|
||||
// fully contained
|
||||
ok(cObj.isContainedWithinRect(new fabric.Point(10,10), new fabric.Point(100,100)));
|
||||
// only intersects
|
||||
ok(!cObj.isContainedWithinRect(new fabric.Point(10,10), new fabric.Point(25, 25)));
|
||||
// doesn't intersect
|
||||
ok(!cObj.isContainedWithinRect(new fabric.Point(100,100), new fabric.Point(110, 110)));
|
||||
});
|
||||
|
||||
test('isContainedWithinRect absolute', function() {
|
||||
var cObj = new fabric.Rect({ left: 20, top: 20, width: 10, height: 10 });
|
||||
var absolute = true;
|
||||
canvas.add(cObj);
|
||||
canvas.viewportTransform = [2, 0, 0, 2, 0, 0];
|
||||
cObj.setCoords();
|
||||
canvas.calcViewportBoundaries();
|
||||
ok(typeof cObj.isContainedWithinRect == 'function');
|
||||
|
||||
// fully contained
|
||||
ok(cObj.isContainedWithinRect(new fabric.Point(10,10), new fabric.Point(100,100), absolute));
|
||||
// only intersects
|
||||
ok(!cObj.isContainedWithinRect(new fabric.Point(10,10), new fabric.Point(25, 25), absolute));
|
||||
// doesn't intersect
|
||||
ok(!cObj.isContainedWithinRect(new fabric.Point(100,100), new fabric.Point(110, 110), absolute));
|
||||
});
|
||||
|
||||
test('intersectsWithRect', function() {
|
||||
var object = new fabric.Object({ left: 0, top: 0, width: 40, height: 50, angle: 160 }),
|
||||
point1 = new fabric.Point(-10, -10),
|
||||
point2 = new fabric.Point(20, 30),
|
||||
point3 = new fabric.Point(10, 15),
|
||||
point4 = new fabric.Point(30, 35),
|
||||
point5 = new fabric.Point(50, 60),
|
||||
point6 = new fabric.Point(70, 80);
|
||||
|
||||
object.setCoords();
|
||||
|
||||
// object and area intersects
|
||||
equal(object.intersectsWithRect(point1, point2), true);
|
||||
// area is contained in object (no intersection)
|
||||
equal(object.intersectsWithRect(point3, point4), false);
|
||||
// area is outside of object (no intersection)
|
||||
equal(object.intersectsWithRect(point5, point6), false);
|
||||
});
|
||||
|
||||
test('intersectsWithObject', function() {
|
||||
var object = new fabric.Object({ left: 20, top: 30, width: 40, height: 50, angle: 230, strokeWidth: 0 }),
|
||||
object1 = new fabric.Object({ left: 20, top: 30, width: 60, height: 30, angle: 10, strokeWidth: 0 }),
|
||||
object2 = new fabric.Object({ left: 25, top: 35, width: 20, height: 20, angle: 50, strokeWidth: 0 }),
|
||||
object3 = new fabric.Object({ left: 50, top: 50, width: 20, height: 20, angle: 0, strokeWidth: 0 });
|
||||
|
||||
object.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
object1.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
object2.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
object3.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
|
||||
equal(object.intersectsWithObject(object1), true, 'object and object1 intersects');
|
||||
equal(object.intersectsWithObject(object2), true, 'object2 is contained in object');
|
||||
equal(object.intersectsWithObject(object3), false, 'object3 is outside of object (no intersection)');
|
||||
});
|
||||
|
||||
test('isContainedWithinObject', function() {
|
||||
var object = new fabric.Object({ left: 0, top: 0, width: 40, height: 40, angle: 0 }),
|
||||
object1 = new fabric.Object({ left: 1, top: 1, width: 38, height: 38, angle: 0 }),
|
||||
object2 = new fabric.Object({ left: 20, top: 20, width: 40, height: 40, angle: 0 }),
|
||||
object3 = new fabric.Object({ left: 50, top: 50, width: 40, height: 40, angle: 0 });
|
||||
|
||||
object.setCoords();
|
||||
object1.setCoords();
|
||||
object2.setCoords();
|
||||
object3.setCoords();
|
||||
|
||||
equal(object1.isContainedWithinObject(object), true, 'object1 is fully contained within object');
|
||||
equal(object2.isContainedWithinObject(object), false, 'object2 intersects object (not fully contained)');
|
||||
equal(object3.isContainedWithinObject(object), false, 'object3 is outside of object (not fully contained)');
|
||||
object1.angle = 45;
|
||||
object1.setCoords();
|
||||
equal(object1.isContainedWithinObject(object), false, 'object1 rotated is not contained within object');
|
||||
|
||||
var rect1 = new fabric.Rect({
|
||||
width: 50,
|
||||
height: 50,
|
||||
left: 50,
|
||||
top: 50
|
||||
});
|
||||
|
||||
var rect2 = new fabric.Rect({
|
||||
width: 100,
|
||||
height: 100,
|
||||
left: 100,
|
||||
top: 0,
|
||||
angle: 45,
|
||||
});
|
||||
rect1.setCoords();
|
||||
rect2.setCoords();
|
||||
equal(rect1.isContainedWithinObject(rect2), false, 'rect1 rotated is not contained within rect2');
|
||||
});
|
||||
|
||||
test('isContainedWithinRect', function() {
|
||||
var object = new fabric.Object({ left: 40, top: 40, width: 40, height: 50, angle: 160 }),
|
||||
point1 = new fabric.Point(0, 0),
|
||||
point2 = new fabric.Point(80, 80),
|
||||
point3 = new fabric.Point(0, 0),
|
||||
point4 = new fabric.Point(80, 60),
|
||||
point5 = new fabric.Point(80, 80),
|
||||
point6 = new fabric.Point(90, 90);
|
||||
|
||||
object.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
|
||||
// area is contained in object (no intersection)
|
||||
equal(object.isContainedWithinRect(point1, point2), true);
|
||||
// object and area intersects
|
||||
equal(object.isContainedWithinRect(point3, point4), false);
|
||||
// area is outside of object (no intersection)
|
||||
equal(object.isContainedWithinRect(point5, point6), false);
|
||||
});
|
||||
|
||||
test('isContainedWithinRect', function() {
|
||||
var object = new fabric.Object({ left: 40, top: 40, width: 40, height: 50, angle: 160 }),
|
||||
point1 = new fabric.Point(0, 0),
|
||||
point2 = new fabric.Point(80, 80),
|
||||
point3 = new fabric.Point(0, 0),
|
||||
point4 = new fabric.Point(80, 60),
|
||||
point5 = new fabric.Point(80, 80),
|
||||
point6 = new fabric.Point(90, 90);
|
||||
|
||||
object.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
|
||||
// area is contained in object (no intersection)
|
||||
equal(object.isContainedWithinRect(point1, point2), true);
|
||||
// object and area intersects
|
||||
equal(object.isContainedWithinRect(point3, point4), false);
|
||||
// area is outside of object (no intersection)
|
||||
equal(object.isContainedWithinRect(point5, point6), false);
|
||||
});
|
||||
|
||||
test('containsPoint', function() {
|
||||
var object = new fabric.Object({ left: 40, top: 40, width: 40, height: 50, angle: 160, strokeWidth: 0 }),
|
||||
point1 = new fabric.Point(30, 30),
|
||||
point2 = new fabric.Point(60, 30),
|
||||
point3 = new fabric.Point(45, 65),
|
||||
point4 = new fabric.Point(15, 40),
|
||||
point5 = new fabric.Point(30, 15);
|
||||
|
||||
object.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
|
||||
// point1 is contained in object
|
||||
equal(object.containsPoint(point1), true);
|
||||
// point2 is outside of object (right)
|
||||
equal(object.containsPoint(point2), false);
|
||||
// point3 is outside of object (bottom)
|
||||
equal(object.containsPoint(point3), false);
|
||||
// point4 is outside of object (left)
|
||||
equal(object.containsPoint(point4), false);
|
||||
// point5 is outside of object (top)
|
||||
equal(object.containsPoint(point5), false);
|
||||
});
|
||||
|
||||
test('containsPoint with padding', function() {
|
||||
var object = new fabric.Object({ left: 40, top: 40, width: 40, height: 50, angle: 160, padding: 5 }),
|
||||
point1 = new fabric.Point(30, 30),
|
||||
point2 = new fabric.Point(10, 20),
|
||||
point3 = new fabric.Point(65, 30),
|
||||
point4 = new fabric.Point(45, 75),
|
||||
point5 = new fabric.Point(10, 40),
|
||||
point6 = new fabric.Point(30, 5);
|
||||
|
||||
object.set({ originX: 'center', originY: 'center' }).setCoords();
|
||||
|
||||
// point1 is contained in object
|
||||
equal(object.containsPoint(point1), true);
|
||||
// point2 is contained in object (padding area)
|
||||
equal(object.containsPoint(point2), true);
|
||||
// point2 is outside of object (right)
|
||||
equal(object.containsPoint(point3), false);
|
||||
// point3 is outside of object (bottom)
|
||||
equal(object.containsPoint(point4), false);
|
||||
// point4 is outside of object (left)
|
||||
equal(object.containsPoint(point5), false);
|
||||
// point5 is outside of object (top)
|
||||
equal(object.containsPoint(point6), false);
|
||||
});
|
||||
|
||||
test('setCoords', function() {
|
||||
var cObj = new fabric.Object({ left: 150, top: 150, width: 100, height: 100, strokeWidth: 0});
|
||||
ok(typeof cObj.setCoords == 'function');
|
||||
equal(cObj.setCoords(), cObj, 'chainable');
|
||||
|
||||
equal(cObj.oCoords.tl.x, 150);
|
||||
equal(cObj.oCoords.tl.y, 150);
|
||||
equal(cObj.oCoords.tr.x, 250);
|
||||
equal(cObj.oCoords.tr.y, 150);
|
||||
equal(cObj.oCoords.bl.x, 150);
|
||||
equal(cObj.oCoords.bl.y, 250);
|
||||
equal(cObj.oCoords.br.x, 250);
|
||||
equal(cObj.oCoords.br.y, 250);
|
||||
equal(cObj.oCoords.mtr.x, 200);
|
||||
equal(cObj.oCoords.mtr.y, 110);
|
||||
|
||||
cObj.set('left', 250).set('top', 250);
|
||||
|
||||
// coords should still correspond to initial one, even after invoking `set`
|
||||
|
|
@ -37,6 +289,46 @@
|
|||
equal(cObj.oCoords.mtr.y, 210);
|
||||
});
|
||||
|
||||
test('setCoords and aCoords', function() {
|
||||
var cObj = new fabric.Object({ left: 150, top: 150, width: 100, height: 100, strokeWidth: 0});
|
||||
cObj.canvas = {
|
||||
viewportTransform: [2, 0, 0, 2, 0, 0]
|
||||
};
|
||||
cObj.setCoords();
|
||||
|
||||
equal(cObj.oCoords.tl.x, 300, 'oCoords are modified by viewportTransform');
|
||||
equal(cObj.oCoords.tl.y, 300, 'oCoords are modified by viewportTransform');
|
||||
equal(cObj.oCoords.tr.x, 500, 'oCoords are modified by viewportTransform');
|
||||
equal(cObj.oCoords.tr.y, 300, 'oCoords are modified by viewportTransform');
|
||||
equal(cObj.oCoords.bl.x, 300, 'oCoords are modified by viewportTransform');
|
||||
equal(cObj.oCoords.bl.y, 500, 'oCoords are modified by viewportTransform');
|
||||
equal(cObj.oCoords.br.x, 500, 'oCoords are modified by viewportTransform');
|
||||
equal(cObj.oCoords.br.y, 500, 'oCoords are modified by viewportTransform');
|
||||
equal(cObj.oCoords.mtr.x, 400, 'oCoords are modified by viewportTransform');
|
||||
equal(cObj.oCoords.mtr.y, 260, 'oCoords are modified by viewportTransform');
|
||||
|
||||
equal(cObj.aCoords.tl.x, 150, 'aCoords do not interfere with viewportTransform');
|
||||
equal(cObj.aCoords.tl.y, 150, 'aCoords do not interfere with viewportTransform');
|
||||
equal(cObj.aCoords.tr.x, 250, 'aCoords do not interfere with viewportTransform');
|
||||
equal(cObj.aCoords.tr.y, 150, 'aCoords do not interfere with viewportTransform');
|
||||
equal(cObj.aCoords.bl.x, 150, 'aCoords do not interfere with viewportTransform');
|
||||
equal(cObj.aCoords.bl.y, 250, 'aCoords do not interfere with viewportTransform');
|
||||
equal(cObj.aCoords.br.x, 250, 'aCoords do not interfere with viewportTransform');
|
||||
equal(cObj.aCoords.br.y, 250, 'aCoords do not interfere with viewportTransform');
|
||||
});
|
||||
|
||||
test('isOnScreen', function(){
|
||||
var cObj = new fabric.Object({ left: 50, top: 50, width: 100, height: 100, strokeWidth: 0});
|
||||
cObj.canvas = canvas;
|
||||
cObj.setCoords();
|
||||
ok(cObj.isOnScreen(), 'object is onScreen');
|
||||
cObj.top = 1000;
|
||||
cObj.setCoords();
|
||||
ok(!cObj.isOnScreen(), 'object is not onScreen with top 1000');
|
||||
canvas.setZoom(0.2);
|
||||
ok(cObj.isOnScreen(), 'zooming out the object is again on screen');
|
||||
});
|
||||
|
||||
test('calcTransformMatrix', function(){
|
||||
var cObj = new fabric.Object({ width: 10, height: 15, strokeWidth: 0 });
|
||||
ok(typeof cObj.calcTransformMatrix == 'function', 'calcTransformMatrix should exist');
|
||||
|
|
@ -72,4 +364,59 @@
|
|||
ok(typeof cObj._constrainScale == 'function', '_constrainScale should exist');
|
||||
});
|
||||
|
||||
test('getCoords return coordinate of object in canvas coordinate.', function() {
|
||||
var cObj = new fabric.Object({ width: 10, height: 15, strokeWidth: 2, top: 30, left: 40 });
|
||||
var coords = cObj.getCoords();
|
||||
deepEqual(coords[0], new fabric.Point(40, 30), 'return top left corner');
|
||||
deepEqual(coords[1], new fabric.Point(52, 30), 'return top right corner');
|
||||
deepEqual(coords[2], new fabric.Point(52, 47), 'return bottom right corner');
|
||||
deepEqual(coords[3], new fabric.Point(40, 47), 'return bottom left corner');
|
||||
|
||||
cObj.left += 5;
|
||||
coords = cObj.getCoords();
|
||||
deepEqual(coords[0], new fabric.Point(40, 30), 'return top left corner cached oCoords');
|
||||
deepEqual(coords[1], new fabric.Point(52, 30), 'return top right corner cached oCoords');
|
||||
deepEqual(coords[2], new fabric.Point(52, 47), 'return bottom right corner cached oCoords');
|
||||
deepEqual(coords[3], new fabric.Point(40, 47), 'return bottom left corner cached oCoords');
|
||||
|
||||
coords = cObj.getCoords(false, true);
|
||||
deepEqual(coords[0], new fabric.Point(45, 30), 'return top left corner recalculated');
|
||||
deepEqual(coords[1], new fabric.Point(57, 30), 'return top right corner recalculated');
|
||||
deepEqual(coords[2], new fabric.Point(57, 47), 'return bottom right corner recalculated');
|
||||
deepEqual(coords[3], new fabric.Point(45, 47), 'return bottom left corner recalculated');
|
||||
});
|
||||
|
||||
test('getCoords return coordinate of object in zoomed canvas coordinate.', function() {
|
||||
var cObj = new fabric.Object({ width: 10, height: 15, strokeWidth: 2, top: 30, left: 40 });
|
||||
cObj.canvas = {
|
||||
viewportTransform: [2, 0, 0, 2, 35, 35]
|
||||
};
|
||||
var coords = cObj.getCoords();
|
||||
deepEqual(coords[0], new fabric.Point(115, 95), 'return top left corner is influenced by canvas zoom');
|
||||
deepEqual(coords[1], new fabric.Point(139, 95), 'return top right corner is influenced by canvas zoom');
|
||||
deepEqual(coords[2], new fabric.Point(139, 129), 'return bottom right corner is influenced by canvas zoom');
|
||||
deepEqual(coords[3], new fabric.Point(115, 129), 'return bottom left corner is influenced by canvas zoom');
|
||||
});
|
||||
|
||||
test('getCoords return coordinate of object in absolute coordinates and ignore canvas zoom', function() {
|
||||
var cObj = new fabric.Object({ width: 10, height: 15, strokeWidth: 2, top: 30, left: 40 });
|
||||
cObj.canvas = {
|
||||
viewportTransform: [2, 0, 0, 2, 35, 35]
|
||||
};
|
||||
var coords = cObj.getCoords(true);
|
||||
deepEqual(coords[0], new fabric.Point(40, 30), 'return top left corner cached oCoords');
|
||||
deepEqual(coords[1], new fabric.Point(52, 30), 'return top right corner cached oCoords');
|
||||
deepEqual(coords[2], new fabric.Point(52, 47), 'return bottom right corner cached oCoords');
|
||||
deepEqual(coords[3], new fabric.Point(40, 47), 'return bottom left corner cached oCoords');
|
||||
});
|
||||
|
||||
// test('getCoords return coordinate of object', function() {
|
||||
// var cObj = new fabric.Object({ width: 10, height: 15, strokeWidth: 2, top: 30, left: 40 });
|
||||
// var coords = cObj.getCoords();
|
||||
// equal(coords[0], { x: 40, y: 30 }, 'return top left corner');
|
||||
// equal(coords[1], { x: 1, y: 1 }, 'return top right corner');
|
||||
// equal(coords[2], { x: 1, y: 1 }, 'return bottom right corner');
|
||||
// equal(coords[3], { x: 1, y: 1 }, 'return bottom left corner');
|
||||
// });
|
||||
|
||||
})();
|
||||
|
|
|
|||
Loading…
Reference in a new issue