我模仿 Facebook 的 Paper 應用構建了一個開閉卡片的輪播效果做爲技術演示.它使用了 React Native 及其動畫庫.前端
當人們聽到 React Native 後第一反應會以爲它運行緩慢.這是由於通常人會去這樣解釋 React Native: "它容許你經過 Javascript 構建你的應用程序",而人們會認爲瀏覽器中運行的 JavaScript 性能並不夠好.react
但事實是,它採用的所有都是原生界面元素.但你經過 React Native 構建界面時, 每次都會實例化 Android 和 iOS 的原生 UI.所以,相比於比較沉重的 DOM 結構它是至關請輕量的.git
下面一段介紹:我是如何着手構建相似 Facebook 的 Paper 應用的交互效果的. 咱們能夠放大和縮小輪播圖,在動畫進行的時候,咱們也能夠中止它.github
先來看看它是什麼樣子:web
上面的屏幕截圖,是從我所構建的 App 中截出來的. 左邊是當前縮小的卡片列表.您能夠滑動它們.您也能夠把它拉起來,讓它們變成全屏. 如今你能夠在全屏狀態下滑動卡片,一個接一個. 咱們來與下面 Facebook Paper應用的交互模型來進行比較.vim
點這裏查看 Youtube 上的視頻react-native
咱們以實例化兩個狀態變量開始.一個用於存儲 pan 值,另外一個存儲動畫進度:從0到1.這一進展變量是基於 pan 值進行插值.瀏覽器
let pan = new Animated.ValueXY(); this.state = { pan: pan, dockAnimation: pan.y.interpolate({ inputRange: [-300, 0], outputRange: [0, 1], }) }
如今,咱們須要建立一個 panResponder. 這是一個複雜的手勢操控的概念,它判斷何時應該激活手勢以及們完成事件的各類方法.在咱們的例子中,咱們要在手勢正在進行和結束對它進行跟蹤.微信
this._panResponder = PanResponder.create({ onStartShouldSetPanResponder: (evt, gestureState) => true, onStartShouldSetPanResponderCapture: (evt, gestureState) => true, onMoveShouldSetPanResponder: (evt, gestureState) => true, onMoveShouldSetPanResponderCapture: (evt, gestureState) => true, onPanResponderGrant: () => {}, onPanResponderMove: Animated.event([null, {dx: this.state.pan.x, dy: this.state.pan.y}]), onPanResponderRelease: (evt, gestureState) => { // dragging stopped, animate the item to the correct position } })
在實際代碼中能夠看到看到 onPanResponderRelease 塊的所有實現.它作的很簡單:決定用戶是否已經拖遠遠,並切換 state 的值.若是是,繪製這個動畫.ide
transform: [{ scale: this.state.dockAnimation.interpolate({ inputRange: [0, 1], outputRange: [1, 0.5], }) }
多種變換被以 ListView 的 style 的方式應用. 我已經用 scale 變換做爲例子展現了,再一次,咱們使用插值來控制動畫.
<AnimatedListView style={this.getListViewStyle()} {...this._panResponder.panHandlers} />
最後,styles 和 panResponder 的 panResponder 都被綁定到了 ListView. 須要注意的是在咱們建立了一個一個組合式的 ListView: AnimatedListView,這樣的動畫庫能夠從樣式對象解析出動畫的值.
這就是咱們須要爲動畫作的全部事情!剩下的就是使用 Flex 佈局來構建那些漂亮的卡片.Jason Brown 寫了一本有關React Native動畫庫的好書:http://browniefed.com/react-n...
我在 Github 上共享了全部的代碼,你能夠自由修改它!
paramaggarwal/rn-paper-interface
<iframe src="https://player.vimeo.com/vide... width="640" height="1137" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
目前,我只在iOS上運行過.可是你能夠嘗試在 Android 上運行,並在 github 上打開一個 PR. 我沒有用過任何的 iOS 特定的 API, 因此理論上,它應該在 Android 上工做.
做者信息
原文做者:Param Aggarwal
原文連接:http://t.cn/RtnSJwA
翻譯自力譜宿雲 LeapCloud旗下MaxLeap團隊_UX成員:Jason
中文首發地址:https://blog.maxleap.cn/archi...
譯者簡介:MaxLeap UX 組負責人,負責前端開發,客戶端/部分服務端 SDK 開發及開發者用戶體驗優化相關工做. 持續關注新技術,熱愛產品, 熱衷全棧/全端開發. 曾供職於搜狐搜狐武漢研究院,後投身 MaxLeap致力於爲開發者提供快速高效的開發體驗.
相關文章
ReactJS 開發過程當中的一些使用心得
在 React Web 和 原生 App 中共享代碼
React Native 一週年回顧
React.js 最佳實踐(2016)
做者往期做品:
在 React Web 和 原生 App 中共享代碼
React.js 最佳實踐(2016)
活動預告
報名連接:http://t.cn/Rt9ooRw
歡迎關注微信公衆號:MaxLeap_yidongyanfa