在ReactJS上实现自由粒子运动

问候! 我想向您展示如何实现粒子在指定范围内自由移动的一种方式。 我将使用ReactJS完成此任务。 但是算法本身仍然是通用的,您可以在任何地方使用它。

图片

在本文的结尾,我们将与您一起创建一个这样的东西

错误的方式


解决此问题的第一件事就是将X和Y随机化。让我们看看会发生什么。


在这里,我们简单地将X和Y中每秒从-50到50范围内的移位随机化:

Math.random() * 100 - 50 

并且使用css transition属性可以平稳地进行过渡:

 transition: transform 1s linear; 

如您所见,结果并不完全是我们想要的。 当然,您可以对其进行配置,以便将班次添加到现有位置,这将更像是事实。 但是,我们仍然需要走一些不同的道路。

正确的方法


前面的方法似乎很歪,原因如下:

  1. 实际上,粒子不能如此突然地改变其方向。
  2. 每个时间段的粒子必须经过一定距离

这表明您需要在一定的度数范围内精确地随机化粒子的移动方向,以免出现急转弯。 因此,我们将解决第一个问题。

为了解决第二个问题,我们将提前指出在时间间隔内需要移动粒子的步骤。

现在,您必须记住三角学的基本过程。 我们知道长度l和角度deg 。 需要找到XY

图片

罪恶是对侧与斜边的比率。
cos是边与斜边的比率。

我们得到以下公式进行计算:

 x = cos(deg) * l y = sin(deg) * l 

但是有一件事。 在javaScript中, Math.sin以弧度表示一个角度( 值从-1到1 )。 因此,在投射角之前,必须先将其转换为弧度。

 deg() = deg() * Pi / 180 

我们编写了一个函数,该函数将在输入端接收角度,以及需要移动粒子的距离。 函数{ x, y }与我们的平移值将返回该函数。

 function getShift(deg, step) { return { x: +(Math.cos(deg * Math.PI / 180) * step).toFixed(), y: +(Math.sin(deg * Math.PI / 180) * step).toFixed(), }; }; 

我们将测试函数将输出什么。 假设我们每次将粒子移动10px 。 让我们看看不同角度的getShift返回什么。

图片

 getShift(30, 10); // {x: 9, y: 5} getShift(90, 10); // {x: 0, y: 10} getShift(135, 10); // {x: -7, y: 7} getShift(210, 10); // {x: -9, y: -5} getShift(-30, 10); // {x: 9, y: -5} 

好吧,看来,您是否同意?

现在尝试修复我们的第一个书面申请。


已经不错! 仍然需要实现一个框架,超出该框架,粒子将无法飞出。 从现在开始,很可能一段时间后,蓝色圆圈将从屏幕上飞走。

为了制作框架,您将需要添加一个新的常量。 并且还添加一个条件。 这是while循环为我们工作的地方。 如果路上有限制,那么我们将旋转拐角,直到从车架转弯为止。

为了清楚起见,请添加一个黄色正方形,超过该正方形该圆圈将无法飞出。 这是发生了什么:


我们的算法已完全可以使用。 下一步是使用其功能在ReactJS上实现此算法。

将算法移植到ReactJS


在将应用程序移植到ReactJS时,我们将为自己设置以下任务:

  1. 创建一个MovingPart包装器MovingPart ,您可以在其中放置任何东西。
  2. 在这种状态下,我们将存储X和Y的值,因为只需要它们即可重绘组件。
  3. 在外面,一个组件将被扔进一个间隔中,一个边界超出该边界是不可能的,并且一步将元素在一个时间间隔中移动。
  4. 让我们对MovingPart几个组件进行MovingPart ,以便粗略地设想它可以在现实生活中应用的地方

结果,我们得到以下示例:


我们将从data数组中获取初始数据。

之后,我们描述MovingPart组件:

  • 间隔(interval),距离(distance)和距离(step)的一步是我们从道具外面得到的;
  • 在元件内部确定运动过程中的最大旋转量(maxRotate)和当前移动角度(deg)
  • x和y的值被取出到组件的状态;
  • getShift方法定义为组件的内部方法。

之后,使用map循环渲染所有元素,并用我们创建的MovingPart组件包装它们。

感谢您的关注! 这是我关于哈布雷的第一篇文章,希望对您有用。 试试吧,实验。

Source: https://habr.com/ru/post/zh-CN440874/


All Articles