diff --git a/src/elements_parser.js b/src/elements_parser.js
index ab2088be121..0bb377f0b9c 100644
--- a/src/elements_parser.js
+++ b/src/elements_parser.js
@@ -46,8 +46,8 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
var _this = this;
return function(obj) {
var _options;
- _this.resolveGradient(obj, 'fill');
- _this.resolveGradient(obj, 'stroke');
+ _this.resolveGradient(obj, el, 'fill');
+ _this.resolveGradient(obj, el, 'stroke');
if (obj instanceof fabric.Image && obj._originalElement) {
_options = obj.parsePreserveAspectRatioAttribute(el);
}
@@ -69,10 +69,12 @@ fabric.ElementsParser = function(elements, callback, options, reviver, parsingOp
return fabric[storage][this.svgUid][id];
};
- proto.resolveGradient = function(obj, property) {
+ proto.resolveGradient = function(obj, el, property) {
var gradientDef = this.extractPropertyDefinition(obj, property, 'gradientDefs');
if (gradientDef) {
- obj.set(property, fabric.Gradient.fromElement(gradientDef, obj));
+ var opacityAttr = el.getAttribute(property + '-opacity');
+ var gradient = fabric.Gradient.fromElement(gradientDef, obj, opacityAttr);
+ obj.set(property, gradient);
}
};
diff --git a/src/gradient.class.js b/src/gradient.class.js
index 8288fc49cf2..b3313b53e67 100644
--- a/src/gradient.class.js
+++ b/src/gradient.class.js
@@ -1,7 +1,7 @@
(function() {
/* _FROM_SVG_START_ */
- function getColorStop(el) {
+ function getColorStop(el, multiplier) {
var style = el.getAttribute('style'),
offset = el.getAttribute('offset') || 0,
color, colorAlpha, opacity, i;
@@ -41,7 +41,7 @@
color = new fabric.Color(color);
colorAlpha = color.getAlpha();
opacity = isNaN(parseFloat(opacity)) ? 1 : parseFloat(opacity);
- opacity *= colorAlpha;
+ opacity *= colorAlpha * multiplier;
return {
offset: offset,
@@ -302,11 +302,12 @@
* @memberOf fabric.Gradient
* @param {SVGGradientElement} el SVG gradient element
* @param {fabric.Object} instance
+ * @param {String} opacityAttr A fill-opacity or stroke-opacity attribute to multiply to each stop's opacity.
* @return {fabric.Gradient} Gradient instance
* @see http://www.w3.org/TR/SVG/pservers.html#LinearGradientElement
* @see http://www.w3.org/TR/SVG/pservers.html#RadialGradientElement
*/
- fromElement: function(el, instance) {
+ fromElement: function(el, instance, opacityAttr) {
/**
* @example:
*
@@ -340,6 +341,12 @@
*
*/
+ var multiplier = parseFloat(opacityAttr) / (/%$/.test(opacityAttr) ? 100 : 1);
+ multiplier = multiplier < 0 ? 0 : multiplier > 1 ? 1 : multiplier;
+ if (isNaN(multiplier)) {
+ multiplier = 1;
+ }
+
var colorStopEls = el.getElementsByTagName('stop'),
type,
gradientUnits = el.getAttribute('gradientUnits') || 'objectBoundingBox',
@@ -362,7 +369,7 @@
}
for (i = colorStopEls.length; i--; ) {
- colorStops.push(getColorStop(colorStopEls[i]));
+ colorStops.push(getColorStop(colorStopEls[i], multiplier));
}
ellipseMatrix = _convertPercentUnitsToValues(instance, coords, gradientUnits);
diff --git a/test/unit/gradient.js b/test/unit/gradient.js
index 66f97cfe6c1..7c32f1b18fe 100644
--- a/test/unit/gradient.js
+++ b/test/unit/gradient.js
@@ -209,7 +209,7 @@
element.appendChild(stop2);
var object = new fabric.Object({ width: 100, height: 100 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.ok(gradient instanceof fabric.Gradient);
@@ -250,7 +250,7 @@
element.appendChild(stop2);
var object = new fabric.Object({ width: 200, height: 200 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.ok(gradient instanceof fabric.Gradient);
@@ -283,7 +283,7 @@
element.appendChild(stop2);
var object = new fabric.Object({ width: 200, height: 200 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.ok(gradient instanceof fabric.Gradient);
@@ -315,7 +315,7 @@
element.appendChild(stop2);
var object = new fabric.Object({ width: 100, height: 100, top: 0, left: 0 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.ok(gradient instanceof fabric.Gradient);
@@ -350,7 +350,7 @@
element.appendChild(stop2);
var object = new fabric.Object({ width: 100, height: 100 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.ok(gradient instanceof fabric.Gradient);
@@ -369,13 +369,13 @@
element.setAttribute('y2', 'Infinity');
var object = new fabric.Object({ width: 200, height: 200 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.equal(gradient.coords.x1, 60);
assert.equal(gradient.coords.y1, 20);
assert.equal(gradient.coords.x2, 40);
assert.equal(gradient.coords.y2, 200);
object = new fabric.Object({ width: 200, height: 200, top: 50, left: 10 });
- gradient = fabric.Gradient.fromElement(element, object);
+ gradient = fabric.Gradient.fromElement(element, object, '');
assert.equal(gradient.coords.x1, 70);
assert.equal(gradient.coords.y1, 70);
assert.equal(gradient.coords.x2, 50);
@@ -394,7 +394,7 @@
element.setAttribute('r', '100%');
var object = new fabric.Object({ width: 200, height: 200 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.equal(gradient.coords.x1, 60, 'should change with width height');
assert.equal(gradient.coords.y1, 40, 'should change with width height');
assert.equal(gradient.coords.x2, 20, 'should change with width height');
@@ -403,7 +403,7 @@
assert.equal(gradient.coords.r2, 200, 'should change with width height');
object = new fabric.Object({ width: 200, height: 200, top: 10, left: 10 });
- gradient = fabric.Gradient.fromElement(element, object);
+ gradient = fabric.Gradient.fromElement(element, object, '');
assert.equal(gradient.coords.x1, 70, 'should change with top left');
assert.equal(gradient.coords.y1, 50, 'should change with top left');
assert.equal(gradient.coords.x2, 30, 'should change with top left');
@@ -425,7 +425,7 @@
element.setAttribute('gradientUnits', 'userSpaceOnUse');
var object = new fabric.Object({ width: 200, height: 200 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.equal(gradient.coords.x1, 30, 'should not change with width height');
assert.equal(gradient.coords.y1, 20, 'should not change with width height');
assert.equal(gradient.coords.x2, 15, 'should not change with width height');
@@ -434,7 +434,7 @@
assert.equal(gradient.coords.r2, 100, 'should not change with width height');
object = new fabric.Object({ width: 200, height: 200, top: 50, left: 60 });
- gradient = fabric.Gradient.fromElement(element, object);
+ gradient = fabric.Gradient.fromElement(element, object, '');
assert.equal(gradient.coords.x1, 30, 'should not change with top left');
assert.equal(gradient.coords.y1, 20, 'should not change with top left');
assert.equal(gradient.coords.x2, 15, 'should not change with top left');
@@ -455,14 +455,14 @@
element.setAttribute('gradientUnits', 'userSpaceOnUse');
var object = new fabric.Object({ width: 200, height: 200 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.equal(gradient.coords.x1, 30, 'should not change with width height');
assert.equal(gradient.coords.y1, 20, 'should not change with width height');
assert.equal(gradient.coords.x2, 15, 'should not change with width height');
assert.equal(gradient.coords.y2, 18, 'should not change with width height');
object = new fabric.Object({ width: 200, height: 200, top: 40, left: 40 });
- gradient = fabric.Gradient.fromElement(element, object);
+ gradient = fabric.Gradient.fromElement(element, object, '');
assert.equal(gradient.coords.x1, 30, 'should not change with top left');
assert.equal(gradient.coords.y1, 20, 'should not change with top left');
assert.equal(gradient.coords.x2, 15, 'should not change with top left');
@@ -486,7 +486,7 @@
element.appendChild(stop2);
var object = new fabric.Object({ width: 100, height: 100 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.ok(gradient instanceof fabric.Gradient);
@@ -519,7 +519,7 @@
element.appendChild(stop2);
element.setAttribute('gradientTransform', 'matrix(3.321 -0.6998 0.4077 1.9347 -440.9168 -408.0598)');
var object = new fabric.Object({ width: 100, height: 100 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.ok(gradient instanceof fabric.Gradient);
@@ -568,7 +568,7 @@
element.appendChild(stop4);
var object = new fabric.Object({ width: 100, height: 100 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.ok(gradient instanceof fabric.Gradient);
@@ -625,7 +625,7 @@
element.appendChild(stop4);
var object = new fabric.Object({ width: 100, height: 100 });
- var gradient = fabric.Gradient.fromElement(element, object);
+ var gradient = fabric.Gradient.fromElement(element, object, '');
assert.ok(gradient instanceof fabric.Gradient);
diff --git a/test/unit/parser.js b/test/unit/parser.js
index 7938d9d87f3..75bdb4138a9 100644
--- a/test/unit/parser.js
+++ b/test/unit/parser.js
@@ -451,6 +451,28 @@
});
});
+ QUnit.test('parseSVGFromString path fill-opacity with gradient', function(assert) {
+ var done = assert.async();
+ var string = '' +
+ '';
+
+ fabric.loadSVGFromString(string, function(objects) {
+ assert.equal(objects[0].fill.colorStops[0].opacity, 0.5);
+ assert.equal(objects[0].fill.colorStops[0].color, 'rgb(255,0,0)');
+ assert.equal(objects[0].fill.colorStops[1].opacity, 0.25);
+ assert.equal(objects[0].fill.colorStops[1].color, 'rgb(0,255,0)');
+ done();
+ });
+ });
+
QUnit.test('parseSVGFromString with svg:namespace', function(assert) {
var done = assert.async();
var string = '