如何在画布中绘制重复形状/标记的线条?

时间:2017-06-06 10:43:53

标签: javascript canvas

我正在寻找一种在<canvas>元素中使用标记的方法,如下图所示。

SVG marker-mid example

在SVG中我们可以做到这一点,感谢markers,但我还没有找到类似的方法来做到这一点。我知道我们可以通过createPattern功能在画布上创建模式,但我怀疑它可以帮助解决这个问题。

编辑:这不是this问题的重复,因为我正在寻找一种方法来重复路径上的形状/标记。它不是将标记放在特定的给定点。

正如我已经评论过的那样,我发现svg-path-properties对我的解决方案来说几乎是完美的。

1 个答案:

答案 0 :(得分:1)

遗憾的是,没有本地方法可以在canvas API中为笔划添加标记。即使我们能够将strokeStyle设置为CanvasPattern,也无法使此模式遵循我们路径的方向。

这意味着您必须自己计算标记的方向和位置...
为此,您可以参考许多帖子,例如TomàsAntunes在评论中提出的this one

然而,要做到你向我们展示的确切三角形状,我有一个非mathy hack,它不能很好地工作,但是我想分享。

笔划可以有破折号阵列,这会在笔划中产生间隙 通过多次偏移此破折号数组并减少笔划的lineWidth,我们可以 sort-of 创建这些箭头形状:

var ctx = c.getContext('2d');
// our default path
ctx.beginPath();
ctx.moveTo(50, 20);
ctx.bezierCurveTo(230, 30, 150, 60, 50, 100);
ctx.bezierCurveTo(250, 50, 150, 60, 150, 150);
ctx.stroke();
// the hack
for (var i = 0; i < 9; i += .5) {
  // set an dasharray of 1px visible, then 40 invisible
  ctx.setLineDash([1, 49]);
  // offset the dash-array by one px
  ctx.lineDashOffset = i;
  // reduce the width of our stroke
  ctx.lineWidth = i;
  ctx.stroke();
}
<canvas id="c"></canvas>

但是这个方法的主要警告(除了要求重绘相同的路径20次)是真正遵循路径,并且在角度,它可能不再完全像我们的三角形。

var ctx = c.getContext('2d');
// our default path
ctx.beginPath();
ctx.moveTo(50, 20);
ctx.bezierCurveTo(230, 30, 150, 60, 50, 100);
ctx.stroke();
// the hack
for (var i = 0; i < 9; i += .5) {
  // set an dasharray of 1px visible, then 20 invisible
  ctx.setLineDash([1, 14]);
  // offset the dash-array by one px
  ctx.lineDashOffset = i;
  // reduce the width of our stroke
  ctx.lineWidth = i*2;
  ctx.stroke();
}
<canvas id="c"></canvas>