我正在尝试修改画布图案的起源,但无法达到我想要的效果.
我需要绘制一条填充点状图案的线条.虚线图案通过createPattern创建(为其动态创建canvas元素).
画布(基本上是一个红点)的创建方式如下:
function getPatternCanvas() { var dotWidth = 20,dotDistance = 5,patternCanvas = document.createElement('canvas'),patternCtx = patternCanvas.getContext('2d'); patternCanvas.width = patternCanvas.height = dotWidth + dotDistance; // attempt #1: // patternCtx.translate(10,10); patternCtx.fillStyle = 'red'; patternCtx.beginPath(); patternCtx.arc(dotWidth / 2,dotWidth / 2,Math.PI * 2,false); patternCtx.closePath(); patternCtx.fill(); return patternCanvas; }
然后使用该模式(画布)绘制一条线:
var canvasEl = document.getElementById('c'); var ctx = canvasEl.getContext('2d'); var pattern = ctx.createPattern(getPatternCanvas(),'repeat'); // attempt #2 // ctx.translate(10,10); ctx.strokeStyle = pattern; ctx.lineWidth = 30; ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(100,100); ctx.stroke();
所以我们得到这个:
现在,我想用10px来抵消这些点的来源.翻译模式画布没有帮助,因为我们没有获得完整的点:
并且翻译画布本身的上下文并没有帮助,因为它抵消了线条,而不是图案本身:
翻译上下文似乎不会影响模式起源.
有没有办法修改模式本身的偏移量?
解决方法
更新自此答案发布以来,现在(自2015/02起)CanvasPattern实例本身就有一个本地setTransform()(见
specs).它可能还没有在所有浏览器中可用(只有Firefox在编写时支持它).
方法1
您可以偏移主画布并将增量值添加到该行的实际位置:
var offsetX = 10,offsetY = 10; ctx.translate(offsetX,offsetY); ctx.lineTo(x - offsetX,y - offsetY); // ...
(演示只显示正在翻译的模式,但当然,通常你会将它与它一起移动).
这样你就取消了这条线本身的翻译.但它引入了一些开销,因为除非您可以缓存结果值,否则每次都需要计算坐标.
方法2
我能想到的另一种方式是创造一种自我模式.即对于图案画布重复点,以便当您将其移动到其边界外时,它将以相反的方向重复.
例如,这里第一个正方形是正常图案,第二个是描述为方法二的偏移图案,第三个图像使用偏移图案进行填充,表明它将起作用.
关键是两个模式具有相同的大小,并且第一个模式重复偏移到第二个版本中.然后可以将第二个版本用作主要的填充.
var ctx = demo.getContext('2d'),pattern; // create the pattern ctx.fillStyle = 'red'; ctx.arc(25,25,22,2*Math.PI); ctx.fill(); // offset and repeat first pattern to base for second pattern ctx = demo2.getContext('2d'); pattern = ctx.createPattern(demo,'repeat'); ctx.translate(25,25); ctx.fillStyle = pattern; ctx.fillRect(-25,-25,50,50); // use second pattern to fill main canvas ctx = demo3.getContext('2d'); pattern = ctx.createPattern(demo2,'repeat'); ctx.fillStyle = pattern; ctx.fillRect(0,200,200);