指南 · 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.jsximport { 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 }] } }} />;