From 14e37d734c0e8d9c1190e58955a7d70ea7d60de1 Mon Sep 17 00:00:00 2001 From: fuzhen Date: Wed, 16 Dec 2015 13:19:05 +0800 Subject: [PATCH 1/5] replace image.getAttribute("src") with image.src. --- canvas2svg.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/canvas2svg.js b/canvas2svg.js index 1d790bc..28e125f 100644 --- a/canvas2svg.js +++ b/canvas2svg.js @@ -1077,7 +1077,7 @@ } svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", - image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src")); + image.nodeName === "CANVAS" ? image.toDataURL() : image.src); parent.appendChild(svgImage); this.__currentElement = svgImage; this.translate(dx, dy); @@ -1099,7 +1099,7 @@ img.setAttribute("width", image.width); img.setAttribute("height", image.height); img.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", - image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src")); + image.nodeName === "CANVAS" ? image.toDataURL() : image.src); pattern.appendChild(img); this.__defs.appendChild(pattern); } else if(image instanceof ctx) { @@ -1108,7 +1108,7 @@ } return new CanvasPattern(pattern, this); }; - + ctx.prototype.setLineDash = function(dashArray) { if (dashArray && dashArray.length > 0) { this.lineDash = dashArray.join(","); @@ -1116,7 +1116,7 @@ this.lineDash = null; } }; - + /** * Not yet implemented */ @@ -1126,7 +1126,7 @@ ctx.prototype.putImageData = function(){}; ctx.prototype.globalCompositeOperation = function(){}; ctx.prototype.setTransform = function(){}; - + //add options for alternative namespace if (typeof window === "object") { window.C2S = ctx; From d2e840c0774a3537f3a634e36b8a4718641a850a Mon Sep 17 00:00:00 2001 From: fuzhen Date: Thu, 17 Dec 2015 01:20:29 +0800 Subject: [PATCH 2/5] fix a bug that image is not translated to (dx, dy) when ctx.drawImage(img, dx, dy) --- canvas2svg.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/canvas2svg.js b/canvas2svg.js index 28e125f..8df3fc0 100644 --- a/canvas2svg.js +++ b/canvas2svg.js @@ -1075,13 +1075,10 @@ context.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh); image = canvas; } - + svgImage.setAttribute("transform",["translate(",dx,",",dy,")"].join("")); svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", image.nodeName === "CANVAS" ? image.toDataURL() : image.src); parent.appendChild(svgImage); - this.__currentElement = svgImage; - this.translate(dx, dy); - this.__currentElement = currentElement; } }; From 170b8c574d20a85013c339c74a781b41a46efcbf Mon Sep 17 00:00:00 2001 From: fuzhen Date: Thu, 17 Dec 2015 02:12:48 +0800 Subject: [PATCH 3/5] 1. clear entire canvas when clearRect(0,0, canvas.width, canvas.height), this removes unnecessary white rects generated by clearRect when clearing canvas. 2. clone child SVG node at first before drawImage(c2s, x, y) to prevent unwanted updates by parent C2S context. --- canvas2svg.js | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/canvas2svg.js b/canvas2svg.js index 8df3fc0..77f2897 100644 --- a/canvas2svg.js +++ b/canvas2svg.js @@ -776,10 +776,38 @@ }; + /** + * Clear entire canvas: + * 1. save current transforms + * 2. remove all the childNodes of the root g element + */ + ctx.prototype.__clearCanvas = function() { + var current = this.__closestGroupOrSvg(), + transform = current.getAttribute("transform"); + var rootGroup = this.__root.childNodes[1]; + var childNodes = rootGroup.childNodes; + for (var i = childNodes.length - 1; i >= 0; i--) { + if (childNodes[i]) { + rootGroup.removeChild(childNodes[i]); + } + } + this.__currentElement = rootGroup; + this.__stack = [this.__getStyleState()]; + this.__groupStack = []; + if (transform) { + this.__addTransform(transform); + } + }; + /** * "Clears" a canvas by just drawing a white rectangle in the current group. */ ctx.prototype.clearRect = function(x, y, width, height) { + //clear entire canvas + if (x === 0 && y === 0 && width === this.width && height === this.height) { + this.__clearCanvas(); + return; + } var rect, parent = this.__closestGroupOrSvg(); rect = this.__createElement("rect", { x : x, @@ -1043,7 +1071,7 @@ if(image instanceof ctx) { //canvas2svg mock canvas context. In the future we may want to clone nodes instead. //also I'm currently ignoring dw, dh, sw, sh, sx, sy for a mock context. - svg = image.getSvg(); + svg = image.getSvg().cloneNode(true); if (svg.childNodes && svg.childNodes.length > 1) { defs = svg.childNodes[0]; while(defs.childNodes.length) { @@ -1053,10 +1081,8 @@ } group = svg.childNodes[1]; if (group) { + group.setAttribute("transform",["translate(",dx,",",dy,")"].join("")); parent.appendChild(group); - this.__currentElement = group; - this.translate(dx, dy); - this.__currentElement = currentElement; } } } else if(image.nodeName === "CANVAS" || image.nodeName === "IMG") { From ef3ab241e6a7112a57e2dfd2d7f1948d0ba9022e Mon Sep 17 00:00:00 2001 From: fuzhen Date: Thu, 17 Dec 2015 12:52:13 +0800 Subject: [PATCH 4/5] reset stacks when clearing canvas --- canvas2svg.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/canvas2svg.js b/canvas2svg.js index 77f2897..4499fd4 100644 --- a/canvas2svg.js +++ b/canvas2svg.js @@ -447,6 +447,10 @@ */ ctx.prototype.restore = function(){ this.__currentElement = this.__groupStack.pop(); + //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); @@ -792,7 +796,7 @@ } } this.__currentElement = rootGroup; - this.__stack = [this.__getStyleState()]; + //reset __groupStack as all the child group nodes are all removed. this.__groupStack = []; if (transform) { this.__addTransform(transform); From 9dc92b79aae169d5daa43465468ea1371c81f84d Mon Sep 17 00:00:00 2001 From: fuzhen Date: Fri, 18 Dec 2015 09:59:13 +0800 Subject: [PATCH 5/5] 1. move back to image.getAttribute("src") 2. save the original transform of C2S context in drawImage --- canvas2svg.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/canvas2svg.js b/canvas2svg.js index 4499fd4..e34309a 100644 --- a/canvas2svg.js +++ b/canvas2svg.js @@ -1071,7 +1071,7 @@ parent = this.__closestGroupOrSvg(); currentElement = this.__currentElement; - + var translateDirective = "translate(" + dx + ", " + dy + ")"; if(image instanceof ctx) { //canvas2svg mock canvas context. In the future we may want to clone nodes instead. //also I'm currently ignoring dw, dh, sw, sh, sx, sy for a mock context. @@ -1085,7 +1085,15 @@ } group = svg.childNodes[1]; if (group) { - group.setAttribute("transform",["translate(",dx,",",dy,")"].join("")); + //save original transform + var originTransform = group.getAttribute("transform"); + var transformDirective; + if (originTransform) { + transformDirective = originTransform+" "+translateDirective; + } else { + transformDirective = translateDirective; + } + group.setAttribute("transform", transformDirective); parent.appendChild(group); } } @@ -1105,9 +1113,9 @@ context.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh); image = canvas; } - svgImage.setAttribute("transform",["translate(",dx,",",dy,")"].join("")); + svgImage.setAttribute("transform", translateDirective); svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", - image.nodeName === "CANVAS" ? image.toDataURL() : image.src); + image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src")); parent.appendChild(svgImage); } }; @@ -1126,7 +1134,7 @@ img.setAttribute("width", image.width); img.setAttribute("height", image.height); img.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", - image.nodeName === "CANVAS" ? image.toDataURL() : image.src); + image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src")); pattern.appendChild(img); this.__defs.appendChild(pattern); } else if(image instanceof ctx) {