我的问题:我有一个ImageObject,用于创建PatternObject。我的问题是,我在创建模式之前更改了图像的width
和height
属性,但实际上并没有重新映射图像(这也没有问题)。问题是,我现在有一个图案,与图像本身的尺寸不同(原始图像尺寸)。如果我想用该模式的fillStyle绘制一条线,它就不适合(因为我需要一个新尺寸的图案)。
我的问题:有没有一种简单的方法可以调整图案的宽度和高度?
我的尝试 以及为什么我不喜欢它们:
1)将原始图像渲染到具有新尺寸的画布并从中创建图案。没有使用它,因为无法直接加载模式,因为画布被创建并渲染得太慢。但我直接想要这种模式
2)计算新图像尺寸与原始图像尺寸之间的差异,更改上下文的lineWidth,使图案高度精确拟合并缩小线条,因此它具有不错的尺寸。没有使用它,因为我实时渲染,这太慢,以至于以后在webapps中使用。
答案 0 :(得分:8)
使用画布(您的第1步)是最灵活的方式。
使用画布在另一个画布上绘制比直接使用图像要慢。它们都使用相同的元素基础(就像对图像一样使用位图)。
(更新:使用模式作为样式绘图会在更新的浏览器中对模式的局部变换矩阵执行额外步骤。)
以图案大小创建一个新画布,并将图像简单地绘制到其中:
patternCtx.drawImage(img, 0, 0, patternWidth, patternHeight);
然后使用patternCtx的画布作为模式的基础(在第一次绘制时,模式在内部模式缓存此图像,如果可能的话,它只会将整个画布填满之前的内容加倍)。
另一种选择是将图像预先缩放到您需要的所有尺寸,将它们全部加载,然后选择尺寸与您需要的图像。
第三是将图像自己绘制成图案。然而,与内置方法相比,这并不是那么有效,尽管使用上述方法(内部)可以获得可用的结果。
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function() {
fillPattern(this, 64, 64);
change.onchange = change.oninput = function() {
fillPattern(img, this.value, this.value);
}
};
img.src = "//i.stack.imgur.com/tkBVh.png";
// Fills canvas with image as pattern at size w,h
function fillPattern(img, w, h) {
//draw once
ctx.drawImage(img, 0, 0, w, h);
while (w < canvas.width) {
ctx.drawImage(canvas, w, 0);
w <<= 1; // shift left 1 = *2 but slightly faster
}
while (h < canvas.height) {
ctx.drawImage(canvas, 0, h);
h <<= 1;
}
}
<input id=change type=range min=8 max=120 value=64><br>
<canvas id=canvas width=500 height=400></canvas>
(或使用video as pattern)。