Fix adding CanvasPattern

The current code was going into an infinite loop
It's also setting `patternUnits` to `userSpaceOnUse` in order to get the same behaviour as canvas patterns
This commit is contained in:
Xavier Delamotte 2021-11-10 16:48:00 +00:00
parent 218b3d3a5b
commit f8d0aa06c0
4 changed files with 55 additions and 19 deletions

View File

@ -371,7 +371,7 @@ export default (function () {
})
}
var keys = Object.keys(STYLES), i, style, value, id, regex, matches;
var keys = Object.keys(STYLES), i, style, value, regex, matches, id, nodeIndex, node;
for (i = 0; i < keys.length; i++) {
style = STYLES[keys[i]];
value = this[keys[i]];
@ -381,10 +381,11 @@ export default (function () {
//pattern
if (value.__ctx) {
//copy over defs
while(value.__ctx.__defs.childNodes.length) {
id = value.__ctx.__defs.childNodes[0].getAttribute("id");
this.__ids[id] = id;
this.__defs.appendChild(value.__ctx.__defs.childNodes[0]);
for(nodeIndex = 0; nodeIndex < value.__ctx.__defs.childNodes.length; nodeIndex++){
node = value.__ctx.__defs.childNodes[nodeIndex];
id = node.getAttribute("id");
this.__ids[id] = id;
this.__defs.appendChild(node);
}
}
currentElement.setAttribute(style.apply, format("url(#{id})", {id:value.__root.getAttribute("id")}));
@ -1155,6 +1156,11 @@ export default (function () {
pattern.setAttribute("id", id);
pattern.setAttribute("width", image.width);
pattern.setAttribute("height", image.height);
// We want the pattern sizing to be absolute, and not relative
// https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Patterns
// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/patternUnits
pattern.setAttribute("patternUnits", "userSpaceOnUse");
if (image.nodeName === "CANVAS" || image.nodeName === "IMG") {
img = this.__document.createElementNS("http://www.w3.org/2000/svg", "image");
img.setAttribute("width", image.width);

View File

@ -15,24 +15,26 @@ import setLineDash from './tests/setLineDash'
import text from './tests/text'
import tiger from './tests/tiger'
import transform from './tests/transform'
import pattern from "./tests/pattern";
const tests = [
tiger,
arc,
arcTo,
arcTo2,
emptyArc,
fillstyle,
globalAlpha,
gradient,
linecap,
linewidth,
rgba,
rotate,
saveandrestore,
arc,
arcTo,
arcTo2,
emptyArc,
fillstyle,
globalAlpha,
gradient,
linecap,
linewidth,
rgba,
rotate,
saveandrestore,
setLineDash,
text,
transform
transform,
pattern
];
for (let fn of tests) {
@ -56,4 +58,4 @@ for (let fn of tests) {
const ctx = c.getContext('2d');
fn(ctx);
}
}
}

BIN
test/pattern.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

28
test/tests/pattern.js Normal file
View File

@ -0,0 +1,28 @@
export default function pattern(ctx) {
// Create a pattern
const patternCanvas = document.createElement('canvas');
const patternContext = patternCanvas.getContext('2d');
// Give the pattern a width and height of 50
patternCanvas.width = 50;
patternCanvas.height = 50;
// Give the pattern a background color and draw an arc
patternContext.fillStyle = '#fec';
patternContext.fillRect(0, 0, patternCanvas.width, patternCanvas.height);
patternContext.arc(0, 0, 50, 0, .5 * Math.PI);
patternContext.stroke();
const pattern = ctx.createPattern(patternCanvas, 'repeat');
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, 50, 50);
var img = new Image();
img.src = 'pattern.png';
img.onload = function() {
var pattern = ctx.createPattern(img, 'repeat');
ctx.fillStyle = pattern;
ctx.fillRect(50, 50, 300, 300);
};
};