繁体   English   中英

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

[英]What is an alternative method for drawing dashed lines on an HTML5 Canvas?

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

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

问题:由于我无法将我们的HTML更新为PDF转换器软件或直接获得对其的支持,因此谁能提供不使用setLineDash()在画布上绘制虚线的替代方法的示例吗?

编辑

@ K3N,

按照您将这个问题标记为另一个问题的副本时收到的通知中的说明,我正在编辑以解释它的不同之处。

我相信,尽管两个问题的答案都可能相似,但我的问题并非您所指出问题的重复。 我承认这两个问题都要求一种在画布上绘制虚线的方法。 但是,另一个问题是询问如何通过任何方法实现虚线。 我的问题特别指出,我无法使用setLineDash()属性绘制虚线。 这种差异限制了可能的答案,我相信足以使两个问题都足够清楚。

您可以创建线段。

该函数将从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
}

  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]); 
 canvas { border : 2px solid black; } 
 <canvas id="canvas"></canvas> 

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

您可以在画布上下文上设置笔划样式。 描边图案可以是任何画布图案。 所以在这里我创建了一个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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM