Framer Motion:如何让元素始终居中于屏幕(含动画)
问题解决:Framer Motion 初始居中与最终自适应居中
核心问题分析
- 初始元素未从页面中心启动:当前代码使用固定像素值定义初始位置,无法适配不同屏幕尺寸,且父容器布局未确保初始状态下元素处于视口中心。
- 最终文本无法自适应居中:动画结束后的
x值为固定像素,在不同屏幕宽度下会导致整体文本偏移,破坏居中布局。
解决方案代码
import { motion } from 'framer-motion'; import Image from 'next/image'; // 若未使用Next.js,替换为原生img标签即可 export const HeroSection: React.FC = () => { return ( {/* 占满视口高度,确保垂直方向居中 */} <section className='flex flex-col justify-center items-center min-h-screen w-full text-4xl md:text-5xl lg:text-6xl xl:text-7xl'> <div className='text-white font-bold'> <motion.div className='flex justify-center items-center'> {/* 初始在中心,动画左移并显示AN */} <motion.div className='flex' initial={{ x: 0 }} animate={{ x: '-20%' }} // 用百分比替代固定像素,适配全屏幕 transition={{ duration: 3, delay: 2 }} > <h1>D</h1> <motion.h1 className='opacity-0' initial={{ opacity: 0 }} // 仅用opacity控制显示,避免布局跳动 animate={{ opacity: 1 }} transition={{ ease: 'linear', duration: 3, delay: 5, }} > AN </motion.h1> </motion.div> {/* 初始在中心,动画右移并显示ECU */} <motion.div className='flex' initial={{ x: 0 }} animate={{ x: '20%' }} // 百分比偏移保证自适应 transition={{ duration: 3, delay: 2 }} > <h1>J</h1> <motion.h1 className='opacity-0' initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ ease: 'linear', duration: 3, delay: 5, }} > ECU </motion.h1> </motion.div> </motion.div> </div> <Image alt='down-arrow' src='/down-arrow.png' width='50' height='50' className='filter invert animate-bounce opacity-60 pb-12' /> </section> ); };
关键修改说明
- 视口垂直居中:给
section添加min-h-screen,结合flex flex-col justify-center确保内容始终垂直居中于视口。 - 初始中心启动:将两个动画元素的初始位置设为
x: 0,依赖父容器的justify-center让元素从中心开始动画。 - 自适应动画位置:用百分比值替代固定像素的偏移量,确保在不同屏幕尺寸下动画比例一致,最终整体文本仍保持居中。
- 避免布局跳动:移除
display: hidden,仅通过opacity控制文本显示/隐藏,防止动画过程中布局重排导致的跳动。
内容的提问来源于stack exchange,提问作者SamePop20
相关产品推荐
相关产品推荐

