Update gradient.class.js

This commit is contained in:
Andrea Bogazzi 2014-09-02 22:40:00 +02:00
parent cefc838e90
commit d87af17aa4

View file

@ -8,7 +8,7 @@
// convert percents to absolute values
offset = parseFloat(offset) / (/%$/.test(offset) ? 100 : 1);
offset = offset < 0 ? 0 : offset > 1 ? 1 : offset;
if (style) {
var keyValuePairs = style.split(/\s*;\s*/);
@ -78,19 +78,20 @@
* @see {@link fabric.Gradient#initialize} for constructor definition
*/
fabric.Gradient = fabric.util.createClass(/** @lends fabric.Gradient.prototype */ {
/*
* Stores the original position of the gradient when we convert from % to fixed values, for objectBoundingBox case.
* @type Number
* @default 0
*/
origX: 0,
/*
* Stores the original position of the gradient when we convert from % to fixed values, for objectBoundingBox case.
/**
* Horizontal offset for aligning gradients coming from SVG when outside pathgroups
* @type Number
* @default 0
*/
origY: 0,
offsetX : 0,
/**
* Vertical offset for aligning gradients coming from SVG when outside pathgroups
* @type Number
* @default 0
*/
offsetY : 0,
/**
* Constructor
@ -116,15 +117,13 @@
coords.r1 = options.coords.r1 || 0;
coords.r2 = options.coords.r2 || 0;
}
this.coords = coords;
this.gradientUnits = options.gradientUnits || 'objectBoundingBox';
this.colorStops = options.colorStops.slice();
if (options.gradientTransform) {
this.gradientTransform = options.gradientTransform;
}
this.origX = options.left || this.origX;
this.origY = options.top || this.origY;
this.offsetX = options.offsetX || this.offsetX;
this.offsetY = options.offsetY || this.offsetY;
},
/**
@ -152,8 +151,9 @@
return {
type: this.type,
coords: this.coords,
gradientUnits: this.gradientUnits,
colorStops: this.colorStops
colorStops: this.colorStops,
offsetX: this.offsetX,
offsetY: this.offsetY
};
},
@ -164,7 +164,7 @@
* @param {Boolean} normalize Whether coords should be normalized
* @return {String} SVG representation of an gradient (linear/radial)
*/
toSVG: function(object, normalize) {
toSVG: function(object) {
var coords = fabric.util.object.clone(this.coords),
markup, commonAttributes;
@ -172,20 +172,22 @@
this.colorStops.sort(function(a, b) {
return a.offset - b.offset;
});
if (normalize && this.gradientUnits === 'userSpaceOnUse') {
coords.x1 += object.width / 2;
coords.y1 += object.height / 2;
coords.x2 += object.width / 2;
coords.y2 += object.height / 2;
if (!(object.group && object.group.type === 'path-group')) {
for (var prop in coords) {
if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
coords[prop] += this.offsetX - object.width / 2;
}
else if (prop === 'y1' || prop === 'y2') {
coords[prop] += this.offsetY - object.height / 2;
}
}
}
else if (this.gradientUnits === 'objectBoundingBox') {
_convertValuesToPercentUnits(object, coords);
}
commonAttributes = 'id="SVGID_' + this.id +
'" gradientUnits="' + this.gradientUnits + '"';
commonAttributes = 'id="SVGID_' + this.id +
'" gradientUnits="userSpaceOnUse"';
if (this.gradientTransform) {
commonAttributes += ' gradientTransform="matrix(' + this.gradientTransform.join(' ') + ')" ';
commonAttributes += ' gradientTransform="matrix(' + this.gradientTransform.join(' ') + ')" ';
}
if (this.type === 'linear') {
markup = [
@ -322,7 +324,7 @@
gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox',
gradientTransform = el.getAttribute('gradientTransform'),
colorStops = [],
coords = { };
coords = { }, ellipseMatrix;
if (type === 'linear') {
coords = getLinearCoords(el);
@ -335,19 +337,19 @@
colorStops.push(getColorStop(colorStopEls[i]));
}
_convertPercentUnitsToValues(instance, coords);
ellipseMatrix = _convertPercentUnitsToValues(instance, coords, gradientUnits);
var gradient = new fabric.Gradient({
type: type,
coords: coords,
gradientUnits: gradientUnits,
colorStops: colorStops
colorStops: colorStops,
offsetX: -instance.left,
offsetY: -instance.top
});
if (gradientTransform) {
gradient.gradientTransform = fabric.parseTransformAttribute(gradientTransform);
if (gradientTransform || ellipseMatrix !== '') {
gradient.gradientTransform = fabric.parseTransformAttribute((gradientTransform || '') + ellipseMatrix);
}
return gradient;
},
/* _FROM_SVG_END_ */
@ -361,7 +363,7 @@
*/
forObject: function(obj, options) {
options || (options = { });
_convertPercentUnitsToValues(obj, options);
_convertPercentUnitsToValues(obj, options.coords, 'userSpaceOnUse');
return new fabric.Gradient(options);
}
});
@ -369,35 +371,35 @@
/**
* @private
*/
function _convertPercentUnitsToValues(object, options) {
function _convertPercentUnitsToValues(object, options, gradientUnits) {
var propValue, addFactor = 0, multFactor = 1, ellipseMatrix = '';
for (var prop in options) {
propValue = parseFloat(options[prop], 10);
if (typeof options[prop] === 'string' && /^\d+%$/.test(options[prop])) {
var percents = parseFloat(options[prop], 10);
if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
options[prop] = fabric.util.toFixed(object.width * percents / 100, 2) + object.left;
}
else if (prop === 'y1' || prop === 'y2') {
options[prop] = fabric.util.toFixed(object.height * percents / 100, 2) + object.top;
}
multFactor = 0.01;
} else {
multFactor = 1;
}
}
}
/* _TO_SVG_START_ */
/**
* @private
*/
function _convertValuesToPercentUnits(object, options) {
for (var prop in options) {
//convert to percent units
if (prop === 'x1' || prop === 'x2' || prop === 'r2') {
options[prop] = fabric.util.toFixed((options[prop] - object.fill.origX) / object.width * 100, 2) + '%';
multFactor *= gradientUnits === 'objectBoundingBox' ? object.width : 1;
addFactor = gradientUnits === 'objectBoundingBox' ? object.left || 0 : 0;
}
else if (prop === 'y1' || prop === 'y2') {
options[prop] = fabric.util.toFixed((options[prop] - object.fill.origY) / object.height * 100, 2) + '%';
multFactor *= gradientUnits === 'objectBoundingBox' ? object.height : 1;
addFactor = gradientUnits === 'objectBoundingBox' ? object.top || 0 : 0;
}
options[prop] = propValue * multFactor + addFactor;
}
if (object.type === 'ellipse' && options['r2'] !== null && gradientUnits === 'objectBoundingBox' && object.rx !== object.ry) {
var scaleFactor = object.ry/object.rx;
ellipseMatrix = ' scale(1, ' + scaleFactor + ')';
if (options['y1']) {
options['y1'] /= scaleFactor;
}
if (options['y2']) {
options['y2'] /= scaleFactor;
}
}
return ellipseMatrix;
}
/* _TO_SVG_END_ */
})();