如何在TailwindCSS中链式调用transform实现多阶段过渡动画效果?
原写法失效的原因
你在类名字符串里罗列多个transform相关原子类的写法本身是无效的:CSS同一时间只会给元素应用一个transform属性值,同类原子类同时存在时,优先级更高/后定义的类会直接覆盖前面的类,不存在按顺序执行的逻辑。
更推荐的解决方案:不需要用JS定时器,直接自定义CSS动画
你要的三阶段动画属于固定时序的动效,用CSS @keyframes 实现更稳定,不会出现定时器时序偏移、内存泄漏之类的问题,适配Tailwind的方式如下:
- 先在
tailwind.config.js中扩展自定义动画配置:
/** @type {import('tailwindcss').Config} */ module.exports = { theme: { extend: { keyframes: { barOpen: { '0%': { transform: 'translateX(0) rotate(-45deg)' }, '50%': { transform: 'translateX(-2px) rotate(0deg)' }, '100%': { transform: 'translateX(0) rotate(45deg)' }, } }, animation: { 'bar-open': 'barOpen 600ms ease-in-out forwards', } }, } }
这里总时长设为600ms,刚好前300ms执行从初始态到第二阶段的变换,后300ms执行第二到第三阶段的变换,forwards属性保证动画结束后停在最后一帧的状态。
- 直接在组件中调用自定义动画类即可:
const initialRotation = "-rotate-45" <div className={`absolute h-px w-3 bg-white text-white last:ml-2 transform ease-in-out ${toggled ? 'animate-bar-open' : initialRotation}`} />
如果你确实需要用JS控制类切换,才需要用到setTimeout
如果你的动画逻辑后续需要和其他交互联动,必须用JS控制状态,那可以用定时器做阶段切换,注意要在组件卸载时清除定时器避免内存泄漏:
import { useState, useEffect } from 'react' // 组件内部逻辑 const [toggled, setToggled] = useState(false) const [isSecondStageDone, setIsSecondStageDone] = useState(false) useEffect(() => { let timer if (toggled) { // 第二阶段300ms结束后切换到第三阶段类 timer = setTimeout(() => { setIsSecondStageDone(true) }, 300) } else { // 重置开关时同步重置阶段状态 setIsSecondStageDone(false) } // 组件卸载/依赖变化时清除定时器 return () => clearTimeout(timer) }, [toggled]) // 类名拼接逻辑 const barClass = `absolute h-px w-3 bg-white text-white last:ml-2 transform ease-in-out duration-300` const finalClass = toggled ? isSecondStageDone ? 'rotate-45 translate-x-0' : 'rotate-0 translate-x-[-2px]' : '-rotate-45 translate-x-0' <div className={`${barClass} ${finalClass}`} />
内容的提问来源于stack exchange,提问作者Darkbound
相关产品推荐
相关产品推荐

