gpt4 book ai didi

javascript - 用两个不同大小的末端画一条线

转载 作者:行者123 更新时间:2023-11-30 12:25:58 25 4
gpt4 key购买 nike

我怎样才能让一条线与 Canvas 有两种不同的大小?

我用 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>

最佳答案

我曾经想过构建这样一条可变宽度的线,然后我结束了构建自己的解决方案,并用它写了一篇博文。
我会在这里复制它的第一部分,也可以在这里找到四舍五入的版本: https://gamealchemist.wordpress.com/2013/08/28/variable-width-lines-in-html5-canvas/


html5 中可变宽度的线条

一旦我们意识到我们需要绘制的不是一条线:实际上它是一个多边形,那么绘制这样一条 [可变宽度] 线就非常容易了。

如果我们要画的线段是(A,B),情况是这样的:

enter image description here

我们其实要画的是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 的长度,而 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 颜色绘制可变宽度的线段:

enter image description here

(关于@MarkE 关于链接线段的(有趣的)评论,我担心这是一个相当困难的目标,因为有许多具体情况取决于线段之间的线长度/w1/w2/ Angular 。我完全解决了它使用力场和行进立方体,但我担心这完全是题外话!!:-) )

关于javascript - 用两个不同大小的末端画一条线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29377748/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com