一尘不染

点划线

html

我想不可能设置像CSS这样的笔触属性,这非常容易。使用CSS,我们已经用虚线,点线,实线表示,但是在画布上绘制线条或笔触时,这似乎不是一个选择。您是如何实现的?

我已经看到了一些示例,但是它们对于实现如此愚蠢的功能确实很渴望。


阅读 309

收藏
2020-05-10

共1个答案

一尘不染

好玩的问题!我编写了一个自定义的虚线实现;您可以在这里尝试。我采用了AdobeIllustrator的方法,并允许您指定破折号/间隙长度的数组。

这是我的实现(对于s / o线宽略有更改):

var CP = window.CanvasRenderingContext2D && CanvasRenderingContext2D.prototype;
if (CP && CP.lineTo){
  CP.dashedLine = function(x,y,x2,y2,dashArray){
    if (!dashArray) dashArray=[10,5];
    if (dashLength==0) dashLength = 0.001; // Hack for Safari
    var dashCount = dashArray.length;
    this.moveTo(x, y);
    var dx = (x2-x), dy = (y2-y);
    var slope = dx ? dy/dx : 1e15;
    var distRemaining = Math.sqrt( dx*dx + dy*dy );
    var dashIndex=0, draw=true;
    while (distRemaining>=0.1){
      var dashLength = dashArray[dashIndex++%dashCount];
      if (dashLength > distRemaining) dashLength = distRemaining;
      var xStep = Math.sqrt( dashLength*dashLength / (1 + slope*slope) );
      if (dx<0) xStep = -xStep;
      x += xStep
      y += slope*xStep;
      this[draw ? 'lineTo' : 'moveTo'](x,y);
      distRemaining -= dashLength;
      draw = !draw;
    }
  }
}

若要从20,150到画一条170,10长为30px的虚线,然后以10px的间距划线,请使用:

myContext.dashedLine(20,150,170,10,[30,10]);

要绘制交替的点和点,请使用(例如):

myContext.lineCap   = 'round';
myContext.lineWidth = 4; // Lines 4px wide, dots of diameter 4
myContext.dashedLine(20,150,170,10,[30,10,0,10]);

“非常短”的破折号长度0与圆角的lineCap结合在一起会在您的直线上产生点。

如果有人知道访问画布上下文路径当前点的方法,那么我很想知道,因为它可以让我编写它,ctx.dashTo(x,y,dashes)而不是要求您在方法调用中重新指定起点。

2020-05-10