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

Version 2.0.2 #4741

Merged
merged 1 commit into from
Feb 18, 2018
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
**Version 2.0.2**
- fixed image toSVG support for crop [#4738](https://github.com/kangax/fabric.js/pull/4738)
- changed math for better rounded results [#4734](https://github.com/kangax/fabric.js/pull/4734)

**Version 2.0.1**
- fixed filter for blend image in WEBGL [#4706](https://github.com/kangax/fabric.js/pull/4706)
- fixed interactions between canvas toDataURL and multiplier + retina [#4705](https://github.com/kangax/fabric.js/pull/4705)
Expand Down
2 changes: 1 addition & 1 deletion HEADER.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */

var fabric = fabric || { version: '2.0.1' };
var fabric = fabric || { version: '2.0.2' };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
Expand Down
2 changes: 1 addition & 1 deletion ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Remove the template from below and provide thoughtful commentary *and code sampl

<!-- BUG TEMPLATE -->
## Version
2.0
2.0.2

## Test Case
http://jsfiddle.net/fabricjs/Da7SP/
Expand Down
218 changes: 149 additions & 69 deletions dist/fabric.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* build: `node build.js modules=ALL exclude=gestures,accessors minifier=uglifyjs` */
/*! Fabric.js Copyright 2008-2015, Printio (Juriy Zaytsev, Maxim Chernyak) */

var fabric = fabric || { version: '2.0.1' };
var fabric = fabric || { version: '2.0.2' };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
}
Expand Down Expand Up @@ -567,13 +567,57 @@ fabric.CommonMethods = {
atan2 = Math.atan2,
pow = Math.pow,
abs = Math.abs,
PiBy180 = Math.PI / 180;
PiBy180 = Math.PI / 180,
PiBy2 = Math.PI / 2;

/**
* @namespace fabric.util
*/
fabric.util = {

/**
* Calculate the cos of an angle, avoiding returning floats for known results
* @static
* @memberOf fabric.util
* @param {Number} angle the angle in radians or in degree
* @return {Number}
*/
cos: function(angle) {
if (angle === 0) { return 1; }
if (angle < 0) {
// cos(a) = cos(-a)
angle = -angle;
}
var angleSlice = angle / PiBy2;
switch (angleSlice) {
case 1: case 3: return 0;
case 2: return -1;
}
return Math.cos(angle);
},

/**
* Calculate the sin of an angle, avoiding returning floats for known results
* @static
* @memberOf fabric.util
* @param {Number} angle the angle in radians or in degree
* @return {Number}
*/
sin: function(angle) {
if (angle === 0) { return 0; }
var angleSlice = angle / PiBy2, sign = 1;
if (angle < 0) {
// sin(-a) = -sin(a)
sign = -1;
}
switch (angleSlice) {
case 1: return sign;
case 2: return 0;
case 3: return -sign;
}
return Math.sin(angle);
},

/**
* Removes value from an array.
* Presence of value (and its position in an array) is determined via `Array.prototype.indexOf`
Expand Down Expand Up @@ -649,8 +693,8 @@ fabric.CommonMethods = {
* @return {Object} The new rotated point
*/
rotateVector: function(vector, radians) {
var sin = Math.sin(radians),
cos = Math.cos(radians),
var sin = fabric.util.sin(radians),
cos = fabric.util.cos(radians),
rx = vector.x * cos - vector.y * sin,
ry = vector.x * sin + vector.y * cos;
return {
Expand Down Expand Up @@ -1329,8 +1373,8 @@ fabric.CommonMethods = {
}

var PI = Math.PI, th = rotateX * PI / 180,
sinTh = Math.sin(th),
cosTh = Math.cos(th),
sinTh = fabric.util.sin(th),
cosTh = fabric.util.cos(th),
fromX = 0, fromY = 0;

rx = Math.abs(rx);
Expand Down Expand Up @@ -1389,10 +1433,10 @@ fabric.CommonMethods = {
return segmentToBezierCache[argsString2];
}

var costh2 = Math.cos(th2),
sinth2 = Math.sin(th2),
costh3 = Math.cos(th3),
sinth3 = Math.sin(th3),
var costh2 = fabric.util.cos(th2),
sinth2 = fabric.util.sin(th2),
costh3 = fabric.util.cos(th3),
sinth3 = fabric.util.sin(th3),
toX = cosTh * rx * costh3 - sinTh * ry * sinth3 + cx1,
toY = sinTh * rx * costh3 + cosTh * ry * sinth3 + cy1,
cp1X = fromX + mT * ( -cosTh * rx * sinth2 - sinTh * ry * costh2),
Expand Down Expand Up @@ -3408,7 +3452,7 @@ if (typeof console !== 'undefined') {
*/
fabric.parseTransformAttribute = (function() {
function rotateMatrix(matrix, args) {
var cos = Math.cos(args[0]), sin = Math.sin(args[0]),
var cos = fabric.util.cos(args[0]), sin = fabric.util.sin(args[0]),
x = 0, y = 0;
if (args.length === 3) {
x = args[1];
Expand Down Expand Up @@ -13898,8 +13942,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
adjustPosition: function(to) {
var angle = degreesToRadians(this.angle),
hypotFull = this.getScaledWidth(),
xFull = Math.cos(angle) * hypotFull,
yFull = Math.sin(angle) * hypotFull,
xFull = fabric.util.cos(angle) * hypotFull,
yFull = fabric.util.sin(angle) * hypotFull,
offsetFrom, offsetTo;

//TODO: this function does not consider mixed situation like top, center.
Expand Down Expand Up @@ -13990,7 +14034,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
}

var degreesToRadians = fabric.util.degreesToRadians,
multiplyMatrices = fabric.util.multiplyTransformMatrices;
multiplyMatrices = fabric.util.multiplyTransformMatrices,
transformPoint = fabric.util.transformPoint;

fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {

Expand Down Expand Up @@ -14335,45 +14380,55 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
* @chainable
*/
calcCoords: function(absolute) {
var theta = degreesToRadians(this.angle),
var rotateMatrix = this._calcRotateMatrix(),
translateMatrix = this._calcTranslateMatrix(),
startMatrix = multiplyMatrices(translateMatrix, rotateMatrix),
vpt = this.getViewportTransform(),
dim = absolute ? this._getTransformedDimensions() : this._calculateCurrentDimensions(),
currentWidth = dim.x, currentHeight = dim.y,
sinTh = theta ? Math.sin(theta) : 0,
cosTh = theta ? Math.cos(theta) : 1,
_angle = currentWidth > 0 ? Math.atan(currentHeight / currentWidth) : 0,
_hypotenuse = (currentWidth / Math.cos(_angle)) / 2,
offsetX = Math.cos(_angle + theta) * _hypotenuse,
offsetY = Math.sin(_angle + theta) * _hypotenuse,
center = this.getCenterPoint(),
// offset added for rotate and scale actions
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);
finalMatrix = absolute ? startMatrix : multiplyMatrices(vpt, startMatrix),
dim = this._getTransformedDimensions(),
w = dim.x / 2, h = dim.y / 2,
tl = transformPoint({ x: -w, y: -h }, finalMatrix),
tr = transformPoint({ x: w, y: -h }, finalMatrix),
bl = transformPoint({ x: -w, y: h }, finalMatrix),
br = transformPoint({ x: w, y: h }, finalMatrix);
if (!absolute) {
var padding = this.padding, angle = degreesToRadians(this.angle),
cos = fabric.util.cos(angle), sin = fabric.util.sin(angle),
cosP = cos * padding, sinP = sin * padding, cosPSinP = cosP + sinP,
cosPMinusSinP = cosP - sinP;
if (padding) {
tl.x -= cosPMinusSinP;
tl.y -= cosPSinP;
tr.x += cosPSinP;
tr.y -= cosPMinusSinP;
bl.x -= cosPSinP;
bl.y += cosPMinusSinP;
br.x += cosPMinusSinP;
br.y += cosPSinP;
}
var ml = new fabric.Point((tl.x + bl.x) / 2, (tl.y + bl.y) / 2),
mt = new fabric.Point((tr.x + tl.x) / 2, (tr.y + tl.y) / 2),
mr = new fabric.Point((br.x + tr.x) / 2, (br.y + tr.y) / 2),
mb = new fabric.Point((br.x + bl.x) / 2, (br.y + bl.y) / 2),
mtr = new fabric.Point(mt.x + sinTh * this.rotatingPointOffset, mt.y - cosTh * this.rotatingPointOffset);
}

// debugging

/* setTimeout(function() {
canvas.contextTop.fillStyle = 'green';
canvas.contextTop.fillRect(mb.x, mb.y, 3, 3);
canvas.contextTop.fillRect(bl.x, bl.y, 3, 3);
canvas.contextTop.fillRect(br.x, br.y, 3, 3);
canvas.contextTop.fillRect(tl.x, tl.y, 3, 3);
canvas.contextTop.fillRect(tr.x, tr.y, 3, 3);
canvas.contextTop.fillRect(ml.x, ml.y, 3, 3);
canvas.contextTop.fillRect(mr.x, mr.y, 3, 3);
canvas.contextTop.fillRect(mt.x, mt.y, 3, 3);
canvas.contextTop.fillRect(mtr.x, mtr.y, 3, 3);
}, 50); */
mtr = new fabric.Point(mt.x + sin * this.rotatingPointOffset, mt.y - cos * this.rotatingPointOffset);
}

// if (!absolute) {
// var canvas = this.canvas;
// setTimeout(function() {
// canvas.contextTop.clearRect(0, 0, 700, 700);
// canvas.contextTop.fillStyle = 'green';
// canvas.contextTop.fillRect(mb.x, mb.y, 3, 3);
// canvas.contextTop.fillRect(bl.x, bl.y, 3, 3);
// canvas.contextTop.fillRect(br.x, br.y, 3, 3);
// canvas.contextTop.fillRect(tl.x, tl.y, 3, 3);
// canvas.contextTop.fillRect(tr.x, tr.y, 3, 3);
// canvas.contextTop.fillRect(ml.x, ml.y, 3, 3);
// canvas.contextTop.fillRect(mr.x, mr.y, 3, 3);
// canvas.contextTop.fillRect(mt.x, mt.y, 3, 3);
// canvas.contextTop.fillRect(mtr.x, mtr.y, 3, 3);
// }, 50);
// }

var coords = {
// corners
Expand Down Expand Up @@ -14417,16 +14472,21 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
*/
_calcRotateMatrix: function() {
if (this.angle) {
var theta = degreesToRadians(this.angle), cos = Math.cos(theta), sin = Math.sin(theta);
// trying to keep rounding error small, ugly but it works.
if (cos === 6.123233995736766e-17 || cos === -1.8369701987210297e-16) {
cos = 0;
}
var theta = degreesToRadians(this.angle), cos = fabric.util.cos(theta), sin = fabric.util.sin(theta);
return [cos, sin, -sin, cos, 0, 0];
}
return fabric.iMatrix.concat();
},

/**
* calculate the translation matrix for an object transform
* @return {Array} rotation matrix for the object
*/
_calcTranslateMatrix: function() {
var center = this.getCenterPoint();
return [1, 0, 0, 1, center.x, center.y];
},

transformMatrixKey: function(skipGroup) {
var sep = '_', prefix = '';
if (!skipGroup && this.group) {
Expand Down Expand Up @@ -14465,8 +14525,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
if (cache.key === key) {
return cache.value;
}
var center = this.getCenterPoint(),
matrix = [1, 0, 0, 1, center.x, center.y],
var matrix = this._calcTranslateMatrix(),
rotateMatrix,
dimensionMatrix = this._calcDimensionsTransformMatrix(this.skewX, this.skewY, true);
if (this.angle) {
Expand Down Expand Up @@ -14522,8 +14581,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
if (typeof skewY === 'undefined') {
skewY = this.skewY;
}
var dimensions = this._getNonTransformedDimensions(),
dimX = dimensions.x / 2, dimY = dimensions.y / 2,
var dimensions = this._getNonTransformedDimensions();
if (skewX === 0 && skewY === 0) {
return { x: dimensions.x * this.scaleX, y: dimensions.y * this.scaleY };
}
var dimX = dimensions.x / 2, dimY = dimensions.y / 2,
points = [
{
x: -dimX,
Expand Down Expand Up @@ -15036,8 +15098,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
/* Math.sqrt(2 * Math.pow(this.cornerSize, 2)) / 2, */
/* 0.707106 stands for sqrt(2)/2 */
cornerHypotenuse = this.cornerSize * 0.707106,
cosHalfOffset = cornerHypotenuse * Math.cos(newTheta),
sinHalfOffset = cornerHypotenuse * Math.sin(newTheta),
cosHalfOffset = cornerHypotenuse * fabric.util.cos(newTheta),
sinHalfOffset = cornerHypotenuse * fabric.util.sin(newTheta),
x, y;

for (var point in coords) {
Expand Down Expand Up @@ -16047,10 +16109,10 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
);
}
else {
var startX = Math.cos(this.startAngle) * this.radius,
startY = Math.sin(this.startAngle) * this.radius,
endX = Math.cos(this.endAngle) * this.radius,
endY = Math.sin(this.endAngle) * this.radius,
var startX = fabric.util.cos(this.startAngle) * this.radius,
startY = fabric.util.sin(this.startAngle) * this.radius,
endX = fabric.util.cos(this.endAngle) * this.radius,
endY = fabric.util.sin(this.endAngle) * this.radius,
largeFlag = angle > pi ? '1' : '0';

markup.push(
Expand Down Expand Up @@ -19001,24 +19063,42 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
return object;
},

/**
* Returns true if an image has crop applied, inspecting values of cropX,cropY,width,hight.
* @return {Boolean}
*/
hasCrop: function() {
return this.cropX || this.cropY || this.width < this._element.width || this.height < this._element.height;
},

/* _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 markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2;
var markup = this._createBaseSVGMarkup(), x = -this.width / 2, y = -this.height / 2, clipPath = '';
if (this.hasCrop()) {
var clipPathId = fabric.Object.__uid++;
markup.push(
'<clipPath id="imageCrop_' + clipPathId + '">\n',
'\t<rect x="' + x + '" y="' + y + '" width="' + this.width + '" height="' + this.height + '" />\n',
'</clipPath>\n'
);
clipPath = ' clip-path="url(#imageCrop_' + clipPathId + ')" ';
}
markup.push('<g transform="', this.getSvgTransform(), this.getSvgTransformMatrix(), '">\n');
var imageMarkup = ['\t<image ', this.getSvgId(), 'xlink:href="', this.getSvgSrc(true),
'" x="', x, '" y="', y,
'" x="', x - this.cropX, '" y="', y - this.cropY,
'" style="', this.getSvgStyles(),
// we're essentially moving origin of transformation from top/left corner to the center of the shape
// by wrapping it in container <g> element with actual transformation, then offsetting object to the top/left
// so that object's center aligns with container's left/top
'" width="', this.width,
'" height="', this.height,
'"></image>\n'];
'" width="', this._element.width || this._element.naturalWidth,
'" height="', this._element.height || this._element.height,
'"', clipPath,
'></image>\n'];
if (this.paintFirst === 'fill') {
Array.prototype.push.apply(markup, imageMarkup);
}
Expand Down Expand Up @@ -20530,7 +20610,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
* @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
* @example
* var filter = new fabric.Image.filters.Brightness({
* brightness: 200
* brightness: 0.05
* });
* object.filters.push(filter);
* object.applyFilters();
Expand Down Expand Up @@ -23499,7 +23579,7 @@ fabric.Image.filters.BaseFilter.fromObject = function(object, callback) {
mainParameter: 'rotation',

calculateMatrix: function() {
var rad = this.rotation * Math.PI, cos = Math.cos(rad), sin = Math.sin(rad),
var rad = this.rotation * Math.PI, cos = fabric.util.cos(rad), sin = fabric.util.sin(rad),
aThird = 1 / 3, aThirdSqtSin = Math.sqrt(aThird) * sin, OneMinusCos = 1 - cos;
this.matrix = [
1, 0, 0, 0, 0,
Expand Down
2 changes: 1 addition & 1 deletion dist/fabric.min.js

Large diffs are not rendered by default.

Loading