feat: respect transformation matrix in clearRect and drawImage

This commit is contained in:
Zeno Zeng 2021-06-05 13:22:53 +08:00
parent 3703af4632
commit 91d06bff2e

View File

@ -348,8 +348,8 @@
/** /**
* @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform
*/ */
ctx.prototype.__applyTransformation = function (element) { ctx.prototype.__applyTransformation = function (element, matrix) {
const {a, b, c, d, e, f} = this.getTransform(); const {a, b, c, d, e, f} = matrix || this.getTransform();
element.setAttribute('transform', `matrix(${a} ${b} ${c} ${d} ${e} ${f})`) element.setAttribute('transform', `matrix(${a} ${b} ${c} ${d} ${e} ${f})`)
} }
@ -813,10 +813,13 @@
* "Clears" a canvas by just drawing a white rectangle in the current group. * "Clears" a canvas by just drawing a white rectangle in the current group.
*/ */
ctx.prototype.clearRect = function (x, y, width, height) { ctx.prototype.clearRect = function (x, y, width, height) {
//clear entire canvas let {a, b, c, d, e, f} = this.getTransform();
if (x === 0 && y === 0 && width === this.width && height === this.height) { if (JSON.stringify([a, b, c, d, e, f]) === JSON.stringify([1, 0, 0, 1, 0, 0])) {
this.__clearCanvas(); //clear entire canvas
return; if (x === 0 && y === 0 && width === this.width && height === this.height) {
this.__clearCanvas();
return;
}
} }
var rect, parent = this.__closestGroupOrSvg(); var rect, parent = this.__closestGroupOrSvg();
rect = this.__createElement("rect", { rect = this.__createElement("rect", {
@ -1088,7 +1091,7 @@
parent = this.__closestGroupOrSvg(); parent = this.__closestGroupOrSvg();
currentElement = this.__currentElement; currentElement = this.__currentElement;
var translateDirective = "translate(" + dx + ", " + dy + ")"; const matrix = this.getTransform().translate(dx, dy);
if (image instanceof ctx) { if (image instanceof ctx) {
//canvas2svg mock canvas context. In the future we may want to clone nodes instead. //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. //also I'm currently ignoring dw, dh, sw, sh, sx, sy for a mock context.
@ -1102,15 +1105,7 @@
} }
group = svg.childNodes[1]; group = svg.childNodes[1];
if (group) { if (group) {
//save original transform this.__applyTransformation(group, matrix);
var originTransform = group.getAttribute("transform");
var transformDirective;
if (originTransform) {
transformDirective = originTransform+" "+translateDirective;
} else {
transformDirective = translateDirective;
}
group.setAttribute("transform", transformDirective);
parent.appendChild(group); parent.appendChild(group);
} }
} }
@ -1130,7 +1125,7 @@
context.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh); context.drawImage(image, sx, sy, sw, sh, 0, 0, dw, dh);
image = canvas; image = canvas;
} }
svgImage.setAttribute("transform", translateDirective); this.__applyTransformation(svgImage, matrix);
svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", svgImage.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href",
image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src")); image.nodeName === "CANVAS" ? image.toDataURL() : image.getAttribute("src"));
parent.appendChild(svgImage); parent.appendChild(svgImage);