摘要:簡而言之,它將對動畫中變化的屬性數值做插值運算并且刷新視圖。注意我們所建立的的是的一個實例。最后我們使用,表示這個組件是可動畫組件。一直不停動動畫序列的方法可以傳一個回調函數,在動畫全部執行完時觸發。
翻譯自 React-native Animated API Basic Example
翻譯過程中有刪改
本文是探索 react-native 中實現的的 Animated API,Web 版本上的 React 沒有該 API,不過可以使用在 react-europe 大會上發布的 react-motion。
本文中將會完成一個動畫例子,效果如下圖
Animated API的原理并非通過 setState 方法使 react 重渲染,而是使用 setNativeProps 方法更新 native 視圖。
Animated API 導出了幾個特殊的 components:Animated.View, Animated.Text, 和 Animated.Image。Animated API 直接在 Objective-C 的 native 環境中調整這些 components 的外觀樣式,跳過了 JS 環境中 react 的 diff 與 reconciliation 過程,從而獲得流暢、高效的動畫。
簡而言之,它將對動畫中變化的屬性數值做插值運算并且刷新 native 視圖。
我們將實現一個簡單的動畫效果:沿手機屏幕四個邊,按照左上角 -> 左下角 -> 右下角 -> 右上角的順序,移動一個正方形。示意圖大概如下
< -- < | | V -- ^開始 導入依賴
import React, { AppRegistry, Component, Dimensions, StyleSheet, View, Animated } from "react-native"; const { width, height } = Dimensions.get("window"); const SQUARE_DIMENSIONS = 30;樣式
const styles = StyleSheet.create({ container: { flex: 1 }, square: { width: SQUARE_DIMENSIONS, height: SQUARE_DIMENSIONS, backgroundColor: "blue" } });基本邏輯
class AnimatedSquare extends Component { constructor(props) { super(props); this.state = { pan: new Animated.ValueXY() } } getStyle() { return [styles.square, { transform: this.state.pan.getTranslateTransform() }]; } render() { return (); } }
上面代碼中有幾個需要解釋的地方。
注意我們所建立的 component 的 state 是 Animated.ValueXY 的一個實例。這個 API 將在 X、Y 兩個值上進行插值。
getStyle() 方法,返回一個樣式對象數組。包括描述了方塊寬高大小的 square 基本樣式,以及最為重要的,一個 transform 樣式對象。
我們使用 getTranslateTransform 這個 Animated API 中的 helper 方法,來返回一個適合 transform 屬性結構的值。
這個返回值的結構類似于[{ translateX: xValue}, {translateY: yValue}],xValue 和 yValue 是計算后的插值。
最后我們使用 Animated.View,表示這個組件是可動畫組件。
移動正方形一開始正方形是靜止在左上角的,現在我們把它從左上角(x = 0, y = 0)移動到左下角(x = 0, y = (屏幕高 - 正方形高))
const SPRING_CONFIG = {tension: 2, friction: 3}; //Soft spring //... componentDidMount() { Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: 0, y: height - SQUARE_DIMENSIONS} // return to start }).start(); }
在組件裝載后,我們通過 Animated.spring 進行 Spring(彈性)動畫 ,我們給彈性動畫設置了 SPRING_CONFIG 配置,包括 tension(張力)和 friction(摩擦)值,所以正方形到達左下角后,會有一個小小回彈動畫。
再動,又動,還動我們會建立一個順序的動畫序列,讓動畫一個接一個進行。當然除了 sequence(順序),你還可以按 parallel(并行)組合動畫效果,讓動畫同時進行。
componentDidMount() { Animated.sequence([ Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: 0, y: height - SQUARE_DIMENSIONS} //animate to bottom left }), Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: width - SQUARE_DIMENSIONS, y: height - SQUARE_DIMENSIONS} // animated to bottom right }), Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: width - SQUARE_DIMENSIONS, y: 0} //animate to top right }), Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: 0, y: 0} // return to start }) ]).start(); }
如之前設想的一樣,我們定義了4個彈性動畫。注釋解釋了動畫移動方向。
一直不停動Animated.sequence(animtionList: Arrary).start(cb: Function);
動畫序列的start方法可以傳一個回調函數,在動畫全部執行完時觸發。在我們的例子中,這時候正方形回到了起點,我們可以重新開始一遍動畫。
componentDidMount() { this.startAndRepeat(); } startAndRepeat() { this.triggerAnimation(this.startAndRepeat); } triggerAnimation(cb) { Animated.sequence([ Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: 0, y: height - SQUARE_DIMENSIONS} //animate to bottom left }), Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: width - SQUARE_DIMENSIONS, y: height - SQUARE_DIMENSIONS} // animated to bottom right }), Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: width - SQUARE_DIMENSIONS, y: 0} //animate to top right }), Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: 0, y: 0} // return to start }) ]).start(cb); }
我們把動畫邏輯提取為一個方法,在完成回調函數中觸發它。
全部代碼import React, { AppRegistry, Component, Dimensions, StyleSheet, View, Animated } from "react-native"; const { width, height } = Dimensions.get("window"); const SQUARE_DIMENSIONS = 30; const SPRING_CONFIG = {tension: 2, friction: 3}; class AnimatedSquare extends Component { constructor(props) { super(props); this.state = { pan: new Animated.ValueXY() } } componentDidMount() { this.startAndRepeat(); } startAndRepeat() { this.triggerAnimation(this.startAndRepeat); } triggerAnimation(cb) { Animated.sequence([ Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: 0, y: height - SQUARE_DIMENSIONS} //animate to bottom left }), Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: width - SQUARE_DIMENSIONS, y: height - SQUARE_DIMENSIONS} // animated to bottom right }), Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: width - SQUARE_DIMENSIONS, y: 0} //animate to top right }), Animated.spring(this.state.pan, { ...SPRING_CONFIG, toValue: {x: 0, y: 0} // return to start }) ]).start(cb); } getStyle() { return [styles.square, { transform: this.state.pan.getTranslateTransform() }]; } render() { return (其它一些范例); } } const styles = StyleSheet.create({ container: { flex: 1 }, square: { width: SQUARE_DIMENSIONS, height: SQUARE_DIMENSIONS, backgroundColor: "blue" } }); AppRegistry.registerComponent("AnimatedSquare", () => AnimatedSquare);
react-native-animated-demo-tinder
UIExplorer Animated example
Cheng Lou – The State of Animation in React at react-europe 2015
react-motion – Github
React Native Animation API
Spencer Ahrens – React Native: Building Fluid User Experiences at react-europe 2015
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78952.html
摘要:面試如何防騙一份優秀的前端開發工程師簡歷是怎么樣的作為,有哪些一般人我都告訴他,但是他都不聽的忠告如何面試前端工程師 更多資源請Star:https://github.com/maidishike... 文章轉自:https://github.com/jsfront/mo... 3月份前端資源分享 1. Javascript 使用judge.js做信息判斷 javascript...
摘要:正在失業中的課多周刊第期我們的微信公眾號,更多精彩內容皆在微信公眾號,歡迎關注。若有幫助,請把課多周刊推薦給你的朋友,你的支持是我們最大的動力。是一種禍害譯本文淺談了在中關于的不好之處。淺談超時一運維的排查方式。 正在失業中的《課多周刊》(第3期) 我們的微信公眾號:fed-talk,更多精彩內容皆在微信公眾號,歡迎關注。 若有幫助,請把 課多周刊 推薦給你的朋友,你的支持是我們最大的...
摘要:正在失業中的課多周刊第期我們的微信公眾號,更多精彩內容皆在微信公眾號,歡迎關注。若有幫助,請把課多周刊推薦給你的朋友,你的支持是我們最大的動力。是一種禍害譯本文淺談了在中關于的不好之處。淺談超時一運維的排查方式。 正在失業中的《課多周刊》(第3期) 我們的微信公眾號:fed-talk,更多精彩內容皆在微信公眾號,歡迎關注。 若有幫助,請把 課多周刊 推薦給你的朋友,你的支持是我們最大的...
閱讀 4160·2021-11-22 13:52
閱讀 2074·2021-09-22 15:12
閱讀 1121·2019-08-30 15:53
閱讀 3455·2019-08-29 17:12
閱讀 2190·2019-08-29 16:23
閱讀 1647·2019-08-26 13:56
閱讀 1772·2019-08-26 13:44
閱讀 1880·2019-08-26 11:56