fix issue with mixing transform with path commands
Fixes this case: var ctx = new C2S() ctx.save() ctx.translate(10, 10) ctx.fillStyle = 'red' ctx.fillRect(0, 0, 10, 10) ctx.fillStyle = 'blue' ctx.fillRect(10, 0, 10, 10) ctx.fillStyle = 'green' ctx.fillRect(20, 0, 10, 10) ctx.fillStyle = 'pink' ctx.translate(10, 10); ctx.rect(0, 0, 10, 10); ctx.translate(10, 10); ctx.rect(0, 0, 100, 100); ctx.scale(2, 2) ctx.rect(100, 100, 10, 10); ctx.fill() window.open(`data:image/svg+xml;utf8,${ctx.getSerializedSvg()}`)
This commit is contained in:
parent
17a2239c37
commit
c7df7fa81e
@ -340,6 +340,16 @@
|
||||
* @private
|
||||
*/
|
||||
ctx.prototype.__applyStyleToCurrentElement = function (type) {
|
||||
var currentElement = this.__currentElement;
|
||||
var currentStyleGroup = this.__currentElementsToStyle;
|
||||
if (currentStyleGroup) {
|
||||
currentElement.setAttribute(type, "");
|
||||
currentElement = currentStyleGroup.element;
|
||||
currentStyleGroup.children.forEach(function (node) {
|
||||
node.setAttribute(type, "");
|
||||
})
|
||||
}
|
||||
|
||||
var keys = Object.keys(STYLES), i, style, value, id, regex, matches;
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
style = STYLES[keys[i]];
|
||||
@ -356,37 +366,35 @@
|
||||
this.__defs.appendChild(value.__ctx.__defs.childNodes[0]);
|
||||
}
|
||||
}
|
||||
this.__currentElement.setAttribute("fill", format("url(#{id})", {id:value.__root.getAttribute("id")}));
|
||||
currentElement.setAttribute("fill", format("url(#{id})", {id:value.__root.getAttribute("id")}));
|
||||
}
|
||||
else if (style.apply.indexOf("fill")!==-1 && value instanceof CanvasGradient) {
|
||||
//gradient
|
||||
this.__currentElement.setAttribute("fill", format("url(#{id})", {id:value.__root.getAttribute("id")}));
|
||||
currentElement.setAttribute("fill", format("url(#{id})", {id:value.__root.getAttribute("id")}));
|
||||
} else if (style.apply.indexOf(type)!==-1 && style.svg !== value) {
|
||||
if ((style.svgAttr === "stroke" || style.svgAttr === "fill") && value.indexOf("rgba") !== -1) {
|
||||
//separate alpha value, since illustrator can't handle it
|
||||
regex = /rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d?\.?\d*)\s*\)/gi;
|
||||
matches = regex.exec(value);
|
||||
this.__currentElement.setAttribute(style.svgAttr, format("rgb({r},{g},{b})", {r:matches[1], g:matches[2], b:matches[3]}));
|
||||
currentElement.setAttribute(style.svgAttr, format("rgb({r},{g},{b})", {r:matches[1], g:matches[2], b:matches[3]}));
|
||||
//should take globalAlpha here
|
||||
var opacity = matches[4];
|
||||
var globalAlpha = this.globalAlpha;
|
||||
if (globalAlpha != null) {
|
||||
opacity *= globalAlpha;
|
||||
}
|
||||
this.__currentElement.setAttribute(style.svgAttr+"-opacity", opacity);
|
||||
currentElement.setAttribute(style.svgAttr+"-opacity", opacity);
|
||||
} else {
|
||||
var attr = style.svgAttr;
|
||||
if (keys[i] === 'globalAlpha') {
|
||||
attr = type+'-'+style.svgAttr;
|
||||
if (this.__currentElement.getAttribute(attr)) {
|
||||
if (currentElement.getAttribute(attr)) {
|
||||
//fill-opacity or stroke-opacity has already been set by stroke or fill.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
//otherwise only update attribute if right type, and not svg default
|
||||
this.__currentElement.setAttribute(attr, value);
|
||||
|
||||
|
||||
currentElement.setAttribute(attr, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -462,13 +470,13 @@
|
||||
*/
|
||||
ctx.prototype.restore = function () {
|
||||
this.__currentElement = this.__groupStack.pop();
|
||||
this.__currentElementsToStyle = null;
|
||||
//Clearing canvas will make the poped group invalid, currentElement is set to the root group node.
|
||||
if (!this.__currentElement) {
|
||||
this.__currentElement = this.__root.childNodes[1];
|
||||
}
|
||||
var state = this.__stack.pop();
|
||||
this.__applyStyleState(state);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@ -479,6 +487,12 @@
|
||||
//if the current element has siblings, add another group
|
||||
var parent = this.__closestGroupOrSvg();
|
||||
if (parent.childNodes.length > 0) {
|
||||
if (this.__currentElement.nodeName === "path") {
|
||||
this.__currentElementsToStyle || (this.__currentElementsToStyle = { element: parent, children: [] });
|
||||
this.__currentElementsToStyle.children.push(this.__currentElement)
|
||||
this.__applyCurrentDefaultPath();
|
||||
}
|
||||
|
||||
var group = this.__createElement("g");
|
||||
parent.appendChild(group);
|
||||
this.__currentElement = group;
|
||||
@ -548,11 +562,11 @@
|
||||
* @private
|
||||
*/
|
||||
ctx.prototype.__applyCurrentDefaultPath = function () {
|
||||
if (this.__currentElement.nodeName === "path") {
|
||||
var d = this.__currentDefaultPath;
|
||||
this.__currentElement.setAttribute("d", d);
|
||||
var currentElement = this.__currentElement;
|
||||
if (currentElement.nodeName === "path") {
|
||||
currentElement.setAttribute("d", this.__currentDefaultPath);
|
||||
} else {
|
||||
throw new Error("Attempted to apply path command to node " + this.__currentElement.nodeName);
|
||||
console.error("Attempted to apply path command to node", currentElement.nodeName);
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user