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