gpt4 book ai didi

javascript - 在 Canvas 上平滑地将对象从 A 移动到 B

转载 作者:行者123 更新时间:2023-11-28 04:17:16 25 4
gpt4 key购买 nike

我正在尝试使用 HTML Canvas 和常规 javascript 将对象从 A 点平滑地移动到 B 点。

A点是一组坐标

B点就是光标所在的位置。

我把我目前拥有的东西做了一个 jsfiddle:https://jsfiddle.net/as9fhmw8/

while(projectile.mouseX > projectile.x && projectile.mouseY < projectile.y)
{
ctx.save();
ctx.beginPath();
ctx.translate(projectile.x, projectile.y);
ctx.arc(0,0,5,0,2*Math.PI);
ctx.fillStyle = "blue";
ctx.fill();
ctx.stroke();
ctx.restore();
if(projectile.mouseX > projectile.x && projectile.mouseY < projectile.y)
{
var stepsize = (projectile.mouseX - projectile.x) / (projectile.y - projectile.mouseY);
projectile.x += (stepsize + 1);
}
if(projectile.mouseY < projectile.y)
{
var stepsize = (projectile.y - projectile.mouseY) / (projectile.mouseX - projectile.x);
projectile.y -= (stepsize + 1);
}
}

基本上我想不通的是让 while 循环变慢(这样它看起来像动画而不是仅仅经历每一次迭代并显示结果)。

我也不知道如何防止 Arc 重复,从而创建一条永久线,而不是看起来从 a 点移动到 b 点。

最佳答案

此处的平滑动画实际上是关于确定每次循环迭代将对象移动多远。

这里涉及到一点数学,但还算不错。

速度

在您的情况下,速度就是您的粒子在一段时间内沿任何给定方向行进的速度。如果您希望粒子在 4 秒内移动 200px,则速度将为 50px/second

利用此信息,您可以轻松确定在给定任意时间长度的情况下移动(动画)粒子的像素数。

像素 = pixelsPerSecond * 秒

很高兴知道要移动多少像素,但不会转换为单独的 X 和 Y 坐标。这就是向量的用武之地。

向量

数学中的矢量是方向和大小的度量。就我们的目的而言,这就像将我们的速度与 Angular (47°) 相结合。

向量的一个重要特性是它可以分解为单独的 X 和 Y 分量(对于二维空间)。

因此,如果我们想以47° Angular 以50px/second 的速度移动我们的粒子,我们可以计算一个向量,例如所以:

function Vector(magnitude, angle){
var angleRadians = (angle * Math.PI) / 180;

this.magnitudeX = magnitude * Math.cos(angleRadians);
this.magnitudeY = magnitude * Math.sin(angleRadians);
}

var moveVector = new Vector(50, 47);

这方面的美妙之处在于,这些值可以简单地添加到任何一组 X 和 Y 坐标,以根据您的速度计算移动它们。

鼠标移动矢量

以这种方式为您的对象建模还有一个额外的好处,那就是让事物变得漂亮并且在数学上保持一致。您的粒子和鼠标之间的距离只是另一个矢量。

我们可以使用更多的数学计算距离和 Angular 。还记得毕达哥拉斯那个家伙吗?事实证明他很聪明。

function distanceAndAngleBetweenTwoPoints(x1, y1, x2, y2){
var x = x2 - x1,
y = y2 - y1;

return {
// x^2 + y^2 = r^2
distance: Math.sqrt(x * x + y * y),

// convert from radians to degrees
angle: Math.atan2(y, x) * 180 / Math.PI
}
}

var mouseCoords = getMouseCoords();
var data = distanceAndAngleBetweenTwoPoints(particle.x, particle.y, mouse.x, mouse.y);

//Spread movement out over three seconds
var velocity = data.distance / 3;

var toMouseVector = new Vector(velocity, data.angle);

流畅的动画

以一种不不稳定的方式在屏幕上动画你的东西意味着执行以下操作:

  1. 尽可能快地运行你的动画循环
  2. 确定自上次以来经过了多少时间
  3. 根据经过的时间移动每个项目。
  4. 重新绘制屏幕

对于动画循环,我会使用 requestAnimationFrame API 而不是 setInterval,因为它将具有更好的整体性能。

清屏

此外,当您重新绘制屏幕时,只需在整个对象上以您想要的任何背景颜色绘制一个大矩形,然后再重新绘制您的项目。

ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);

将它们放在一起

这是一个演示所有这些技术的 fiddle :https://jsfiddle.net/jwcarroll/2r69j1ok/3/

关于javascript - 在 Canvas 上平滑地将对象从 A 移动到 B,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40472364/

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