blog 新的动画效果
- Published on
- Authors
- Name
- Wxm
页面出现的线性的动画,之前在刚开始重构 blog 时就想实现,不过因为当时比较忙,就暂时搁置了,最近有空,就还是使用 motion 库来实现一下。
需要实现的效果
页面元素依次出现,首先是过渡动画包括 opacity blur X 这三部分的变化,并且需要有一个 delay 的效果,让元素一个一个的出现。
实现思路
opacity blur X 这种变化,使用 motion 实现十分简单,甚至用原生 js 也很简单,问题在于 delay 的效果。页面有很多元素 甚至包括需要渲染的列表,如果一个一个添加恐怕是十分浪费时间。
花了一点时间仔细查了 motion 的文档,发现一个好东西 staggerChildren
(文档) ,使用这个配合 variants
属性,可以轻松实现元素和子元素的依次出现。
代码
先新建一个 motionVariants.tsx
组件重复调用。在其中定义 containerVariants
和 itemVariants
。
export const containerVariants = {
hidden: {
opacity: 0,
filter: "blur(8px)",
transform: "translateY(16px) translateZ(0)",
},
visible: {
opacity: 1,
filter: "blur(0)",
transform: "none",
transition: {
transform: { duration: 0.4, timeConstant: 750 },
opacity: { duration: 0.7, timeConstant: 350 },
filter: { duration: 0.8, timeConstant: 350 },
type: "tween",
duration: 0.6,
ease: [0.25, 0.3, 0.5, 1],
delayChildren: 0,
// staggerChildren: 0.12, // 每个子项之间的延迟时间
staggerChildren: 0.08, // 每个子项之间的延迟时间
},
},
};
export const itemVariants = {
hidden: {
opacity: 0,
filter: "blur(8px)",
transform: "translateY(16px) translateZ(0)",
transition: {},
},
visible: {
opacity: 1,
filter: "blur(0)",
transform: "none",
transition: {
transform: { duration: 0.2, timeConstant: 350 },
opacity: { duration: 0.4, timeConstant: 350 },
filter: { duration: 0.4, timeConstant: 350 },
duration: 0.4,
ease: [0.25, 0.3, 0.5, 1],
},
},
};
在你的组件中添加效果
import { motion } from 'framer-motion'
import { containerVariants, itemVariants } from '@/components/MyMotion'
return (
<>
<motion.div variants={containerVariants} initial="hidden" animate="visible">
<motion.div variants={itemVariants}>
<h2>title</h2>
</motion.div>
<motion.div variants={itemVariants}>
<p>body</p>
</motion.div>
<motion.div variants={itemVariants}>
<p>link</p>
</motion.div>
</div>
</>
)
}