指南 · 03

Animated 元件

渲染一般元素,讓它們移動到目的地、回應手勢並優雅地離場。

Animated.<tag>

Animated.div、Animated.button、Animated.svg 以及其他所有 HTML 或 SVG 標籤,都會渲染沒有包裝層的一般元素。它們的 style 接受值,transform 可以像 React Native 一樣寫成陣列。

這些元素上有限的 transform 與 opacity 動態(包括彈簧)可以由瀏覽器播放。

正在準備範例…

seed、pose、poses 與 tempo

seed 是第一格,pose 是目前的目的地(一個物件,或 poses 中某一項的名稱),tempo 是時間曲線或彈簧。只改 tempo 不會重播沒有改變的目的地。

元素抵達時會觸發 onRest。

Card.jsx
<Animated.article
  seed={{ opacity: 0, transform: [{ translateY: 16 }] }}
  pose={selected ? 'raised' : 'rest'}
  poses={{
    rest: { opacity: 1, transform: [{ translateY: 0 }, { scale: 1 }] },
    raised: { opacity: 1, transform: [{ translateY: -8 }, { scale: 1.04 }] },
  }}
  tempo={{ spring: { stiffness: 300, damping: 26 } }}
  onRest={() => console.log('arrived')}
/>;

回應手勢

respond 把手勢對應到暫時的目的地:hover、focus、focusWithin、press、longPress、drag、inView 等。回應結束時,元素會從當下所在的位置回到自己的 pose。

onResponse 會回報每個邊緣;respond={{ press: {} }} 只觀察手勢,不改變任何視覺效果。

正在準備範例…

用 Animated.Scope 共用預設值

Animated.Scope 會把 pose 名稱、tempo 與動畫預設值傳給其內的 Animated 元素。

Menu.jsx
<Animated.Scope tempo={{ spring: { stiffness: 380, damping: 30 } }}>
  <Animated.li pose={{ opacity: 1 }} />
  <Animated.li pose={{ opacity: 1 }} />
</Animated.Scope>;

你自己的元件

Animated.wrap(Component)(在 React Native 中是 createAnimatedComponent)能讓一個轉發 ref、最後解析為單一 DOM 元素的元件接受同樣的 props。

Link.jsx
import { forwardRef } from 'react';
import { Animated } from '@kkwaenggwari/animated';

const Link = forwardRef((props, ref) => <a ref={ref} {...props} />);
const AnimatedLink = Animated.wrap(Link);

<AnimatedLink href="/pricing" respond={{ hover: { transform: [{ translateX: 4 }] } }} />;

搜尋

輸入關鍵字搜尋文件。