[译] 关于 React Motion 的简要介绍

React 很棒,在过去的几周里,我用它玩得很开心,因此我决定尝试一下React Motion。一开始 API 就让我感到有困惑和棘手,可是最终一切开始变得有意义,不过这须要时间。遗憾的是,我在网上找不到合适的 React Motion 教程,因此我决定把这篇文章写出来,不只是做为一个开发者们的资源,也能给我本身做参考。前端

React Motion 对外暴露三个主要的组件:Motion, StaggeredMotion 和 TransitionMotion。在本教程中,咱们将一块儿看一看 Motion 组件,以后你会发现将在这一部分花费大量时间。react

因为这是一个 React Motion 教程,因此我将假设你有点熟悉 React 以及 ES2015。android

咱们将在使用 React Motion 从新建立 一个 Framerjs 的例子 时探索 API。你能够在这找到代码的最终版本 在这ios

最终效果git

咱们首先要研究一点数学问题,可是不要担忧,我会尽量详细地解释每个步骤。你能够直接跳过这一部分到 React.start(); 部分。github

准备好了吗? 那就开始吧...spring

Math.start();

咱们能够把蓝色的大按钮称为——主按钮, 从蓝色按钮上飞出的按钮称为——子按钮。后端

Fig. 1数组

子按钮拥有两种位置状态, 1) 子按钮均隐藏在主按钮后面的位置, 2) 子按钮在主按钮周围排列成一个圆圈的位置。浏览器

这里就出现了数学问题,咱们必须想出一种方法,在一个完美的圆中均匀地排列主按钮周围的子按钮。你能够经过试错法将这些值经过代码写死,但认真的说,谁会这么作呢?另外,一旦你找到正确的数学方法,只要你愿意你能够摆听任意多的子按钮,而他们都会自动排列本身。

首先让咱们了解几个术语。

M_X, M_Y

Fig. 2

M_X, M_Y 分别表示以主按钮为中心的 X 和 Y 坐标。(M_X, M_Y) 这个点将用做计算每一个子按钮的距离和方向的参考。

每一个子按钮最初都隐藏在主按钮中心的后面,中心坐标为 M_X, M_Y。

分离角、扇形角、飞出半径

Fig. 3

飞出半径为子按钮飞出后距离主按钮的距离,其余两个词语的释义看起来不言自明。

还须要注意一个地方,

扇形角 = (子按钮数-1) * 分离角

如今,咱们须要设计一个函数,该函数接收子按钮 (0, 1, 2, 3 …) 的索引,并返回子按钮的新位置的 x 和 y 的坐标。

基准角、索引

Fig. 4

因为一般来讲三角学中的角度是从 x 轴的正方向测量的,咱们将从相反的方向(右到左)开始给咱们的子按钮编号。这样,之后咱们就没必要在每次须要子按钮的最后位置时乘以负一。

当咱们看到它时,请注意 (参见 Fig. 3)

基准角 = (180 — 扇形角)/2

(必定程度上)。

Fig. 5

每一个子按钮都有它本身的角度,我称之为角。这个角是计算子按钮最终位置所需的最后一条信息。

请注意, (参见 Fig. 3, Fig. 4)

索引为 i 的子按钮的角度 = 基准角 + ( i * 分离角)

如今,一旦咱们有了每一个子按钮的角,

Fig. 6

咱们就可以为每一个子按钮计算 增量X and 增量Y

请注意 (参见 Fig. 2),

子按钮的最终 X 轴坐标 = M_X + 增量X

子按钮的最终 Y 轴坐标 = M_Y - 增量Y

(咱们从 M_Y 中减去增量X,由于不一样于原点在左下角的通常坐标系,浏览器的原点在左上角,因此为了方便移动,你能够下降他们 y 轴坐标的值。)

因此,这些就是咱们所须要的数学方法,如今咱们有两样东西:每一个子按钮的初始位置 (M_X, M_Y) 和子按钮的最终位置,剩下的魔发就交由 React 来完成吧!

React.start();

在下面的关键代码中,你将会看到发生什么,点击主按钮,咱们将 isOpen 的状态变量设置为 true (第85行)。一旦 isOpen 为 true,就会传递不一样的子按钮的样式(第97行,第66行,第75行)。

结果:

Fig. 7

好的,咱们在此处完成了不少操做,咱们在按钮上设置子按钮的初始位置和最终位置,如今咱们须要作的就是添加 React Motion 来激活在初始位置和最终位置之间的动画。

React-Motion.start();

获取 几个参数 每一个参数是可选的,但咱们不关心这里的可选参数,由于咱们没有作任何与这个参数有关的事情。

其中 一个参数是 style, style 将做为参数传递到回调函数中,该函数包含内建的 interpolated values ,而后执行它的动画。

(第8行 : 由于正在React中执行迭代,因此须要将一个 key 参数传递给子组件。)

就像这样,

即便在这样作之后,结果也不会与图 Fig. 7 有所不一样,为何这么说?好吧,咱们还须要最后一步,使用_spring_。

正如前面提到的, 回调函数包含内建的值,也就是说, spring 帮助函数内建的值插入样式值。

咱们须要修改 initialChildButtonStylesfinalChildButtonStyles 并注意 topleftspring 覆盖的值。这些是仅有的改变,如今,

Fig. 8

spring 可选地接收第二个参数,这是一个包含两个数字的数组 [Stiffness, damping],默认值为[170,26],这致使了上图 Fig. 8 中呈现的结果。

将 Stiffness 视为动画发生的速度,这不是一个很是精确的假设,只是速度越大的值越大。Dampness 是一个晃动效果参数,不过相反的,值越小,晃动效果越明显。

能够看看这个

[320, 8] — Fig. 9

[320, 17] — Fig. 10

咱们离最终完成很近了,可是尚未。若是咱们在每次下一个子按钮开始动画前添加延迟会怎样?为了达到最终效果,这正是咱们须要作的,但这样作并不那么简单,我不得不把每一个运动组件以数组的形式存储到状态变量中,而后一个一个地为每一个子按钮改变状态以达到指望的效果,代码就像这样

this.state = {  
    isOpen: false,  
    childButtons: []  
};
复制代码

而后在 componentDidMount 方法中添加 childButtons

componentDidMount() {  
    let childButtons = [];  
     range(NUM_CHILDREN).forEach(index => {  
        childButtons.push(this.renderChildButton(index));  
    });

    this.setState({childButtons: childButtons.slice(0)});  
 }
复制代码

最终打开菜单功能得以实现:

咱们在这里作了一些美学的调整,如添加图标和一些旋转效果,咱们获得最终效果以下。

方法已覆盖,你能够设置任何数量的子按钮

NUM_CHILDREN = 1

NUM_CHILDREN = 3

NUM_CHILDREN = 8

至关酷对吗? 再说一遍,你能够 在这找到相应代码。若是你以为这篇文章有帮助,请点击下面的推荐按钮。

若是有一些问题、评论、建议或仅仅是想聊个天?能够在 Twitter 上找到我 @NashVail 或者给我发电子邮件 hello@nashvail.me


你可能还会喜欢

  1. Let’s settle ‘this’ — Part One
  2. Let’s settle ‘this’ — Part Two
  3. Designing the perfect wallpaper app

若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索