Gradient fix parsing floats (#4637)

* fixed gradient parsing and circle width/height leak

* added a small test

* fix lint

* test re enabled

* fixed tests
This commit is contained in:
Andrea Bogazzi 2018-01-20 01:09:47 +01:00 committed by GitHub
parent f5ee274052
commit 43ebcd8278
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 15 deletions

View file

@ -413,7 +413,7 @@
options[prop] = 0;
}
propValue = parseFloat(options[prop], 10);
if (typeof options[prop] === 'string' && /^\d+%$/.test(options[prop])) {
if (typeof options[prop] === 'string' && /^(\d+\.\d+)%|(\d+)%$/.test(options[prop])) {
multFactor = 0.01;
}
else {

View file

@ -3,8 +3,7 @@
'use strict';
var fabric = global.fabric || (global.fabric = { }),
pi = Math.PI,
extend = fabric.util.object.extend;
pi = Math.PI;
if (fabric.Circle) {
fabric.warn('fabric.Circle is already defined.');
@ -174,13 +173,11 @@
* @static
* @memberOf fabric.Circle
* @param {SVGElement} element Element to parse
* @param {Object} [options] Options object
* @param {Function} [callback] Options callback invoked after parsing is finished
* @param {Object} [options] Options object
* @throws {Error} If value of `r` attribute is missing or invalid
*/
fabric.Circle.fromElement = function(element, callback, options) {
options || (options = { });
fabric.Circle.fromElement = function(element, callback) {
var parsedAttributes = fabric.parseAttributes(element, fabric.Circle.ATTRIBUTE_NAMES);
if (!isValidRadius(parsedAttributes)) {
@ -189,7 +186,7 @@
parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.radius;
parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.radius;
callback(new fabric.Circle(extend(parsedAttributes, options)));
callback(new fabric.Circle(parsedAttributes));
};
/**

View file

@ -3,8 +3,7 @@
'use strict';
var fabric = global.fabric || (global.fabric = { }),
piBy2 = Math.PI * 2,
extend = fabric.util.object.extend;
piBy2 = Math.PI * 2;
if (fabric.Ellipse) {
fabric.warn('fabric.Ellipse is already defined.');
@ -161,18 +160,16 @@
* @static
* @memberOf fabric.Ellipse
* @param {SVGElement} element Element to parse
* @param {Object} [options] Options object
* @param {Function} [callback] Options callback invoked after parsing is finished
* @return {fabric.Ellipse}
*/
fabric.Ellipse.fromElement = function(element, callback, options) {
options || (options = { });
fabric.Ellipse.fromElement = function(element, callback) {
var parsedAttributes = fabric.parseAttributes(element, fabric.Ellipse.ATTRIBUTE_NAMES);
parsedAttributes.left = (parsedAttributes.left || 0) - parsedAttributes.rx;
parsedAttributes.top = (parsedAttributes.top || 0) - parsedAttributes.ry;
callback(new fabric.Ellipse(extend(parsedAttributes, options)));
callback(new fabric.Ellipse(parsedAttributes));
};
/* _FROM_SVG_END_ */

View file

@ -47,7 +47,7 @@ testrunner.run({
'./test/unit/intersection.js',
'./test/unit/stateful.js'
],
tests: ['./test/unit/pattern.js'],
// tests: ['./test/unit/pattern.js'],
}, function(err, report) {
if (err) {
console.log(err);

View file

@ -77,6 +77,7 @@
var SVG_INTERNALRADIUS = '<radialGradient id="SVGID_0" gradientUnits="userSpaceOnUse" cx="50" cy="150" r="50" fx="-50" fy="-40">\n<stop offset="20%" style="stop-color:red;stop-opacity: undefined"/>\n<stop offset="100%" style="stop-color:green;stop-opacity: 0"/>\n</radialGradient>\n';
var SVG_SWAPPED = '<radialGradient id="SVGID_0" gradientUnits="userSpaceOnUse" cx="-50" cy="-40" r="50" fx="50" fy="150">\n<stop offset="20%" style="stop-color:green;stop-opacity: 0"/>\n<stop offset="100%" style="stop-color:red;stop-opacity: undefined"/>\n</radialGradient>\n';
QUnit.test('constructor linearGradient', function(assert) {
assert.ok(fabric.Gradient);
@ -226,6 +227,72 @@
assert.equal(gradient.colorStops[0].opacity, 0);
});
QUnit.test('fromElement linearGradient with floats percentage - objectBoundingBox', function(assert) {
assert.ok(typeof fabric.Gradient.fromElement === 'function');
var element = fabric.document.createElement('linearGradient');
element.setAttribute('gradientUnits', 'objectBoundingBox');
element.setAttribute('x1', '10%');
element.setAttribute('y1', '0.2%');
element.setAttribute('x2', '200');
element.setAttribute('y2', '20%');
var stop1 = fabric.document.createElement('stop');
var stop2 = fabric.document.createElement('stop');
stop1.setAttribute('offset', '0%');
stop1.setAttribute('stop-color', 'white');
stop2.setAttribute('offset', '100%');
stop2.setAttribute('stop-color', 'black');
stop2.setAttribute('stop-opacity', '0');
element.appendChild(stop1);
element.appendChild(stop2);
var object = new fabric.Object({ width: 200, height: 200 });
var gradient = fabric.Gradient.fromElement(element, object);
assert.ok(gradient instanceof fabric.Gradient);
assert.equal(gradient.coords.x1, 20);
assert.equal(gradient.coords.y1, 0.4);
assert.equal(gradient.coords.x2, 40000);
assert.equal(gradient.coords.y2, 40);
});
QUnit.test('fromElement linearGradient with floats percentage - userSpaceOnUse', function(assert) {
assert.ok(typeof fabric.Gradient.fromElement === 'function');
var element = fabric.document.createElement('linearGradient');
element.setAttribute('gradientUnits', 'userSpaceOnUse');
element.setAttribute('x1', '10%');
element.setAttribute('y1', '0.2%');
element.setAttribute('x2', '200');
element.setAttribute('y2', '20%');
var stop1 = fabric.document.createElement('stop');
var stop2 = fabric.document.createElement('stop');
stop1.setAttribute('offset', '0%');
stop1.setAttribute('stop-color', 'white');
stop2.setAttribute('offset', '100%');
stop2.setAttribute('stop-color', 'black');
stop2.setAttribute('stop-opacity', '0');
element.appendChild(stop1);
element.appendChild(stop2);
var object = new fabric.Object({ width: 200, height: 200 });
var gradient = fabric.Gradient.fromElement(element, object);
assert.ok(gradient instanceof fabric.Gradient);
assert.equal(gradient.coords.x1, 0.1);
assert.equal(gradient.coords.y1, 0.002);
assert.equal(gradient.coords.x2, 200);
assert.equal(gradient.coords.y2, 0.2);
});
QUnit.test('fromElement linearGradient with Infinity', function(assert) {
assert.ok(typeof fabric.Gradient.fromElement === 'function');