如何在React项目中实现Ant Design官网同款主题切换动画?
实现Ant Design官网式主题切换圆形扩散动画
核心思路
这个效果的核心是做一个跟随点击位置的圆形遮罩层,通过CSS动画让它从按钮中心扩散至全屏,同时同步切换页面主题样式,动画结束后隐藏遮罩即可。
具体实现步骤
1. 编写React组件逻辑
在组件中添加遮罩元素的状态管理,处理点击时的坐标计算和动画触发:
import { useState } from 'react'; function ThemeToggle() { const [currentTheme, setCurrentTheme] = useState('light'); const [maskStyle, setMaskStyle] = useState(null); const toggleTheme = (e) => { // 获取切换按钮的实时位置和尺寸 const btnRect = e.currentTarget.getBoundingClientRect(); const centerX = btnRect.left + btnRect.width / 2; const centerY = btnRect.top + btnRect.height / 2; // 设置遮罩初始状态:定位在按钮中心,尺寸为0 setMaskStyle({ left: `${centerX}px`, top: `${centerY}px`, width: '0px', height: '0px', backgroundColor: currentTheme === 'light' ? '#1a1a1a' : '#ffffff', display: 'block' }); // 延迟切换主题,让遮罩动画先启动 setTimeout(() => { setCurrentTheme(prev => prev === 'light' ? 'dark' : 'light'); }, 50); // 动画结束后隐藏遮罩 setTimeout(() => { setMaskStyle(null); }, 600); }; return ( <div className={`app-wrapper ${currentTheme}`}> {/* 主题切换按钮 */} <button className="theme-switch-btn" onClick={toggleTheme}> 切换主题 </button> {/* 动画遮罩层 */} {maskStyle && ( <div className="theme-transition-mask" style={maskStyle} /> )} </div> ); } export default ThemeToggle;
2. 配置CSS动画样式
为遮罩层添加关键帧动画,实现从点到面的扩散效果:
.app-wrapper { width: 100vw; height: 100vh; transition: background-color 0.3s; } .app-wrapper.light { background-color: #fff; color: #1a1a1a; } .app-wrapper.dark { background-color: #1a1a1a; color: #fff; } .theme-switch-btn { position: fixed; bottom: 20px; right: 20px; padding: 10px 16px; border: none; border-radius: 4px; cursor: pointer; } .theme-transition-mask { position: fixed; border-radius: 50%; transform: translate(-50%, -50%); z-index: 9999; animation: expandToFullScreen 0.5s forwards; pointer-events: none; /* 避免遮罩阻挡页面交互 */ } @keyframes expandToFullScreen { to { width: 200vw; height: 200vw; /* 用vw确保覆盖全屏,适配不同屏幕尺寸 */ } }
3. 关键细节注意
- 坐标计算:用
getBoundingClientRect()获取按钮的实时位置,确保遮罩从按钮中心准确扩散。 - 动画与主题切换时机:延迟50ms切换主题,让遮罩动画先启动,视觉过渡更自然。
- 遮罩尺寸:设置
200vw的宽高,确保无论页面宽度如何,都能完全覆盖屏幕,避免留白。 - 层级控制:遮罩层设置高
z-index,保证在所有页面内容上方显示。
适配Ant Design主题变量
如果你的项目用Ant Design定制主题,可以把遮罩背景色替换为对应的主题变量,比如:
// 假设项目使用CSS变量或Less变量 backgroundColor: currentTheme === 'light' ? '--ant-color-bg-dark' : '--ant-color-bg'
内容的提问来源于stack exchange,提问作者Amaranthus
相关产品推荐
相关产品推荐

