我正在尝试修改 Canvas 图案的来源,但无法实现我想要的。

我需要画一条用虚线图案填充的线。虚线图案是通过createPattern创建的(将其动态生成的 Canvas 元素供入)。

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, dotWidth / 2, 0, Math.PI * 2, false);
  patternCtx.closePath();
  patternCtx.fill();

  return patternCanvas;
}

然后使用该图案( Canvas )绘制一条线:
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。翻译图案 Canvas 无济于事,因为这样我们就没有完整的圆点:

Canvas 本身的上下文翻译无济于事,因为它会偏移线,而不是图案本身:

翻译上下文似乎并不影响模式起源。

有没有办法修改图案本身的偏移量?

最佳答案

更新自发布此答案以来,现在(自2015/02年以来)在setTransform()实例本身上有一个本地CanvasPattern(请参阅specs)。它可能并非在所有浏览器中都可用(编写时只有Firefox支持)。
方法1
您可以偏移主 Canvas ,并在该行的实际位置添加一个增量值:

var offsetX = 10, offsetY = 10;
ctx.translate(offsetX, offsetY);
ctx.lineTo(x - offsetX, y - offsetY);
// ...
Example
(该演示仅显示正在翻译的模式,但是,当然,通常您将其与行一起移动)。

等等,这样您就取消了行本身的翻译。但这会带来一些开销,因为每次都需要计算坐标,除非您可以缓存结果值。
方法二
我可以想到的另一种方法是创建自己的模式的模式。 IE。对于图案 Canvas ,请重复该点,以便在将其移动到其边界之外时以相反的方向重复该点。
例如,这里的第一个正方形是普通图案,第二个是描述为方法二的偏移图案,第三个图像使用偏移图案进行填充,表明它将起作用。
关键是两个模式的大小相同,并且第一个模式重复偏移到此第二个版本中。然后可以将第二个版本用作主要版本。
Example 2 (链接断开)
Example 3 animated
var ctx = demo.getContext('2d'),
    pattern;

// create the pattern
ctx.fillStyle = 'red';
ctx.arc(25, 25, 22, 0, 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, 0, 200, 200);

关于html - Canvas 图案偏移,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20253210/

10-12 05:23