如何使用画布将两条不同尺寸的线条划分?
我正在使用canvas
绘制一条线,我希望宽度为30
并逐渐(按比例)减小到15
的尺寸,所以它在行尾就达到了15。
我认为,如果我将context.lineWidth
设置在两个地方(开始和结束),它可能会起作用。
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.beginPath();
context.moveTo(100, 150);
context.lineWidth = 30;
context.lineTo(450, 50);
context.lineWidth = 15;
context.stroke();
</script>
</body>
</html>
&#13;
答案 0 :(得分:3)
我曾经想过建立这样一个可变宽度的线,我结束了自己的解决方案,并写了一篇博文。
我在这里复制它的第一部分,圆形版本也可以在这里找到:
https://gamealchemist.wordpress.com/2013/08/28/variable-width-lines-in-html5-canvas/
html5中的可变宽度行
一旦我们意识到我们需要绘制的不是一条线,那么绘制这样一条[可变宽度]线很容易:实际上它是一个多边形。
如果我们想要绘制的线段是(A,B),情况如下:
我们想要绘制的是A1,A2,B2,B1多边形。
如果我们将N称为法线向量(在方案上绘制),并且将W1和W2分别称为A和B中的宽度,我们有:
A1 = A + N * w1 / 2
A2 = A - N * w1 / 2
B1 = B + N * w2 / 2
B2 = B - N * w2 / 2
那么我们如何找到这个法向量N?
数学说如果(x,y)定义向量V,则其法向量坐标为(-y,x)
N,因此AB的法向量将具有( - (yB - yA),(xB - xA))作为坐标。
但是这个向量有一个烦人的事情:它取决于AB长度,而不是
我们想要的是:我们需要对这个向量进行标准化,即将它的标准长度设置为1,所以当我们稍后将这个向量乘以w1 / 2时,我们会得到正确的长度向量。
矢量归一化是通过将矢量的x和y除以矢量长度来完成的。 因为使用phytagore定理找到长度,所以得到2个正方形,一个平方根,最后2个除以找到归一化向量N:
// computing the normalized vector normal to AB
length = Math.sqrt( sq (xB-xA) + sq (yB - yA) ) ;
Nx = - (yB - yA) / length ;
Ny = (xB - xA) / length ;
现在我们可以计算四个点,让我们用多边形线将它们连接起来,然后填充得到的形状:这是我们的可变宽度线段!
以下是javascript代码:
// varLine : draws a line from A(x1,y1) to B(x2,y2)
// that starts with a w1 width and ends with a w2 width.
// relies on fillStyle for its color.
// ctx is a valid canvas's context2d.
function varLine(ctx, x1, y1, x2, y2, w1, w2) {
var dx = (x2 - x1);
var dy = (y2 - y1);
w1 /= 2; w2 /= 2; // we only use w1/2 and w2/2 for computations.
// length of the AB vector
var length = Math.sqrt(sq(dx) + sq(dy));
if (!length) return; // exit if zero length
dx /= length ; dy /= length ;
var shiftx = - dy * w1 // compute AA1 vector's x
var shifty = dx * w1 // compute AA1 vector's y
ctx.beginPath();
ctx.moveTo(x1 + shiftx, y1 + shifty);
ctx.lineTo(x1 - shiftx, y1 - shifty); // draw A1A2
shiftx = - dy * w2 ; // compute BB1 vector's x
shifty = dx * w2 ; // compute BB1 vector's y
ctx.lineTo(x2 - shiftx, y2 - shifty); // draw A2B1
ctx.lineTo(x2 + shiftx, y2 + shifty); // draw B1B2
ctx.closePath(); // draw B2A1
ctx.fill();
}
因此,让我们看一个小例子的结果:在一个圆圈内绘制具有漂亮的hsl颜色的可变宽度段:
(关于@MarkE&#39; s(有趣)关于链接线段的评论,我担心这是一个相当困难的目标,因为根据线段长度/ w1 / w2 /角度在段之间存在许多具体情况。使用力场和行进立方体完全解决了它,但我担心这完全偏离主题!! :-))