mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-05-18 18:41:08 +00:00
Build distribution
This commit is contained in:
parent
29c0448235
commit
cecd9bea26
4 changed files with 261 additions and 255 deletions
251
dist/fabric.js
vendored
251
dist/fabric.js
vendored
|
|
@ -885,132 +885,107 @@ fabric.Collection = {
|
||||||
|
|
||||||
var arcToSegmentsCache = { },
|
var arcToSegmentsCache = { },
|
||||||
segmentToBezierCache = { },
|
segmentToBezierCache = { },
|
||||||
_join = Array.prototype.join,
|
_join = Array.prototype.join;
|
||||||
argsString;
|
|
||||||
|
|
||||||
// Generous contribution by Raph Levien, from libsvg-0.1.0.tar.gz
|
|
||||||
function arcToSegments(x, y, rx, ry, large, sweep, rotateX, ox, oy) {
|
|
||||||
|
|
||||||
argsString = _join.call(arguments);
|
|
||||||
|
|
||||||
|
/* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp
|
||||||
|
* by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here
|
||||||
|
* http://mozilla.org/MPL/2.0/
|
||||||
|
*/
|
||||||
|
function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {
|
||||||
|
var argsString = _join.call(arguments);
|
||||||
if (arcToSegmentsCache[argsString]) {
|
if (arcToSegmentsCache[argsString]) {
|
||||||
return arcToSegmentsCache[argsString];
|
return arcToSegmentsCache[argsString];
|
||||||
}
|
}
|
||||||
|
|
||||||
var coords = getXYCoords(rotateX, rx, ry, ox, oy, x, y),
|
var PI = Math.PI, th = rotateX * (PI / 180),
|
||||||
|
|
||||||
d = (coords.x1 - coords.x0) * (coords.x1 - coords.x0) +
|
|
||||||
(coords.y1 - coords.y0) * (coords.y1 - coords.y0),
|
|
||||||
|
|
||||||
sfactorSq = 1 / d - 0.25;
|
|
||||||
|
|
||||||
if (sfactorSq < 0) {
|
|
||||||
sfactorSq = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
var sfactor = Math.sqrt(sfactorSq);
|
|
||||||
if (sweep === large) {
|
|
||||||
sfactor = -sfactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
var xc = 0.5 * (coords.x0 + coords.x1) - sfactor * (coords.y1 - coords.y0),
|
|
||||||
yc = 0.5 * (coords.y0 + coords.y1) + sfactor * (coords.x1 - coords.x0),
|
|
||||||
th0 = Math.atan2(coords.y0 - yc, coords.x0 - xc),
|
|
||||||
th1 = Math.atan2(coords.y1 - yc, coords.x1 - xc),
|
|
||||||
thArc = th1 - th0;
|
|
||||||
|
|
||||||
if (thArc < 0 && sweep === 1) {
|
|
||||||
thArc += 2 * Math.PI;
|
|
||||||
}
|
|
||||||
else if (thArc > 0 && sweep === 0) {
|
|
||||||
thArc -= 2 * Math.PI;
|
|
||||||
}
|
|
||||||
|
|
||||||
var segments = Math.ceil(Math.abs(thArc / (Math.PI * 0.5 + 0.001))),
|
|
||||||
result = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < segments; i++) {
|
|
||||||
var th2 = th0 + i * thArc / segments,
|
|
||||||
th3 = th0 + (i + 1) * thArc / segments;
|
|
||||||
|
|
||||||
result[i] = [xc, yc, th2, th3, rx, ry, coords.sinTh, coords.cosTh];
|
|
||||||
}
|
|
||||||
|
|
||||||
arcToSegmentsCache[argsString] = result;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getXYCoords(rotateX, rx, ry, ox, oy, x, y) {
|
|
||||||
|
|
||||||
var th = rotateX * (Math.PI / 180),
|
|
||||||
sinTh = Math.sin(th),
|
sinTh = Math.sin(th),
|
||||||
cosTh = Math.cos(th);
|
cosTh = Math.cos(th),
|
||||||
|
fromX = 0, fromY = 0;
|
||||||
|
|
||||||
rx = Math.abs(rx);
|
rx = Math.abs(rx);
|
||||||
ry = Math.abs(ry);
|
ry = Math.abs(ry);
|
||||||
|
|
||||||
var px = cosTh * (ox - x) + sinTh * (oy - y),
|
var px = -cosTh * toX - sinTh * toY,
|
||||||
py = cosTh * (oy - y) - sinTh * (ox - x),
|
py = -cosTh * toY + sinTh * toX,
|
||||||
pl = (px * px) / (rx * rx) + (py * py) / (ry * ry);
|
rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px,
|
||||||
|
pl = 4 * rx2 * ry2 - rx2 * py2 - ry2 * px2,
|
||||||
|
root = 0;
|
||||||
|
|
||||||
pl *= 0.25;
|
if (pl < 0) {
|
||||||
|
var s = Math.sqrt(1 - 0.25 * pl/(rx2 * ry2));
|
||||||
if (pl > 1) {
|
rx *= s;
|
||||||
pl = Math.sqrt(pl);
|
ry *= s;
|
||||||
rx *= pl;
|
} else {
|
||||||
ry *= pl;
|
root = (large === sweep ? -0.5 : 0.5) *
|
||||||
|
Math.sqrt( pl /(rx2 * py2 + ry2 * px2));
|
||||||
}
|
}
|
||||||
|
|
||||||
var a00 = cosTh / rx,
|
var cx = root * rx * py / ry,
|
||||||
a01 = sinTh / rx,
|
cy = -root * ry * px / rx,
|
||||||
a10 = (-sinTh) / ry,
|
cx1 = cosTh * cx - sinTh * cy + toX / 2,
|
||||||
a11 = (cosTh) / ry;
|
cy1 = sinTh * cx + cosTh * cy + toY / 2,
|
||||||
|
mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry),
|
||||||
|
dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px -cx) / rx, (-py -cy) / ry);
|
||||||
|
|
||||||
return {
|
if (sweep === 0 && dtheta > 0) {
|
||||||
x0: a00 * ox + a01 * oy,
|
dtheta -= 2 * PI;
|
||||||
y0: a10 * ox + a11 * oy,
|
} else if (sweep === 1 && dtheta < 0) {
|
||||||
x1: a00 * x + a01 * y,
|
dtheta += 2 * PI;
|
||||||
y1: a10 * x + a11 * y,
|
}
|
||||||
sinTh: sinTh,
|
|
||||||
cosTh: cosTh
|
// Convert into cubic bezier segments <= 90deg
|
||||||
};
|
var segments = Math.ceil(Math.abs(dtheta / (PI * 0.5))),
|
||||||
|
result = [], mDelta = dtheta / segments,
|
||||||
|
mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2),
|
||||||
|
th3 = mTheta + mDelta;
|
||||||
|
|
||||||
|
for (var i = 0; i < segments; i++) {
|
||||||
|
result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY);
|
||||||
|
fromX = result[i][4];
|
||||||
|
fromY = result[i][5];
|
||||||
|
mTheta += mDelta;
|
||||||
|
th3 += mDelta;
|
||||||
|
}
|
||||||
|
arcToSegmentsCache[argsString] = result;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function segmentToBezier(cx, cy, th0, th1, rx, ry, sinTh, cosTh) {
|
function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) {
|
||||||
argsString = _join.call(arguments);
|
var argsString2 = _join.call(arguments);
|
||||||
|
if (segmentToBezierCache[argsString2]) {
|
||||||
if (segmentToBezierCache[argsString]) {
|
return segmentToBezierCache[argsString2];
|
||||||
return segmentToBezierCache[argsString];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var costh2 = Math.cos(th2),
|
||||||
|
sinth2 = Math.sin(th2),
|
||||||
|
costh3 = Math.cos(th3),
|
||||||
|
sinth3 = Math.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),
|
||||||
|
cp1Y = fromY + mT * ( - sinTh * rx * sinth2 + cosTh * ry * costh2),
|
||||||
|
cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3),
|
||||||
|
cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3);
|
||||||
|
|
||||||
var sinTh0 = Math.sin(th0),
|
segmentToBezierCache[argsString2] = [
|
||||||
cosTh0 = Math.cos(th0),
|
cp1X, cp1Y,
|
||||||
sinTh1 = Math.sin(th1),
|
cp2X, cp2Y,
|
||||||
cosTh1 = Math.cos(th1),
|
toX, toY
|
||||||
|
|
||||||
a00 = cosTh * rx,
|
|
||||||
a01 = -sinTh * ry,
|
|
||||||
a10 = sinTh * rx,
|
|
||||||
a11 = cosTh * ry,
|
|
||||||
thHalf = 0.25 * (th1 - th0),
|
|
||||||
|
|
||||||
t = (8 / 3) * Math.sin(thHalf) *
|
|
||||||
Math.sin(thHalf) / Math.sin(thHalf * 2),
|
|
||||||
|
|
||||||
x1 = cx + cosTh0 - t * sinTh0,
|
|
||||||
y1 = cy + sinTh0 + t * cosTh0,
|
|
||||||
x3 = cx + cosTh1,
|
|
||||||
y3 = cy + sinTh1,
|
|
||||||
x2 = x3 + t * sinTh1,
|
|
||||||
y2 = y3 - t * cosTh1;
|
|
||||||
|
|
||||||
segmentToBezierCache[argsString] = [
|
|
||||||
a00 * x1 + a01 * y1, a10 * x1 + a11 * y1,
|
|
||||||
a00 * x2 + a01 * y2, a10 * x2 + a11 * y2,
|
|
||||||
a00 * x3 + a01 * y3, a10 * x3 + a11 * y3
|
|
||||||
];
|
];
|
||||||
|
return segmentToBezierCache[argsString2];
|
||||||
|
}
|
||||||
|
|
||||||
return segmentToBezierCache[argsString];
|
/*
|
||||||
|
* Private
|
||||||
|
*/
|
||||||
|
function calcVectorAngle(ux, uy, vx, vy) {
|
||||||
|
var ta = Math.atan2(uy, ux),
|
||||||
|
tb = Math.atan2(vy, vx);
|
||||||
|
if (tb >= ta) {
|
||||||
|
return tb - ta;
|
||||||
|
} else {
|
||||||
|
return 2 * Math.PI - (ta - tb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1020,18 +995,24 @@ fabric.Collection = {
|
||||||
* @param {Number} y
|
* @param {Number} y
|
||||||
* @param {Array} coords
|
* @param {Array} coords
|
||||||
*/
|
*/
|
||||||
fabric.util.drawArc = function(ctx, x, y, coords) {
|
fabric.util.drawArc = function(ctx, fx, fy, coords) {
|
||||||
var rx = coords[0],
|
var rx = coords[0],
|
||||||
ry = coords[1],
|
ry = coords[1],
|
||||||
rot = coords[2],
|
rot = coords[2],
|
||||||
large = coords[3],
|
large = coords[3],
|
||||||
sweep = coords[4],
|
sweep = coords[4],
|
||||||
ex = coords[5],
|
tx = coords[5],
|
||||||
ey = coords[6],
|
ty = coords[6],
|
||||||
segs = arcToSegments(ex, ey, rx, ry, large, sweep, rot, x, y);
|
segs = [[ ], [ ], [ ], [ ]],
|
||||||
for (var i = 0; i < segs.length; i++) {
|
segs_norm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);
|
||||||
var bez = segmentToBezier.apply(this, segs[i]);
|
for (var i = 0; i < segs_norm.length; i++) {
|
||||||
ctx.bezierCurveTo.apply(ctx, bez);
|
segs[i][0] = segs_norm[i][0] + fx;
|
||||||
|
segs[i][1] = segs_norm[i][1] + fy;
|
||||||
|
segs[i][2] = segs_norm[i][2] + fx;
|
||||||
|
segs[i][3] = segs_norm[i][3] + fy;
|
||||||
|
segs[i][4] = segs_norm[i][4] + fx;
|
||||||
|
segs[i][5] = segs_norm[i][5] + fy;
|
||||||
|
ctx.bezierCurveTo.apply(ctx, segs[i]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
@ -4704,7 +4685,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
|
||||||
function getColorStop(el) {
|
function getColorStop(el) {
|
||||||
var style = el.getAttribute('style'),
|
var style = el.getAttribute('style'),
|
||||||
offset = el.getAttribute('offset'),
|
offset = el.getAttribute('offset'),
|
||||||
color, opacity;
|
color, colorAlpha, opacity;
|
||||||
|
|
||||||
// convert percents to absolute values
|
// convert percents to absolute values
|
||||||
offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);
|
offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);
|
||||||
|
|
@ -4738,13 +4719,15 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
|
||||||
opacity = el.getAttribute('stop-opacity');
|
opacity = el.getAttribute('stop-opacity');
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert rgba color to rgb color - alpha value has no affect in svg
|
color = new fabric.Color(color);
|
||||||
color = new fabric.Color(color).toRgb();
|
colorAlpha = color.getAlpha();
|
||||||
|
opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);
|
||||||
|
opacity *= colorAlpha;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
offset: offset,
|
offset: offset,
|
||||||
color: color,
|
color: color.toRgb(),
|
||||||
opacity: isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity)
|
opacity: opacity
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4821,8 +4804,8 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
|
||||||
if (options.gradientTransform) {
|
if (options.gradientTransform) {
|
||||||
this.gradientTransform = options.gradientTransform;
|
this.gradientTransform = options.gradientTransform;
|
||||||
}
|
}
|
||||||
this.origX = options.left;
|
this.origX = options.left || this.origX;
|
||||||
this.orgiY = options.top;
|
this.origY = options.top || this.origY;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -5089,10 +5072,10 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
|
||||||
for (var prop in options) {
|
for (var prop in options) {
|
||||||
//convert to percent units
|
//convert to percent units
|
||||||
if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
|
if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
|
||||||
options[prop] = fabric.util.toFixed((options[prop] - object.origX) / object.width * 100, 2) + '%';
|
options[prop] = fabric.util.toFixed((options[prop] - object.fill.origX) / object.width * 100, 2) + '%';
|
||||||
}
|
}
|
||||||
else if (prop === 'y1' || prop === 'y2') {
|
else if (prop === 'y1' || prop === 'y2') {
|
||||||
options[prop] = fabric.util.toFixed((options[prop] - object.origY) / object.height * 100, 2) + '%';
|
options[prop] = fabric.util.toFixed((options[prop] - object.fill.origY) / object.height * 100, 2) + '%';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -18342,10 +18325,30 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
|
||||||
data[i + 2] = Math.min(255, b + tb);
|
data[i + 2] = Math.min(255, b + tb);
|
||||||
break;
|
break;
|
||||||
case 'diff':
|
case 'diff':
|
||||||
|
case 'difference':
|
||||||
data[i] = Math.abs(r - tr);
|
data[i] = Math.abs(r - tr);
|
||||||
data[i + 1] = Math.abs(g - tg);
|
data[i + 1] = Math.abs(g - tg);
|
||||||
data[i + 2] = Math.abs(b - tb);
|
data[i + 2] = Math.abs(b - tb);
|
||||||
break;
|
break;
|
||||||
|
case 'subtract':
|
||||||
|
var _r = r-tr;
|
||||||
|
var _g = g-tg;
|
||||||
|
var _b = b-tb;
|
||||||
|
|
||||||
|
data[i] = (_r < 0) ? 0 : _r;
|
||||||
|
data[i + 1] = (_g < 0) ? 0 : _g;
|
||||||
|
data[i + 2] = (_b < 0) ? 0 : _b;
|
||||||
|
break;
|
||||||
|
case 'darken':
|
||||||
|
data[i] = Math.min(r, tr);
|
||||||
|
data[i + 1] = Math.min(g, tg);
|
||||||
|
data[i + 2] = Math.min(b, tb);
|
||||||
|
break;
|
||||||
|
case 'lighten':
|
||||||
|
data[i] = Math.max(r, tr);
|
||||||
|
data[i + 1] = Math.max(g, tg);
|
||||||
|
data[i + 2] = Math.max(b, tb);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -21709,7 +21712,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.keyCode in this._keysMap) {
|
if (e.keyCode in this._keysMap && e.charCode === 0) {
|
||||||
this[this._keysMap[e.keyCode]](e);
|
this[this._keysMap[e.keyCode]](e);
|
||||||
}
|
}
|
||||||
else if ((e.keyCode in this._ctrlKeysMap) && (e.ctrlKey || e.metaKey)) {
|
else if ((e.keyCode in this._ctrlKeysMap) && (e.ctrlKey || e.metaKey)) {
|
||||||
|
|
@ -21801,7 +21804,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
||||||
* @param {Event} e Event object
|
* @param {Event} e Event object
|
||||||
*/
|
*/
|
||||||
onKeyPress: function(e) {
|
onKeyPress: function(e) {
|
||||||
if (!this.isEditing || e.metaKey || e.ctrlKey || e.keyCode in this._keysMap) {
|
if (!this.isEditing || e.metaKey || e.ctrlKey || ( e.keyCode in this._keysMap && e.charCode === 0 )) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
14
dist/fabric.min.js
vendored
14
dist/fabric.min.js
vendored
File diff suppressed because one or more lines are too long
BIN
dist/fabric.min.js.gz
vendored
BIN
dist/fabric.min.js.gz
vendored
Binary file not shown.
251
dist/fabric.require.js
vendored
251
dist/fabric.require.js
vendored
|
|
@ -885,132 +885,107 @@ fabric.Collection = {
|
||||||
|
|
||||||
var arcToSegmentsCache = { },
|
var arcToSegmentsCache = { },
|
||||||
segmentToBezierCache = { },
|
segmentToBezierCache = { },
|
||||||
_join = Array.prototype.join,
|
_join = Array.prototype.join;
|
||||||
argsString;
|
|
||||||
|
|
||||||
// Generous contribution by Raph Levien, from libsvg-0.1.0.tar.gz
|
|
||||||
function arcToSegments(x, y, rx, ry, large, sweep, rotateX, ox, oy) {
|
|
||||||
|
|
||||||
argsString = _join.call(arguments);
|
|
||||||
|
|
||||||
|
/* Adapted from http://dxr.mozilla.org/mozilla-central/source/content/svg/content/src/nsSVGPathDataParser.cpp
|
||||||
|
* by Andrea Bogazzi code is under MPL. if you don't have a copy of the license you can take it here
|
||||||
|
* http://mozilla.org/MPL/2.0/
|
||||||
|
*/
|
||||||
|
function arcToSegments(toX, toY, rx, ry, large, sweep, rotateX) {
|
||||||
|
var argsString = _join.call(arguments);
|
||||||
if (arcToSegmentsCache[argsString]) {
|
if (arcToSegmentsCache[argsString]) {
|
||||||
return arcToSegmentsCache[argsString];
|
return arcToSegmentsCache[argsString];
|
||||||
}
|
}
|
||||||
|
|
||||||
var coords = getXYCoords(rotateX, rx, ry, ox, oy, x, y),
|
var PI = Math.PI, th = rotateX * (PI / 180),
|
||||||
|
|
||||||
d = (coords.x1 - coords.x0) * (coords.x1 - coords.x0) +
|
|
||||||
(coords.y1 - coords.y0) * (coords.y1 - coords.y0),
|
|
||||||
|
|
||||||
sfactorSq = 1 / d - 0.25;
|
|
||||||
|
|
||||||
if (sfactorSq < 0) {
|
|
||||||
sfactorSq = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
var sfactor = Math.sqrt(sfactorSq);
|
|
||||||
if (sweep === large) {
|
|
||||||
sfactor = -sfactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
var xc = 0.5 * (coords.x0 + coords.x1) - sfactor * (coords.y1 - coords.y0),
|
|
||||||
yc = 0.5 * (coords.y0 + coords.y1) + sfactor * (coords.x1 - coords.x0),
|
|
||||||
th0 = Math.atan2(coords.y0 - yc, coords.x0 - xc),
|
|
||||||
th1 = Math.atan2(coords.y1 - yc, coords.x1 - xc),
|
|
||||||
thArc = th1 - th0;
|
|
||||||
|
|
||||||
if (thArc < 0 && sweep === 1) {
|
|
||||||
thArc += 2 * Math.PI;
|
|
||||||
}
|
|
||||||
else if (thArc > 0 && sweep === 0) {
|
|
||||||
thArc -= 2 * Math.PI;
|
|
||||||
}
|
|
||||||
|
|
||||||
var segments = Math.ceil(Math.abs(thArc / (Math.PI * 0.5 + 0.001))),
|
|
||||||
result = [];
|
|
||||||
|
|
||||||
for (var i = 0; i < segments; i++) {
|
|
||||||
var th2 = th0 + i * thArc / segments,
|
|
||||||
th3 = th0 + (i + 1) * thArc / segments;
|
|
||||||
|
|
||||||
result[i] = [xc, yc, th2, th3, rx, ry, coords.sinTh, coords.cosTh];
|
|
||||||
}
|
|
||||||
|
|
||||||
arcToSegmentsCache[argsString] = result;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getXYCoords(rotateX, rx, ry, ox, oy, x, y) {
|
|
||||||
|
|
||||||
var th = rotateX * (Math.PI / 180),
|
|
||||||
sinTh = Math.sin(th),
|
sinTh = Math.sin(th),
|
||||||
cosTh = Math.cos(th);
|
cosTh = Math.cos(th),
|
||||||
|
fromX = 0, fromY = 0;
|
||||||
|
|
||||||
rx = Math.abs(rx);
|
rx = Math.abs(rx);
|
||||||
ry = Math.abs(ry);
|
ry = Math.abs(ry);
|
||||||
|
|
||||||
var px = cosTh * (ox - x) + sinTh * (oy - y),
|
var px = -cosTh * toX - sinTh * toY,
|
||||||
py = cosTh * (oy - y) - sinTh * (ox - x),
|
py = -cosTh * toY + sinTh * toX,
|
||||||
pl = (px * px) / (rx * rx) + (py * py) / (ry * ry);
|
rx2 = rx * rx, ry2 = ry * ry, py2 = py * py, px2 = px * px,
|
||||||
|
pl = 4 * rx2 * ry2 - rx2 * py2 - ry2 * px2,
|
||||||
|
root = 0;
|
||||||
|
|
||||||
pl *= 0.25;
|
if (pl < 0) {
|
||||||
|
var s = Math.sqrt(1 - 0.25 * pl/(rx2 * ry2));
|
||||||
if (pl > 1) {
|
rx *= s;
|
||||||
pl = Math.sqrt(pl);
|
ry *= s;
|
||||||
rx *= pl;
|
} else {
|
||||||
ry *= pl;
|
root = (large === sweep ? -0.5 : 0.5) *
|
||||||
|
Math.sqrt( pl /(rx2 * py2 + ry2 * px2));
|
||||||
}
|
}
|
||||||
|
|
||||||
var a00 = cosTh / rx,
|
var cx = root * rx * py / ry,
|
||||||
a01 = sinTh / rx,
|
cy = -root * ry * px / rx,
|
||||||
a10 = (-sinTh) / ry,
|
cx1 = cosTh * cx - sinTh * cy + toX / 2,
|
||||||
a11 = (cosTh) / ry;
|
cy1 = sinTh * cx + cosTh * cy + toY / 2,
|
||||||
|
mTheta = calcVectorAngle(1, 0, (px - cx) / rx, (py - cy) / ry),
|
||||||
|
dtheta = calcVectorAngle((px - cx) / rx, (py - cy) / ry, (-px -cx) / rx, (-py -cy) / ry);
|
||||||
|
|
||||||
return {
|
if (sweep === 0 && dtheta > 0) {
|
||||||
x0: a00 * ox + a01 * oy,
|
dtheta -= 2 * PI;
|
||||||
y0: a10 * ox + a11 * oy,
|
} else if (sweep === 1 && dtheta < 0) {
|
||||||
x1: a00 * x + a01 * y,
|
dtheta += 2 * PI;
|
||||||
y1: a10 * x + a11 * y,
|
}
|
||||||
sinTh: sinTh,
|
|
||||||
cosTh: cosTh
|
// Convert into cubic bezier segments <= 90deg
|
||||||
};
|
var segments = Math.ceil(Math.abs(dtheta / (PI * 0.5))),
|
||||||
|
result = [], mDelta = dtheta / segments,
|
||||||
|
mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2),
|
||||||
|
th3 = mTheta + mDelta;
|
||||||
|
|
||||||
|
for (var i = 0; i < segments; i++) {
|
||||||
|
result[i] = segmentToBezier(mTheta, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY);
|
||||||
|
fromX = result[i][4];
|
||||||
|
fromY = result[i][5];
|
||||||
|
mTheta += mDelta;
|
||||||
|
th3 += mDelta;
|
||||||
|
}
|
||||||
|
arcToSegmentsCache[argsString] = result;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function segmentToBezier(cx, cy, th0, th1, rx, ry, sinTh, cosTh) {
|
function segmentToBezier(th2, th3, cosTh, sinTh, rx, ry, cx1, cy1, mT, fromX, fromY) {
|
||||||
argsString = _join.call(arguments);
|
var argsString2 = _join.call(arguments);
|
||||||
|
if (segmentToBezierCache[argsString2]) {
|
||||||
if (segmentToBezierCache[argsString]) {
|
return segmentToBezierCache[argsString2];
|
||||||
return segmentToBezierCache[argsString];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var costh2 = Math.cos(th2),
|
||||||
|
sinth2 = Math.sin(th2),
|
||||||
|
costh3 = Math.cos(th3),
|
||||||
|
sinth3 = Math.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),
|
||||||
|
cp1Y = fromY + mT * ( - sinTh * rx * sinth2 + cosTh * ry * costh2),
|
||||||
|
cp2X = toX + mT * ( cosTh * rx * sinth3 + sinTh * ry * costh3),
|
||||||
|
cp2Y = toY + mT * ( sinTh * rx * sinth3 - cosTh * ry * costh3);
|
||||||
|
|
||||||
var sinTh0 = Math.sin(th0),
|
segmentToBezierCache[argsString2] = [
|
||||||
cosTh0 = Math.cos(th0),
|
cp1X, cp1Y,
|
||||||
sinTh1 = Math.sin(th1),
|
cp2X, cp2Y,
|
||||||
cosTh1 = Math.cos(th1),
|
toX, toY
|
||||||
|
|
||||||
a00 = cosTh * rx,
|
|
||||||
a01 = -sinTh * ry,
|
|
||||||
a10 = sinTh * rx,
|
|
||||||
a11 = cosTh * ry,
|
|
||||||
thHalf = 0.25 * (th1 - th0),
|
|
||||||
|
|
||||||
t = (8 / 3) * Math.sin(thHalf) *
|
|
||||||
Math.sin(thHalf) / Math.sin(thHalf * 2),
|
|
||||||
|
|
||||||
x1 = cx + cosTh0 - t * sinTh0,
|
|
||||||
y1 = cy + sinTh0 + t * cosTh0,
|
|
||||||
x3 = cx + cosTh1,
|
|
||||||
y3 = cy + sinTh1,
|
|
||||||
x2 = x3 + t * sinTh1,
|
|
||||||
y2 = y3 - t * cosTh1;
|
|
||||||
|
|
||||||
segmentToBezierCache[argsString] = [
|
|
||||||
a00 * x1 + a01 * y1, a10 * x1 + a11 * y1,
|
|
||||||
a00 * x2 + a01 * y2, a10 * x2 + a11 * y2,
|
|
||||||
a00 * x3 + a01 * y3, a10 * x3 + a11 * y3
|
|
||||||
];
|
];
|
||||||
|
return segmentToBezierCache[argsString2];
|
||||||
|
}
|
||||||
|
|
||||||
return segmentToBezierCache[argsString];
|
/*
|
||||||
|
* Private
|
||||||
|
*/
|
||||||
|
function calcVectorAngle(ux, uy, vx, vy) {
|
||||||
|
var ta = Math.atan2(uy, ux),
|
||||||
|
tb = Math.atan2(vy, vx);
|
||||||
|
if (tb >= ta) {
|
||||||
|
return tb - ta;
|
||||||
|
} else {
|
||||||
|
return 2 * Math.PI - (ta - tb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1020,18 +995,24 @@ fabric.Collection = {
|
||||||
* @param {Number} y
|
* @param {Number} y
|
||||||
* @param {Array} coords
|
* @param {Array} coords
|
||||||
*/
|
*/
|
||||||
fabric.util.drawArc = function(ctx, x, y, coords) {
|
fabric.util.drawArc = function(ctx, fx, fy, coords) {
|
||||||
var rx = coords[0],
|
var rx = coords[0],
|
||||||
ry = coords[1],
|
ry = coords[1],
|
||||||
rot = coords[2],
|
rot = coords[2],
|
||||||
large = coords[3],
|
large = coords[3],
|
||||||
sweep = coords[4],
|
sweep = coords[4],
|
||||||
ex = coords[5],
|
tx = coords[5],
|
||||||
ey = coords[6],
|
ty = coords[6],
|
||||||
segs = arcToSegments(ex, ey, rx, ry, large, sweep, rot, x, y);
|
segs = [[ ], [ ], [ ], [ ]],
|
||||||
for (var i = 0; i < segs.length; i++) {
|
segs_norm = arcToSegments(tx - fx, ty - fy, rx, ry, large, sweep, rot);
|
||||||
var bez = segmentToBezier.apply(this, segs[i]);
|
for (var i = 0; i < segs_norm.length; i++) {
|
||||||
ctx.bezierCurveTo.apply(ctx, bez);
|
segs[i][0] = segs_norm[i][0] + fx;
|
||||||
|
segs[i][1] = segs_norm[i][1] + fy;
|
||||||
|
segs[i][2] = segs_norm[i][2] + fx;
|
||||||
|
segs[i][3] = segs_norm[i][3] + fy;
|
||||||
|
segs[i][4] = segs_norm[i][4] + fx;
|
||||||
|
segs[i][5] = segs_norm[i][5] + fy;
|
||||||
|
ctx.bezierCurveTo.apply(ctx, segs[i]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
@ -4704,7 +4685,7 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
|
||||||
function getColorStop(el) {
|
function getColorStop(el) {
|
||||||
var style = el.getAttribute('style'),
|
var style = el.getAttribute('style'),
|
||||||
offset = el.getAttribute('offset'),
|
offset = el.getAttribute('offset'),
|
||||||
color, opacity;
|
color, colorAlpha, opacity;
|
||||||
|
|
||||||
// convert percents to absolute values
|
// convert percents to absolute values
|
||||||
offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);
|
offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);
|
||||||
|
|
@ -4738,13 +4719,15 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
|
||||||
opacity = el.getAttribute('stop-opacity');
|
opacity = el.getAttribute('stop-opacity');
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert rgba color to rgb color - alpha value has no affect in svg
|
color = new fabric.Color(color);
|
||||||
color = new fabric.Color(color).toRgb();
|
colorAlpha = color.getAlpha();
|
||||||
|
opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);
|
||||||
|
opacity *= colorAlpha;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
offset: offset,
|
offset: offset,
|
||||||
color: color,
|
color: color.toRgb(),
|
||||||
opacity: isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity)
|
opacity: opacity
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4821,8 +4804,8 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
|
||||||
if (options.gradientTransform) {
|
if (options.gradientTransform) {
|
||||||
this.gradientTransform = options.gradientTransform;
|
this.gradientTransform = options.gradientTransform;
|
||||||
}
|
}
|
||||||
this.origX = options.left;
|
this.origX = options.left || this.origX;
|
||||||
this.orgiY = options.top;
|
this.origY = options.top || this.origY;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -5089,10 +5072,10 @@ fabric.ElementsParser.prototype.checkIfDone = function() {
|
||||||
for (var prop in options) {
|
for (var prop in options) {
|
||||||
//convert to percent units
|
//convert to percent units
|
||||||
if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
|
if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
|
||||||
options[prop] = fabric.util.toFixed((options[prop] - object.origX) / object.width * 100, 2) + '%';
|
options[prop] = fabric.util.toFixed((options[prop] - object.fill.origX) / object.width * 100, 2) + '%';
|
||||||
}
|
}
|
||||||
else if (prop === 'y1' || prop === 'y2') {
|
else if (prop === 'y1' || prop === 'y2') {
|
||||||
options[prop] = fabric.util.toFixed((options[prop] - object.origY) / object.height * 100, 2) + '%';
|
options[prop] = fabric.util.toFixed((options[prop] - object.fill.origY) / object.height * 100, 2) + '%';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -18342,10 +18325,30 @@ fabric.Image.filters.BaseFilter = fabric.util.createClass(/** @lends fabric.Imag
|
||||||
data[i + 2] = Math.min(255, b + tb);
|
data[i + 2] = Math.min(255, b + tb);
|
||||||
break;
|
break;
|
||||||
case 'diff':
|
case 'diff':
|
||||||
|
case 'difference':
|
||||||
data[i] = Math.abs(r - tr);
|
data[i] = Math.abs(r - tr);
|
||||||
data[i + 1] = Math.abs(g - tg);
|
data[i + 1] = Math.abs(g - tg);
|
||||||
data[i + 2] = Math.abs(b - tb);
|
data[i + 2] = Math.abs(b - tb);
|
||||||
break;
|
break;
|
||||||
|
case 'subtract':
|
||||||
|
var _r = r-tr;
|
||||||
|
var _g = g-tg;
|
||||||
|
var _b = b-tb;
|
||||||
|
|
||||||
|
data[i] = (_r < 0) ? 0 : _r;
|
||||||
|
data[i + 1] = (_g < 0) ? 0 : _g;
|
||||||
|
data[i + 2] = (_b < 0) ? 0 : _b;
|
||||||
|
break;
|
||||||
|
case 'darken':
|
||||||
|
data[i] = Math.min(r, tr);
|
||||||
|
data[i + 1] = Math.min(g, tg);
|
||||||
|
data[i + 2] = Math.min(b, tb);
|
||||||
|
break;
|
||||||
|
case 'lighten':
|
||||||
|
data[i] = Math.max(r, tr);
|
||||||
|
data[i + 1] = Math.max(g, tg);
|
||||||
|
data[i + 2] = Math.max(b, tb);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -21709,7 +21712,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.keyCode in this._keysMap) {
|
if (e.keyCode in this._keysMap && e.charCode === 0) {
|
||||||
this[this._keysMap[e.keyCode]](e);
|
this[this._keysMap[e.keyCode]](e);
|
||||||
}
|
}
|
||||||
else if ((e.keyCode in this._ctrlKeysMap) && (e.ctrlKey || e.metaKey)) {
|
else if ((e.keyCode in this._ctrlKeysMap) && (e.ctrlKey || e.metaKey)) {
|
||||||
|
|
@ -21801,7 +21804,7 @@ fabric.util.object.extend(fabric.IText.prototype, /** @lends fabric.IText.protot
|
||||||
* @param {Event} e Event object
|
* @param {Event} e Event object
|
||||||
*/
|
*/
|
||||||
onKeyPress: function(e) {
|
onKeyPress: function(e) {
|
||||||
if (!this.isEditing || e.metaKey || e.ctrlKey || e.keyCode in this._keysMap) {
|
if (!this.isEditing || e.metaKey || e.ctrlKey || ( e.keyCode in this._keysMap && e.charCode === 0 )) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue