- 原文地址:A gentle introduction to React Motion
- 原文做者:Nash Vail
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:doctype233
- 校对者:
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
咱们能够把蓝色的大按钮称为——主按钮, 从蓝色按钮上飞出的按钮称为——子按钮。后端
Fig. 1数组
子按钮拥有两种位置状态, 1) 子按钮均隐藏在主按钮后面的位置, 2) 子按钮在主按钮周围排列成一个圆圈的位置。浏览器
这里就出现了数学问题,咱们必须想出一种方法,在一个完美的圆中均匀地排列主按钮周围的子按钮。你能够经过试错法将这些值经过代码写死,但认真的说,谁会这么作呢?另外,一旦你找到正确的数学方法,只要你愿意你能够摆听任意多的子按钮,而他们都会自动排列本身。
首先让咱们了解几个术语。
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 来完成吧!
在下面的关键代码中,你将会看到发生什么,点击主按钮,咱们将 isOpen 的状态变量设置为 true (第85行)。一旦 isOpen 为 true,就会传递不一样的子按钮的样式(第97行,第66行,第75行)。
结果:
Fig. 7
好的,咱们在此处完成了不少操做,咱们在按钮上设置子按钮的初始位置和最终位置,如今咱们须要作的就是添加 React Motion 来激活在初始位置和最终位置之间的动画。
获取 几个参数 每一个参数是可选的,但咱们不关心这里的可选参数,由于咱们没有作任何与这个参数有关的事情。
其中 一个参数是 style, style 将做为参数传递到回调函数中,该函数包含内建的 interpolated values ,而后执行它的动画。
(第8行 : 由于正在React中执行迭代,因此须要将一个 key 参数传递给子组件。)
就像这样,
即便在这样作之后,结果也不会与图 Fig. 7 有所不一样,为何这么说?好吧,咱们还须要最后一步,使用_spring_。
正如前面提到的, 回调函数包含内建的值,也就是说, spring 帮助函数内建的值插入样式值。
咱们须要修改 initialChildButtonStyles 和 finalChildButtonStyles 并注意 top 和 left 被 spring 覆盖的值。这些是仅有的改变,如今,
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。
你可能还会喜欢
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。