[譯] 關於 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前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索