描述图片

blog 新的动画效果

Published on
Authors
  • Name
    Wxm
    Twitter

页面出现的线性的动画,之前在刚开始重构 blog 时就想实现,不过因为当时比较忙,就暂时搁置了,最近有空,就还是使用 motion 库来实现一下。

需要实现的效果

页面元素依次出现,首先是过渡动画包括 opacity blur X 这三部分的变化,并且需要有一个 delay 的效果,让元素一个一个的出现。

实现思路

opacity blur X 这种变化,使用 motion 实现十分简单,甚至用原生 js 也很简单,问题在于 delay 的效果。页面有很多元素 甚至包括需要渲染的列表,如果一个一个添加恐怕是十分浪费时间。

花了一点时间仔细查了 motion 的文档,发现一个好东西 staggerChildren (文档) ,使用这个配合 variants 属性,可以轻松实现元素和子元素的依次出现。

代码

先新建一个 motionVariants.tsx 组件重复调用。在其中定义 containerVariantsitemVariants

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>
    </>
  )
}

最终效果

0:00/0:00

植松伸夫 - フィナーレ

植松伸夫 - プレリュード

笹井隆司 - 異郷の町

伊藤賢治 - Rising Sun

植松伸夫 - 街のテーマ

植松伸夫 - 怒闘

植松伸夫 - コーネリア城

植松伸夫 - チョコボのテーマ