简体   繁体   English

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

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

Question Background: I am working on a site that, along with other data, draws vertical and horizontal lines on an HTML canvas. 问题背景:我正在一个与其他数据一起在HTML画布上绘制垂直和水平线的站点上。 That page can be converted to a PDF file when the user wants to download the report. 当用户要下载报告时,可以将该页面转换为PDF文件。 Originally we were using one default style line to draw the graph values. 最初,我们使用一条默认样式线来绘制图形值。 Recently we added a second type of data on the graph and used context.setLineDash([x,x]) to draw dashed lines for the second data type. 最近,我们在图上添加了第二种数据类型,并使用context.setLineDash([x,x])绘制了第二种数据类型的虚线。 This works great in browsers. 这在浏览器中效果很好。 However, when the PDF converter software tries to convert a report with dashed lines, the dashed lines do not show up in the resulting PDF. 但是,当PDF转换器软件尝试转换带虚线的报告时,虚线不会显示在生成的PDF中。

After some troubleshooting, I narrowed the problem down to the setLineDash() property. 经过一些故障排除后,我将问题缩小到setLineDash()属性。 It appears our converter sofware can understand normal style lines but does not understand the setLineDash() property. 看来我们的转换器软件可以理解普通的样式行,但不能理解setLineDash()属性。 The converter software is several years old and I have been informed that an updated version of the converter will not be bought. 该转换器软件已有几年历史了,我被告知不会购买该转换器的更新版本。 I also discovered that there is no support for our version from the creator. 我还发现创作者不支持我们的版本。

Question: Since I am unable to update our HTML to PDF converter software or get support for it directly, can anyone provide an example of an alternative way to draw a dashed line on a canvas without using setLineDash() ? 问题:由于我无法将我们的HTML更新为PDF转换器软件或直接获得对其的支持,因此谁能提供不使用setLineDash()在画布上绘制虚线的替代方法的示例吗?

EDIT 编辑

@K3N, @ K3N,

As per the instructions on the notification I received when you marked this question a duplicate of this other question , I am editing to explain how it is different. 按照您将这个问题标记为另一个问题的副本时收到的通知中的说明,我正在编辑以解释它的不同之处。

I believe that though the answers to both questions will likely be similar, my question is not a duplicate of the question you indicated. 我相信,尽管两个问题的答案都可能相似,但我的问题并非您所指出问题的重复。 I concede that both questions are asking for a way to draw dashed lines on a canvas. 我承认这两个问题都要求一种在画布上绘制虚线的方法。 However, the other question is asking how to implement a dashed line by any method. 但是,另一个问题是询问如何通过任何方法实现虚线。 My question specifically states that I cannot use the setLineDash() property to draw a dashed line. 我的问题特别指出,我无法使用setLineDash()属性绘制虚线。 This difference limits the possible answers and I believe it is enough to make both questions sufficiently distinct. 这种差异限制了可能的答案,我相信足以使两个问题都足够清楚。

You can create line segments. 您可以创建线段。

The function will draw a dashed line from the info in the dashArr eg [2,2] will draw a line 2 pixels then a gap 2 pixels and repeat. 该函数将从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> 

I was also facing a similar problem and I used a different approach to solve this problem. 我也面临着类似的问题,因此我使用了不同的方法来解决此问题。 I am posting it in case someone else is having the similar problem. 如果有人遇到类似问题,我会发布它。

You can set the stroke pattern on canvas context. 您可以在画布上下文上设置笔划样式。 Stroke pattern can be any canvas pattern. 描边图案可以是任何画布图案。 So here I created an image of 1 pixel height and 6 pixel width. 所以在这里我创建了一个1像素高和6像素宽的图像。 First three pixels were black and other three were white. 前三个像素为黑色,其他三个像素为白色。 Now I created the image to create a repeating pattern. 现在,我创建了图像以创建重复图案。

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

Now all the calls to context.stroke will use the pattern to draw strokes. 现在,所有对context.stroke的调用都将使用该模式来绘制笔划。 Like if you create a line from the top left corner of the canvas to the bottom right corner it will be a dashed line. 就像从画布的左上角到右下角创建一条线一样,它将是一条虚线。

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

See the full explanation at the following link https://shamailamahmood.blogspot.com/2019/02/html5-canvas-drawing-draw-dotted-or.html 请参阅以下链接的完整说明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