Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在HTML5画布上绘制虚线的替代方法是什么?_Javascript_Html_Canvas - Fatal编程技术网

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

Javascript 在HTML5画布上绘制虚线的替代方法是什么?,javascript,html,canvas,Javascript,Html,Canvas,问题背景: 我正在一个网站上工作,该网站与其他数据一起在HTML画布上绘制垂直和水平线。当用户想要下载报告时,该页面可以转换为PDF文件。最初,我们使用一条默认样式线来绘制图形值。最近,我们在图形上添加了第二种数据类型,并使用context.setLineDash([x,x])为第二种数据类型绘制虚线。这在浏览器中非常有效。但是,当PDF转换器软件尝试转换带有虚线的报告时,虚线不会显示在生成的PDF中 经过一些故障排除,我将问题缩小到setLineDash()属性。我们的转换器软件似乎可以理解普

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

经过一些故障排除,我将问题缩小到
setLineDash()
属性。我们的转换器软件似乎可以理解普通样式线,但不理解
setLineDash()
属性。转换器软件已经有好几年的历史了,我被告知不会购买更新版本的转换器。我还发现造物主不支持我们的版本

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

编辑

@K3N

根据您将此问题标记为的副本时我收到的通知上的说明,我正在编辑以解释其不同之处


我相信,虽然这两个问题的答案很可能是相似的,但我的问题并不是你提到的问题的重复。我承认,这两个问题都在寻求一种在画布上画虚线的方法。然而,另一个问题是如何通过任何方法实现虚线。我的问题特别指出,我不能使用
setLineDash()
属性绘制虚线。这种差异限制了可能的答案,我相信这足以使这两个问题有足够的区别。

您可以创建线段

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

您可以创建线段

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

我也面临着类似的问题,我使用了不同的方法来解决这个问题。我张贴它的情况下,其他人是有类似的问题

可以在画布上下文上设置笔划模式。笔划图案可以是任何画布图案。所以在这里我创建了一个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();
请参阅以下链接中的完整说明

我也面临着类似的问题,我使用了不同的方法来解决这个问题。我张贴它的情况下,其他人是有类似的问题

可以在画布上下文上设置笔划模式。笔划图案可以是任何画布图案。所以在这里我创建了一个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();
请参阅以下链接中的完整说明

如果OP只是说直线,这很好,但我担心他应该用“路径”这个词。@kaido OP的问题是“有人能提供一个在画布上画虚线的替代方法的例子吗?”如果他想画一条路径,然后用一个结尾处的移动距离重复这一行,开始下一个。是的,这就是他说的,我只是说我希望这是他真正说的,因为否则不,当我使用“路径”这个词时,它明确地包括了其他路径方法,我认为这不像他说的那么容易“用一句话结尾的距离重复这句话,然后开始下一句话”。或者你能证明我错了吗?这就是我所说的,我投了赞成票,因为是的,就目前的情况而言,如果我们理解这些词的含义,那么你的答案是“好”。但如果他使用“行”“因为他脑子里有setLineDash…@Kaido对于路径的答案是,如果不重写影响或创建路径、圆弧、椭圆、lineTo、moveTo、rect、strokeRect、strokeText、quadraticCurveTo、bezierCurveTo、scale、translate、transform、setTransform、stroke的所有context2D函数,就无法访问路径数据(Path2D)、保存、还原、我是否遗漏了任何内容。修改失败的PDF编写器或忘记破折号并使用颜色会更容易。直线答案为从线段创建的路径提供了一个简单快速的解决方案,并查看dup答案(65+表示错误的错误代码),这是更有力的。@Kaido,谢谢你指出我原始问题中关于线条类型的模糊性。我对问题的这一部分进行了编辑,以便更具体地描述线条。如果OP只谈论直线
lineTo
,这很好,但我担心他应该使用“路径”这个词。@Kaido OP的问题是“有人能提供一个在画布上画虚线的替代方法的例子吗?”如果他想画一条路径,那么就用一条路径末尾的距离重复这条线,然后开始下一条。是的,他是这么说的,我只是说我