在HTML5 Canvas上绘制虚线的替代方法是什么?

时间:2017-09-19 17:28:49

标签: javascript html5 canvas

问题背景 我正在一个网站上,与其他数据一起在HTML画布上绘制垂直和水平线。当用户想要下载报告时,该页面可以转换为PDF文件。最初我们使用一个默认样式线来绘制图形值。最近我们在图表上添加了第二种类型的数据,并使用context.setLineDash([x,x])为第二种数据类型绘制虚线。这适用于浏览器。但是,当PDF转换器软件尝试使用虚线转换报表时,虚线不会显示在生成的PDF中。

经过一些故障排除后,我将问题缩小到setLineDash()属性。看来我们的转换软件可以理解正常的样式行,但不理解setLineDash()属性。转换器软件已有几年的历史了,我被告知不会购买转换器的更新版本。我还发现创作者不支持我们的版本。

问题:由于我无法将HTML转换为PDF转换软件或直接获得对它的支持,任何人都可以提供一种在画布上绘制虚线的替代方法的示例,而不使用setLineDash()

修改

@ K3N,

根据我在将此问题标记为this other question的副本时收到的通知说明,我正在编辑以解释它是如何不同的。

我相信虽然这两个问题的答案可能相似,但我的问题并不是你所指出的问题的重复。我承认这两个问题都是要求在画布上绘制虚线的方法。但是,另一个问题是询问如何通过任何方法实现虚线。我的问题明确指出我不能使用setLineDash()属性绘制虚线。这种差异限制了可能的答案,我认为这足以使两个问题充分区分。

2 个答案:

答案 0 :(得分:3)

您可以创建线段。

该函数将从dashArr中的信息中绘制一条虚线,例如[2,2]将绘制一条线2像素,然后一个间隙2像素并重复。

function dashedLine(x1,y1,x2,y2,dashArr){
    // get the normalised line vector from start to end
    var nx = x2 - x1;
    var ny = y2 - y1;
    const dist = Math.sqrt(nx * nx + ny * ny);  // get the line length
    nx /= dist;
    ny /= dist;
    var dashIdx = 0;  // the index into the dash array
    var i = 0;        // the current line position in pixels
    ctx.beginPath();  // start a path
    while(i < dist){   // do while less than line length
         // get the line seg dash length
         var dashLen = dashArr[(dashIdx ++) % dashArr.length];
         // draw the dash
         ctx.moveTo(x1 + nx * i, y1 + ny * i);
         i = Math.min(dist,i + dashLen);
         ctx.lineTo(x1 + nx * i, y1 + ny * i);
         // add the spacing
         i += dashArr[(dashIdx ++) % dashArr.length];
         if(i <= 0) { // something is wrong so exit rather than endless loop
              break;
         }
     }
     ctx.stroke();  // stroke
}

&#13;
&#13;
    function dashedLine(x1,y1,x2,y2,dashArr){

        var nx = x2 - x1;
        var ny = y2 - y1;
        const dist = Math.sqrt(nx * nx + ny * ny);
        nx /= dist;
        ny /= dist;
        var dashIdx = 0;
        var i = 0;
        ctx.beginPath();
        while(i < dist){
             var dashLen = dashArr[(dashIdx ++) % dashArr.length];
             ctx.moveTo(x1 + nx * i, y1 + ny * i);
             i = Math.min(dist,i + dashLen);
             ctx.lineTo(x1 + nx * i, y1 + ny * i);
             i += dashArr[(dashIdx ++) % dashArr.length];
             if(i <= 0) { // something is wrong so exit rather than endless loop
                  break;
             }
         }
         ctx.stroke()
    }
    
    
const ctx = canvas.getContext("2d");
dashedLine(0,0,300,150,[5,5]);
&#13;
canvas { border : 2px solid black; }
&#13;
<canvas id="canvas"></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我也面临着类似的问题,因此我使用了不同的方法来解决此问题。如果有人遇到类似问题,我会发布它。

您可以在画布上下文上设置笔划样式。描边图案可以是任何画布图案。所以在这里我创建了一个1像素高和6像素宽的图像。前三个像素为黑色,其他三个像素为白色。现在,我创建了图像以创建重复图案。

var linePattern;
imageToUsedAsPattern.onload = function() {
    linePattern = context.createPattern(imageToUsedAsPattern, "repeat");
    context.strokeStyle=linePattern; 
}
var imageToUsedAsPattern = new Image();
imageToUsedAsPattern.src = "images/linePatterns.jpg";

现在所有对context.stroke的调用都将使用该模式绘制笔划。就像从画布的左上角到右下角创建一条线一样,它就是一条虚线。

context.moveTo(0,0);
context.lineTo(canvas.width,canvas.height);
context.stroke();

在以下链接中查看完整说明 https://shamailamahmood.blogspot.com/2019/02/html5-canvas-drawing-draw-dotted-or.html