问题背景
我正在一个网站上,与其他数据一起在HTML画布上绘制垂直和水平线。当用户想要下载报告时,该页面可以转换为PDF文件。最初我们使用一个默认样式线来绘制图形值。最近我们在图表上添加了第二种类型的数据,并使用context.setLineDash([x,x])
为第二种数据类型绘制虚线。这适用于浏览器。但是,当PDF转换器软件尝试使用虚线转换报表时,虚线不会显示在生成的PDF中。
经过一些故障排除后,我将问题缩小到setLineDash()
属性。看来我们的转换软件可以理解正常的样式行,但不理解setLineDash()
属性。转换器软件已有几年的历史了,我被告知不会购买转换器的更新版本。我还发现创作者不支持我们的版本。
问题:由于我无法将HTML转换为PDF转换软件或直接获得对它的支持,任何人都可以提供一种在画布上绘制虚线的替代方法的示例,而不使用setLineDash()
?
修改
@ K3N,
根据我在将此问题标记为this other question的副本时收到的通知说明,我正在编辑以解释它是如何不同的。
我相信虽然这两个问题的答案可能相似,但我的问题并不是你所指出的问题的重复。我承认这两个问题都是要求在画布上绘制虚线的方法。但是,另一个问题是询问如何通过任何方法实现虚线。我的问题明确指出我不能使用setLineDash()
属性绘制虚线。这种差异限制了可能的答案,我认为这足以使两个问题充分区分。
答案 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
}
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;
答案 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