mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-03-16 22:10:32 +00:00
Some refactoring; move arc into a separate file
This commit is contained in:
parent
6260f55df6
commit
de7b92bda5
8 changed files with 639 additions and 617 deletions
1
build.js
1
build.js
|
|
@ -148,6 +148,7 @@ var filesToInclude = [
|
|||
'src/mixins/collection.mixin.js',
|
||||
|
||||
'src/util/misc.js',
|
||||
'src/util/arc.js',
|
||||
'src/util/lang_array.js',
|
||||
'src/util/lang_object.js',
|
||||
'src/util/lang_string.js',
|
||||
|
|
|
|||
|
|
@ -86,15 +86,16 @@
|
|||
* @param {Object} canvasEl Canvas element to apply filter to
|
||||
*/
|
||||
applyTo: function(canvasEl) {
|
||||
var weights = this.matrix;
|
||||
var context = canvasEl.getContext('2d');
|
||||
var pixels = context.getImageData(0, 0, canvasEl.width, canvasEl.height);
|
||||
|
||||
var side = Math.round(Math.sqrt(weights.length));
|
||||
var halfSide = Math.floor(side/2);
|
||||
var src = pixels.data;
|
||||
var sw = pixels.width;
|
||||
var sh = pixels.height;
|
||||
var weights = this.matrix,
|
||||
context = canvasEl.getContext('2d'),
|
||||
pixels = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
|
||||
|
||||
side = Math.round(Math.sqrt(weights.length)),
|
||||
halfSide = Math.floor(side/2),
|
||||
src = pixels.data,
|
||||
sw = pixels.width,
|
||||
sh = pixels.height;
|
||||
|
||||
// pad output by the convolution matrix
|
||||
var w = sw;
|
||||
|
|
@ -105,6 +106,7 @@
|
|||
|
||||
// go through the destination image pixels
|
||||
var alphaFac = this.opaque ? 1 : 0;
|
||||
|
||||
for (var y=0; y<h; y++) {
|
||||
for (var x=0; x<w; x++) {
|
||||
var sy = y;
|
||||
|
|
@ -113,18 +115,23 @@
|
|||
// calculate the weighed sum of the source image pixels that
|
||||
// fall under the convolution matrix
|
||||
var r=0, g=0, b=0, a=0;
|
||||
|
||||
for (var cy=0; cy<side; cy++) {
|
||||
for (var cx=0; cx<side; cx++) {
|
||||
|
||||
var scy = sy + cy - halfSide;
|
||||
var scx = sx + cx - halfSide;
|
||||
if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) {
|
||||
var srcOff = (scy*sw+scx)*4;
|
||||
var wt = weights[cy*side+cx];
|
||||
r += src[srcOff] * wt;
|
||||
g += src[srcOff+1] * wt;
|
||||
b += src[srcOff+2] * wt;
|
||||
a += src[srcOff+3] * wt;
|
||||
}
|
||||
|
||||
/* jshint maxdepth:5 */
|
||||
if (scy < 0 || scy > sh || scx < 0 || scx > sw) continue;
|
||||
|
||||
var srcOff = (scy*sw+scx)*4;
|
||||
var wt = weights[cy*side+cx];
|
||||
|
||||
r += src[srcOff] * wt;
|
||||
g += src[srcOff+1] * wt;
|
||||
b += src[srcOff+2] * wt;
|
||||
a += src[srcOff+3] * wt;
|
||||
}
|
||||
}
|
||||
dst[dstOff] = r;
|
||||
|
|
|
|||
|
|
@ -282,7 +282,8 @@
|
|||
useNative: true,
|
||||
|
||||
/**
|
||||
* List of properties to consider when checking if state of an object is changed ({@link fabric.Object#hasStateChanged})
|
||||
* List of properties to consider when checking if
|
||||
* state of an object is changed ({@link fabric.Object#hasStateChanged})
|
||||
* as well as for history (undo/redo) purposes
|
||||
* @type Array
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@
|
|||
/**
|
||||
* Background image of canvas instance.
|
||||
* Should be set via {@link fabric.StaticCanvas#setBackgroundImage}.
|
||||
* <b>Backwards incompatibility note:</b> The "backgroundImageOpacity" and "backgroundImageStretch" properties are deprecated since 1.3.9.
|
||||
* <b>Backwards incompatibility note:</b> The "backgroundImageOpacity"
|
||||
* and "backgroundImageStretch" properties are deprecated since 1.3.9.
|
||||
* Use {@link fabric.Image#opacity}, {@link fabric.Image#width} and {@link fabric.Image#height}.
|
||||
* @type fabric.Image
|
||||
* @default
|
||||
|
|
@ -72,7 +73,8 @@
|
|||
/**
|
||||
* Overlay image of canvas instance.
|
||||
* Should be set via {@link fabric.StaticCanvas#setOverlayImage}.
|
||||
* <b>Backwards incompatibility note:</b> The "overlayImageLeft" and "overlayImageTop" properties are deprecated since 1.3.9.
|
||||
* <b>Backwards incompatibility note:</b> The "overlayImageLeft"
|
||||
* and "overlayImageTop" properties are deprecated since 1.3.9.
|
||||
* Use {@link fabric.Image#left} and {@link fabric.Image#top}.
|
||||
* @type fabric.Image
|
||||
* @default
|
||||
|
|
@ -303,7 +305,8 @@
|
|||
|
||||
/**
|
||||
* @private
|
||||
* @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage} or {@link fabric.StaticCanvas#overlayImage|overlayImage})
|
||||
* @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundImage|backgroundImage}
|
||||
* or {@link fabric.StaticCanvas#overlayImage|overlayImage})
|
||||
* @param {(fabric.Image|String)} image fabric.Image instance or URL of an image to set background or overlay to
|
||||
* @param {Function} callback Callback to invoke when image is loaded and set as background or overlay
|
||||
* @param {Object} [options] Optional options to set for the {@link fabric.Image|image}.
|
||||
|
|
@ -325,7 +328,8 @@
|
|||
|
||||
/**
|
||||
* @private
|
||||
* @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor} or {@link fabric.StaticCanvas#overlayColor|overlayColor})
|
||||
* @param {String} property Property to set ({@link fabric.StaticCanvas#backgroundColor|backgroundColor}
|
||||
* or {@link fabric.StaticCanvas#overlayColor|overlayColor})
|
||||
* @param {(Object|String)} color Object with pattern information or color value
|
||||
* @param {Function} [callback] Callback is invoked when color is set
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -12,40 +12,6 @@
|
|||
Math.sin( (t * d - opts.s) * (2 * Math.PI) / opts.p );
|
||||
}
|
||||
|
||||
/**
|
||||
* Quadratic easing in
|
||||
* @memberOf fabric.util.ease
|
||||
*/
|
||||
function easeInQuad(t, b, c, d) {
|
||||
return c*(t/=d)*t + b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quadratic easing out
|
||||
* @memberOf fabric.util.ease
|
||||
*/
|
||||
function easeOutQuad(t, b, c, d) {
|
||||
return -c *(t/=d)*(t-2) + b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quadratic easing in and out
|
||||
* @memberOf fabric.util.ease
|
||||
*/
|
||||
function easeInOutQuad(t, b, c, d) {
|
||||
t /= (d/2);
|
||||
if (t < 1) return c/2*t*t + b;
|
||||
return -c/2 * ((--t)*(t-2) - 1) + b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cubic easing in
|
||||
* @memberOf fabric.util.ease
|
||||
*/
|
||||
function easeInCubic(t, b, c, d) {
|
||||
return c*(t/=d)*t*t + b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cubic easing out
|
||||
* @memberOf fabric.util.ease
|
||||
|
|
@ -305,10 +271,41 @@
|
|||
* @namespace fabric.util.ease
|
||||
*/
|
||||
fabric.util.ease = {
|
||||
easeInQuad: easeInQuad,
|
||||
easeOutQuad: easeOutQuad,
|
||||
easeInOutQuad: easeInOutQuad,
|
||||
easeInCubic: easeInCubic,
|
||||
|
||||
/**
|
||||
* Quadratic easing in
|
||||
* @memberOf fabric.util.ease
|
||||
*/
|
||||
easeInQuad: function(t, b, c, d) {
|
||||
return c*(t/=d)*t + b;
|
||||
},
|
||||
|
||||
/**
|
||||
* Quadratic easing out
|
||||
* @memberOf fabric.util.ease
|
||||
*/
|
||||
easeOutQuad: function(t, b, c, d) {
|
||||
return -c *(t/=d)*(t-2) + b;
|
||||
},
|
||||
|
||||
/**
|
||||
* Quadratic easing in and out
|
||||
* @memberOf fabric.util.ease
|
||||
*/
|
||||
easeInOutQuad: function(t, b, c, d) {
|
||||
t /= (d/2);
|
||||
if (t < 1) return c/2*t*t + b;
|
||||
return -c/2 * ((--t)*(t-2) - 1) + b;
|
||||
},
|
||||
|
||||
/**
|
||||
* Cubic easing in
|
||||
* @memberOf fabric.util.ease
|
||||
*/
|
||||
easeInCubic: function(t, b, c, d) {
|
||||
return c*(t/=d)*t*t + b;
|
||||
},
|
||||
|
||||
easeOutCubic: easeOutCubic,
|
||||
easeInOutCubic: easeInOutCubic,
|
||||
easeInQuart: easeInQuart,
|
||||
|
|
|
|||
137
src/util/arc.js
Normal file
137
src/util/arc.js
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
(function() {
|
||||
|
||||
var arcToSegmentsCache = { },
|
||||
segmentToBezierCache = { },
|
||||
_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);
|
||||
|
||||
if (arcToSegmentsCache[argsString]) {
|
||||
return arcToSegmentsCache[argsString];
|
||||
}
|
||||
|
||||
var coords = getXYCoords(rotateX, rx, ry, ox, oy, x, y);
|
||||
|
||||
var d = (coords.x1-coords.x0) * (coords.x1-coords.x0) +
|
||||
(coords.y1-coords.y0) * (coords.y1-coords.y0);
|
||||
|
||||
var sfactor_sq = 1 / d - 0.25;
|
||||
if (sfactor_sq < 0) sfactor_sq = 0;
|
||||
|
||||
var sfactor = Math.sqrt(sfactor_sq);
|
||||
if (sweep === large) sfactor = -sfactor;
|
||||
|
||||
var xc = 0.5 * (coords.x0 + coords.x1) - sfactor * (coords.y1-coords.y0);
|
||||
var yc = 0.5 * (coords.y0 + coords.y1) + sfactor * (coords.x1-coords.x0);
|
||||
|
||||
var th0 = Math.atan2(coords.y0-yc, coords.x0-xc);
|
||||
var th1 = Math.atan2(coords.y1-yc, coords.x1-xc);
|
||||
|
||||
var th_arc = th1-th0;
|
||||
if (th_arc < 0 && sweep === 1) {
|
||||
th_arc += 2*Math.PI;
|
||||
}
|
||||
else if (th_arc > 0 && sweep === 0) {
|
||||
th_arc -= 2 * Math.PI;
|
||||
}
|
||||
|
||||
var segments = Math.ceil(Math.abs(th_arc / (Math.PI * 0.5 + 0.001)));
|
||||
var result = [];
|
||||
for (var i=0; i<segments; i++) {
|
||||
var th2 = th0 + i * th_arc / segments;
|
||||
var th3 = th0 + (i+1) * th_arc / segments;
|
||||
result[i] = [xc, yc, th2, th3, rx, ry, coords.sin_th, coords.cos_th];
|
||||
}
|
||||
|
||||
arcToSegmentsCache[argsString] = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getXYCoords(rotateX, rx, ry, ox, oy, x, y) {
|
||||
|
||||
var th = rotateX * (Math.PI/180);
|
||||
var sin_th = Math.sin(th);
|
||||
var cos_th = Math.cos(th);
|
||||
rx = Math.abs(rx);
|
||||
ry = Math.abs(ry);
|
||||
var px = cos_th * (ox - x) * 0.5 + sin_th * (oy - y) * 0.5;
|
||||
var py = cos_th * (oy - y) * 0.5 - sin_th * (ox - x) * 0.5;
|
||||
var pl = (px*px) / (rx*rx) + (py*py) / (ry*ry);
|
||||
if (pl > 1) {
|
||||
pl = Math.sqrt(pl);
|
||||
rx *= pl;
|
||||
ry *= pl;
|
||||
}
|
||||
|
||||
var a00 = cos_th / rx;
|
||||
var a01 = sin_th / rx;
|
||||
var a10 = (-sin_th) / ry;
|
||||
var a11 = (cos_th) / ry;
|
||||
|
||||
return {
|
||||
x0: a00 * ox + a01 * oy,
|
||||
y0: a10 * ox + a11 * oy,
|
||||
x1: a00 * x + a01 * y,
|
||||
y1: a10 * x + a11 * y,
|
||||
sin_th: sin_th,
|
||||
cos_th: cos_th
|
||||
};
|
||||
}
|
||||
|
||||
function segmentToBezier(cx, cy, th0, th1, rx, ry, sin_th, cos_th) {
|
||||
argsString = _join.call(arguments);
|
||||
if (segmentToBezierCache[argsString]) {
|
||||
return segmentToBezierCache[argsString];
|
||||
}
|
||||
|
||||
var a00 = cos_th * rx;
|
||||
var a01 = -sin_th * ry;
|
||||
var a10 = sin_th * rx;
|
||||
var a11 = cos_th * ry;
|
||||
|
||||
var th_half = 0.5 * (th1 - th0);
|
||||
var t = (8/3) * Math.sin(th_half * 0.5) *
|
||||
Math.sin(th_half * 0.5) / Math.sin(th_half);
|
||||
|
||||
var x1 = cx + Math.cos(th0) - t * Math.sin(th0);
|
||||
var y1 = cy + Math.sin(th0) + t * Math.cos(th0);
|
||||
var x3 = cx + Math.cos(th1);
|
||||
var y3 = cy + Math.sin(th1);
|
||||
var x2 = x3 + t * Math.sin(th1);
|
||||
var y2 = y3 - t * Math.cos(th1);
|
||||
|
||||
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[argsString];
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws arc
|
||||
* @param {CanvasRenderingContext2D} ctx
|
||||
* @param {Number} x
|
||||
* @param {Number} y
|
||||
* @param {Array} coords
|
||||
*/
|
||||
fabric.util.drawArc = function(ctx, x, y, coords) {
|
||||
var rx = coords[0];
|
||||
var ry = coords[1];
|
||||
var rot = coords[2];
|
||||
var large = coords[3];
|
||||
var sweep = coords[4];
|
||||
var ex = coords[5];
|
||||
var ey = coords[6];
|
||||
var segs = arcToSegments(ex, ey, rx, ry, large, sweep, rot, x, y);
|
||||
for (var i=0; i<segs.length; i++) {
|
||||
var bez = segmentToBezier.apply(this, segs[i]);
|
||||
ctx.bezierCurveTo.apply(ctx, bez);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
|
@ -30,12 +30,14 @@ function camelize(string) {
|
|||
* Capitalizes a string
|
||||
* @memberOf fabric.util.string
|
||||
* @param {String} string String to capitalize
|
||||
* @param {Boolean} [firstLetterOnly] If true only first letter is capitalized and other letters stay untouched,
|
||||
* if false first letter is capitalized and other letters are converted to lowercase.
|
||||
* @param {Boolean} [firstLetterOnly] If true only first letter is capitalized
|
||||
* and other letters stay untouched, if false first letter is capitalized
|
||||
* and other letters are converted to lowercase.
|
||||
* @return {String} Capitalized version of a string
|
||||
*/
|
||||
function capitalize(string, firstLetterOnly) {
|
||||
return string.charAt(0).toUpperCase() + (firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase());
|
||||
return string.charAt(0).toUpperCase() +
|
||||
(firstLetterOnly ? string.slice(1) : string.slice(1).toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
983
src/util/misc.js
983
src/util/misc.js
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue