mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-03-17 06:20:24 +00:00
* various small svg fixes * no debugger * fontsize parsing fix - again * added a visual test * use min 9px * added comment
134 lines
4 KiB
JavaScript
134 lines
4 KiB
JavaScript
fabric.ElementsParser = function(elements, callback, options, reviver, parsingOptions) {
|
|
this.elements = elements;
|
|
this.callback = callback;
|
|
this.options = options;
|
|
this.reviver = reviver;
|
|
this.svgUid = (options && options.svgUid) || 0;
|
|
this.parsingOptions = parsingOptions;
|
|
this.regexUrl = /^url\(['"]?#([^'"]+)['"]?\)/g;
|
|
};
|
|
|
|
(function(proto) {
|
|
proto.parse = function() {
|
|
this.instances = new Array(this.elements.length);
|
|
this.numElements = this.elements.length;
|
|
this.createObjects();
|
|
};
|
|
|
|
proto.createObjects = function() {
|
|
var _this = this;
|
|
this.elements.forEach(function(element, i) {
|
|
element.setAttribute('svgUid', _this.svgUid);
|
|
_this.createObject(element, i);
|
|
});
|
|
};
|
|
|
|
proto.findTag = function(el) {
|
|
return fabric[fabric.util.string.capitalize(el.tagName.replace('svg:', ''))];
|
|
};
|
|
|
|
proto.createObject = function(el, index) {
|
|
var klass = this.findTag(el);
|
|
if (klass && klass.fromElement) {
|
|
try {
|
|
klass.fromElement(el, this.createCallback(index, el), this.options);
|
|
}
|
|
catch (err) {
|
|
fabric.log(err);
|
|
}
|
|
}
|
|
else {
|
|
this.checkIfDone();
|
|
}
|
|
};
|
|
|
|
proto.createCallback = function(index, el) {
|
|
var _this = this;
|
|
return function(obj) {
|
|
var _options;
|
|
_this.resolveGradient(obj, 'fill');
|
|
_this.resolveGradient(obj, 'stroke');
|
|
if (obj instanceof fabric.Image && obj._originalElement) {
|
|
_options = obj.parsePreserveAspectRatioAttribute(el);
|
|
}
|
|
obj._removeTransformMatrix(_options);
|
|
_this.resolveClipPath(obj);
|
|
_this.reviver && _this.reviver(el, obj);
|
|
_this.instances[index] = obj;
|
|
_this.checkIfDone();
|
|
};
|
|
};
|
|
|
|
proto.extractPropertyDefinition = function(obj, property, storage) {
|
|
var value = obj[property];
|
|
if (!(/^url\(/).test(value)) {
|
|
return;
|
|
}
|
|
var id = this.regexUrl.exec(value)[1];
|
|
this.regexUrl.lastIndex = 0;
|
|
return fabric[storage][this.svgUid][id];
|
|
};
|
|
|
|
proto.resolveGradient = function(obj, property) {
|
|
var gradientDef = this.extractPropertyDefinition(obj, property, 'gradientDefs');
|
|
if (gradientDef) {
|
|
obj.set(property, fabric.Gradient.fromElement(gradientDef, obj));
|
|
}
|
|
};
|
|
|
|
proto.createClipPathCallback = function(obj, container) {
|
|
return function(_newObj) {
|
|
_newObj._removeTransformMatrix();
|
|
_newObj.fillRule = _newObj.clipRule;
|
|
container.push(_newObj);
|
|
};
|
|
};
|
|
|
|
proto.resolveClipPath = function(obj) {
|
|
var clipPath = this.extractPropertyDefinition(obj, 'clipPath', 'clipPaths'),
|
|
element, klass, objTransformInv, container, gTransform, options;
|
|
if (clipPath) {
|
|
container = [];
|
|
objTransformInv = fabric.util.invertTransform(obj.calcTransformMatrix());
|
|
for (var i = 0; i < clipPath.length; i++) {
|
|
element = clipPath[i];
|
|
klass = this.findTag(element);
|
|
klass.fromElement(
|
|
element,
|
|
this.createClipPathCallback(obj, container),
|
|
this.options
|
|
);
|
|
}
|
|
if (container.length === 1) {
|
|
clipPath = container[0];
|
|
}
|
|
else {
|
|
clipPath = new fabric.Group(container);
|
|
}
|
|
gTransform = fabric.util.multiplyTransformMatrices(
|
|
objTransformInv,
|
|
clipPath.calcTransformMatrix()
|
|
);
|
|
var options = fabric.util.qrDecompose(gTransform);
|
|
clipPath.flipX = false;
|
|
clipPath.flipY = false;
|
|
clipPath.set('scaleX', options.scaleX);
|
|
clipPath.set('scaleY', options.scaleY);
|
|
clipPath.angle = options.angle;
|
|
clipPath.skewX = options.skewX;
|
|
clipPath.skewY = 0;
|
|
clipPath.setPositionByOrigin({ x: options.translateX, y: options.translateY }, 'center', 'center');
|
|
obj.clipPath = clipPath;
|
|
}
|
|
};
|
|
|
|
proto.checkIfDone = function() {
|
|
if (--this.numElements === 0) {
|
|
this.instances = this.instances.filter(function(el) {
|
|
// eslint-disable-next-line no-eq-null, eqeqeq
|
|
return el != null;
|
|
});
|
|
this.callback(this.instances, this.elements);
|
|
}
|
|
};
|
|
})(fabric.ElementsParser.prototype);
|