如何制作带动态变色效果的倾斜动画弹窗
弹窗倾斜+颜色同步动画实现方案
核心思路
- 利用CSS
transform: rotate()实现弹窗从垂直(90°)到水平(0°)的旋转过渡 - 通过绑定同时长的CSS关键帧动画,让颜色变化与旋转动作完全同步
- 弹窗内部可通过嵌套元素划分颜色区域,分别设置颜色动画
完整可运行代码示例
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>弹窗倾斜变色动画</title> <style> body { display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; background: #f0f0f0; } /* 弹窗容器 */ .popup { width: 300px; height: 150px; position: relative; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); overflow: hidden; /* 初始垂直状态 */ transform: rotate(90deg); /* 旋转动画:1.5秒缓动,结束后保持最终状态 */ animation: popupRotate 1.5s ease-out forwards; } /* 颜色区域划分 */ .popup__section { position: absolute; width: 50%; height: 100%; display: flex; justify-content: center; align-items: center; color: #fff; font-size: 16px; } .popup__left { left: 0; animation: leftColorShift 1.5s ease-out forwards; } .popup__right { right: 0; animation: rightColorShift 1.5s ease-out forwards; } /* 旋转关键帧 */ @keyframes popupRotate { 0% { transform: rotate(90deg); } 100% { transform: rotate(0deg); } } /* 左侧区域颜色变化 */ @keyframes leftColorShift { 0% { background-color: #ff4757; } 100% { background-color: #ffa502; } } /* 右侧区域颜色变化 */ @keyframes rightColorShift { 0% { background-color: #2ed573; } 100% { background-color: #1e90ff; } } </style> </head> <body> <div class="popup"> <div class="popup__section popup__left">左侧区域</div> <div class="popup__section popup__right">右侧区域</div> </div> </body> </html>
关键细节说明
旋转动画控制
- 弹窗初始设置
rotate(90deg)处于垂直状态,通过popupRotate关键帧过渡到水平状态,forwards属性确保动画结束后停在最终位置。 - 可调整
animation的时长(如1s)、缓动函数(如linear)来匹配需求。
- 弹窗初始设置
颜色同步逻辑
- 两个颜色区域的动画时长与旋转动画完全一致,保证颜色变化和旋转动作同步。
- 如果需要多阶段颜色过渡,可在关键帧中添加中间节点,例如:
@keyframes leftColorShift { 0% { background-color: #ff4757; } 50% { background-color: #ff6b81; } 100% { background-color: #ffa502; } }
JS动态控制进阶方案
如果需要基于旋转进度精准计算颜色(比如渐变更细腻),可以用JS监听动画进度:const popup = document.querySelector('.popup'); const leftSection = document.querySelector('.popup__left'); const rightSection = document.querySelector('.popup__right'); popup.addEventListener('animationstart', (e) => { const duration = e.animationDuration; const updateColor = () => { const elapsed = popup.getAnimations()[0].currentTime; const progress = elapsed / duration; // 左侧颜色:从#ff4757(R:255,G:71,B:87)到#ffa502(R:255,G:165,B:2) const leftG = 71 + Math.floor((165 - 71) * progress); const leftB = 87 + Math.floor((2 - 87) * progress); leftSection.style.backgroundColor = `rgb(255, ${leftG}, ${leftB})`; // 右侧颜色:从#2ed573(R:46,G:213,B:115)到#1e90ff(R:30,G:144,B:255) const rightR = 46 + Math.floor((30 - 46) * progress); const rightG = 213 + Math.floor((144 - 213) * progress); const rightB = 115 + Math.floor((255 - 115) * progress); rightSection.style.backgroundColor = `rgb(${rightR}, ${rightG}, ${rightB})`; if (progress < 1) requestAnimationFrame(updateColor); }; requestAnimationFrame(updateColor); });
内容的提问来源于stack exchange,提问作者신재홍
相关产品推荐
相关产品推荐

