首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从A到B的物体在画布上的平滑移动

从A到B的物体在画布上的平滑移动
EN

Stack Overflow用户
提问于 2016-11-07 18:46:47
回答 1查看 5K关注 0票数 1

我试图使用HTML画布和常规的javascript将一个对象从A点顺利地移动到B点。

点A是一组坐标

B点在光标位置的情况下。

到目前为止,我对我所做的一切都做了些微调:https://jsfiddle.net/as9fhmw8/

代码语言:javascript
复制
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循环变慢(这样它看起来就像动画一样,而不是仅仅遍历每一次迭代并显示结果)。

我也想不出如何防止弧复制,这样它创造了一条线是永久的,而不是看起来从点a到点b。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-11-07 20:36:25

这里的流畅动画实际上是确定在循环的每一次迭代中移动对象的距离。

这里涉及一些数学问题,但也不算太糟。

速度

在你的情况下,速度就是你的粒子在一段时间内沿着任何给定的方向运动的速度。如果你想让你的粒子在4秒内运行200px,那么速度将是50px / second

有了这些信息,您可以很容易地确定在给定任意时间长度的情况下移动(动画)粒子的像素数。

pixels = pixelsPerSecond * seconds

这是很好的知道多少像素移动,但没有转换成单独的X和Y坐标。这就是向量进入的地方。

向量

数学中的向量是一个方向和大小的度量。为了我们的目的,这就像把我们的速度和一个角度(47°)结合在一起。

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

因此,如果我们想以50px / second角度移动粒子,我们可以计算出这样的矢量:

代码语言:javascript
复制
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坐标中,根据速度计算来移动它们。

鼠标移动向量

以这种方式对对象进行建模有一个额外的好处,那就是使事情变得更好,并且在数学上保持一致。你的粒子和鼠标之间的距离只是另一个矢量。

我们可以用更多的数学来计算距离和角度。还记得那个毕达哥拉斯吗?结果发现他很聪明。

代码语言:javascript
复制
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,因为它具有更好的总体性能。

清除屏幕

同样,当你重新绘制屏幕时,只要在重新绘制你的项目之前,用你想要的任何背景颜色在整个物体上画一个大矩形就行了。

代码语言:javascript
复制
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);

把所有的东西都放在一起

下面是演示所有这些技术的Fiddle:https://jsfiddle.net/jwcarroll/2r69j1ok/3/

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40472364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档