2013-06-21 40 views
2

我的问题:我有一个ImageObject,用于创建PatternObject。我的问题是,我在创建模式之前更改了图像的widthheight属性,但实际上并未重新映射图像(这也没有问题)。事情是,我现在已经有了一个图形,它的大小与图像本身不同(原始图像的大小)。如果我想用该模式的fillStyle绘制一条线,则不适合(因为我需要一个新尺寸的模式)。在Html5 Canvas中更改图案大小

我的问题:有没有一种简单的方法,以实现模式的宽度和高度可以调整?

我试图,为什么我不喜欢他们:

1)渲染原始图像与新尺寸的画布,并创建该模式。没有使用它,因为由于画布被创建和渲染得太慢,无法直接加载该图案。但我直接需要该图案

2)计算新图像大小和原始图像大小之间的差异,更改上下文的lineWidth,以便模式高度精确地拟合并缩小线条,因此它具有很好的大小。没有使用它,因为我实时渲染,这太慢了,以至于以后在webapps中使用。

谢谢先进! :)

回答

6

使用画布(您的第1步)是最灵活的方法。

使用画布在另一个画布上绘图而不是使用直接使用图像的速度较慢。他们都使用相同的元素基础(你正在像一个图像blitting一个位图)。

更新:使用图案的风格都经过当地变换矩阵在最近的浏览器模式的一个额外的步骤图)

创建模式和简单的尺寸新的画布绘制图像到它:

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)。

+0

+1不错,你给我这么多的选择,会再次尝试第一个,我的问题是,如果我在新定义的画布上绘制,然后尝试从它加载模式,该模式可以以某种方式不加载,因为画布没有准备好加载。 – TheOneAndOnly

+0

@TheOneAndOnly没问题。原因很可能是图像未完成加载。你可以挂钩图像的onload事件,然后触发模式设置等。 – K3N

+1

这段代码非常有用! +1 – A1rPun