iT邦幫忙

2021 iThome 鐵人賽

DAY 16
1
Mobile Development

卡卡30天學 React Native系列 第 16

[ 卡卡 DAY 16 ] - React Native Animated 入門 + useNativeDriver 好棒棒

React Native 提供了 Animated 及 LayoutAnimation API
給使用者有良好的體驗加點動畫是必須的

Animated API

概念

Animated 是 React Native 原生的套件,可以運用內建的 func 來控制動畫使動畫變得更流暢。
通過綁定 Animated.Value 到 View 的 styles 或者 props 上,然後通過 Animated.timing() ... 等方法操作 Animated.Value 進而更新動畫。

  • Animated.event() 關聯 Animated.Value 到某一個 View 的事件上
  • Animated.Value() 用於單個值
  • Animated.ValueXY() 用於矢量值
  • useNativeDriver 使用之後,頁面更新就沒有 JS 的參與,直接都在 Native 的 UI 線程渲染。

Animated.Valued 可以綁定樣式,也可以進行插值運算。單個 Animated.Value 可以用在任意多個屬性上。
深入請看doc

動畫配置

其實跟 css 的動畫很像,Animated 提供了三種動畫類型:

  1. Animated.decay() 初始數度越來越來再來停下
  2. Animated.spring() 彈簧效果
  3. Animated.timing() 使用 easing 函数讓數值隨時間動起來

大家都比較常使用 timing()。default 時 easeInOut 曲線,指定物會逐漸變快到指定數度然後慢慢減慢到停止。
運用 start() 開始
運用 stop() 結束

Animated.timing({}).start(({ finished }) => {
  /* 動畫完成的數值 */
});

開始前先來講一下 useNativeDriver(bool)

這是含在動畫配置裡面的參數,主要是啟用原生動畫的驅動。

什麼意思呢?需要用嗎?哪個比較好呢?

在 React Native 當動畫運轉時有兩個情形:

  • JS tread 計算 + Animation by Native OS (useNativeDriver:false)
  1. compute
  2. serialize
  3. transfer it over the bridge to host OS
  4. deserialize
  5. run the frame
  • Everything by Native OS (useNativeDriver:true)
  1. before your animation starts -> serialize whole animation thing
  2. Native OS would deserialize it

相對起來使用 useNativeDriver:true 的步驟少了很多,實際的優勢有以下:

  1. no more over the bridge transfers
  2. JS thread is now free for other stuff
  3. smoother animations

所以建議使用 useNativeDriver:true 唷!可參考這影片驗證給你看~~

一二三照著做簡單動畫

實作前提
useRef:參考變數,只要 App 沒有完全關閉,useRef 記錄的參考變數就不會消失(類似於全域變數的效果)
useEffect:componentDidMount 階段

  1. 於 components/ 建一個 AnimatedFade.js

    import { Animated } from 'react-native';
    import React, { useRef, useEffect } from "react";
    
  2. 設定初始值

    const fadeIn = useRef(new Animated.Value(0)).current;
    
  3. 使用一個 Animated.View 來顯示畫面 return

     <Animated.View
       style={{
         ...props.style,
         opacity: fadeIn,
       }}>
       {props.children}
     </Animated.View>
    
  4. 於 useEffect 畫面一進來時做出動畫的效果

    useEffect(() => {
        Animated.timing(fadeIn, {
             toValue: 1,
             duration: 1000,
             useNativeDriver: true,
        }).start();
    }, [fadeIn]);
    
    

完整的 AnimatedFade.js

```
import React, {useRef, useEffect} from 'react';

import {Animated} from 'react-native';
const AnimatedFade = props => {
const fadeIn = useRef(new Animated.Value(0)).current;

useEffect(() => {
Animated.timing(fadeIn, {
    toValue: 1,
    duration: 3000,
    useNativeDriver: true,
    }).start();
}, [fadeIn]);

return (
    <Animated.View
    style={{
        ...props.style,
            opacity: fadeIn,
    }}>
        {props.children}
    </Animated.View>
    );
};

export default AnimatedFade;
```
  1. 於 Screens/ 建立 AnimatedScreen.js

     import React from 'react';
     import {View, Text, StyleSheet, Image} from 'react-native';
     import AnimatedFade from '../components/AnimatedFade';
     import {assets} from '../constants';
    
     const IconScreen = () => {
         return (
         <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
             <AnimatedFade>
                 <Image source={assets.water} />
                 <Text style={styles.text}>我出現嚕!</Text>
             </AnimatedFade>
         </View>
         );
     };
     const styles = StyleSheet.create({
         text: {
             width: 300,
             height: 30,
             textAlign: 'center',
             lineHeight: 30,
             backgroundColor: 'pink',
         },
     });
    
     export default IconScreen;
    
  2. 並用之前 navigation 教的把頁面放入 stack 中即可看到動畫拉!!!

https://ithelp.ithome.com.tw/upload/images/20210929/20142011qUT9SCN75k.jpg

https://ithelp.ithome.com.tw/upload/images/20210929/20142011kftDaq63jr.jpg
基於還不知道怎麼用 gif 上來

所以請大家看我按了那個動畫按鈕之後西瓜就慢慢的 fade 進來拉 <3

Day 17 done 簡單的 Animated,請多多指教~


上一篇
[ 卡卡 DAY 15 ] - React Native 頁面導覽 Navigation (下)
下一篇
[ 卡卡 DAY 17 ] - React Native 用 Animated 來做簡單骨架屏
系列文
卡卡30天學 React Native31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
喬叔
iT邦新手 4 級 ‧ 2021-10-01 00:46:04

我也剛好想研究一下做 gif 動畫這件事,有些東西截圖真的不容易說明~
我用 mac, 查到這個試了一下好像還行!
https://blog.dreambreakerx.com/2019/06/licecap-gif-recorder/

謝謝~~mac 昨天我找到一個不錯的~~~
https://ithelp.ithome.com.tw/upload/images/20211001/20142011AI0E6hEM55.png

我要留言

立即登入留言