Framer Motion 简介
Framer Motion 是一个面向创意专业人士的 Web 构建器、简单但功能强大的 React 运动库。
- framer motion 官方网站
- framer 一个设计网站
- framer-motion-3d framer 3d 代码托管 仓库
- framer-motion npm 地址
特点
- Framer Motion 是 React 生产级的动画库。
- Framer Motion 目前支持 React18、React 组件和 React Hooks。
- Framer Motion 支持过渡动画、布局动画、关键帧动画、进入-退出动画、动画变种、手势动画、滚动动画、3D动画和无障碍等。
- ...
组件
Framer Motion 可以基于 React 组件完成动画编码工作:
function Component() {
return <div>
<motion.div /> // 运动组件是针对 60fps 动画和手势优化的 DOM 基元。
<AnimatePresence /> // 当组件从 React 树中删除时,对其进行动画处理。
<LayoutGroup /> // 将应一起执行布局动画的运动组件分组。
<LazyMotion /> // 过延迟加载 Motion 功能的子集来减小包大小。
<MotionConfig /> // 设置 Framer Motion 的配置选项。
<Reorder /> // 使用一组简单的组件创建拖动重新排序效果。
</div>
}
motion 值
使用钩子函数创建 motion value
动画或视频制作过程中,每一帧的运动值。这可以理解为每一帧中对象的位置、旋转、缩放等属性的变化。这些变化值描述了动画的运动轨迹和动态效果。
function Ho() {
const e = useMotionValueEvent(); // 订阅来自 React 组件的运动值事件。
const t = useMotionTemplate(); // 通过字符串模板将多个运动值合并为一个新值。
const s = useScroll(); // 使用 useScroll 挂钩创建滚动链接动画。
const sp = useSpring(); // 通过弹簧使其目标产生动画的运动值。
const ti = useTime(); // 一个运动值,用于更新每个动画帧自创建以来的持续时间(以毫秒为单位)。
const tr = useTransform(); // 创建一个新的运动值来转换一个或多个其他运动值的输出。
const v = useVelocity(); // 创建一个跟踪另一个速度的运动值。
const wc = useWillChange(); // 自动管理将更改的 CSS 属性以优化性能。
}
通用函数
api | 简介 |
---|---|
animate | 手动管理和控制动画 |
scroll | 基于 ScrollTimeline创建滚动链接动画 |
inView | 当元素进入和离开视口时触发回调 |
transform | 创建一个函数,将值从一个范围映射到另一个范围。 |
stagger | 跨元素交错动画的函数。 |
frame | 安排一个函数在 Motion 的动画循环上运行。 |
easing function | 一组强大的缓动函数,可与任何动画库一起使用 |
hooks
钩子 | 简介 |
---|---|
useAnimate | 使用范围选择器和自动清理创建动画函数。 |
useAnimationFrame | 将最新帧时间输出到所提供的回调的动画循环。 |
useDragControls | 手动开始/停止拖动运动组件。 |
useInView | 当元素位于视口内时的简单状态挂钩。 |
useReducedMotion | 确定用户是否喜欢减少动作的钩子。 |
3D
Framer Motion 3D 是一个简单但功能强大的 React Three Fiber 动画库。
- 安装:npm install three @react-three/fiber framer-motion-3d
- 基本用法:
import { motion } from "framer-motion-3d"
function App() {
return <motion.pointLight animate={{ x: 2 }} />
}
相机和canvas 画布
import { MotionCanvas, LayoutCamera } from "framer-motion-3d"
export function Scene() {
<MotionCanvas>
<LayoutCamera position={[0, 0, 5]} />
<Box />
</MotionCanvas>
}
过渡
import { motion } from "framer-motion";
const AnimatedDiv = () => {
return (
<motion.div
animate={{ x: 100, opacity: 0.5 }}
transition={{ duration: 1 }}
>
Hello, Framer Motion!
</motion.div>
);
};
过渡动画的其他类型:
- tween
- spring
- inertia
变体动画
const variants = {
hidden: { opacity: 0 },
visible: { opacity: 1 }
};
<motion.div
initial="hidden"
animate="visible"
variants={variants}
>
Hello, Framer Motion!
</motion.div>
使用 initial 和 animate 指定变体类型,variants 指定变体样式。
手势动画
- hover
- tap
- 拖拽
<motion.div
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
>
Hover me!
</motion.div>
使用 whileHover 指定 hover 动画,使用 whileTap 指定 tap 动画。
使用拖拽添加拖拽即可:
import { motion } from "framer-motion"
export const MyComponent = () => (
<motion.div
drag
dragConstraints={{
top: -50,
left: -50,
right: 50,
bottom: 50,
}}
/>
)
布局动画
- 属性:layout(layoutId)
- 属性:layoutRoot (存在父子关系时)
- 组件:LayoutGroup 组件
function Accordion() {
const [isOpen, setOpen] = useState(false)
return (
<motion.div
layout
style={{ height: isOpen ? "100px" : "500px" }}
onClick={() => setOpen(!isOpen)}
/>
)
}
当我们的元素布局发生了变化的时候,我们就可以使用 layout 属性。
SVG 动画
线条
<motion.circle />
<motion.line />
路径
function DSvg() {
return <svg width="400" height="400">
<g transform="translate(10 10) scale(17 17)">
<motion.path fill={fill} d={path} />
</g>
</svg>
}
路由动画
路由之间切换的有时候也非常重要 motion 可以使用 AnimatePresence
实现淡入淡出效果。
function App() {
return <AnimatePresence mode="wait">
{your_component}
</AnimatePresence>
}
官方示例
Remix Motion Learn 复刻一个官方的示例。需要学习的小伙伴可以学习一下。
总结
本文主要试图全面了解 frame-motion 的功能,frame-motion 简单易用,能简化动画的开发,同时也提供了 Reduced Motion
减少动画无障碍方案。开源免费值得学习。希望能够帮助到大家。