方形径向渐变擦除动画优化:消除关键帧卡顿问题
解决径向擦除渐变矩形动画卡顿问题
需要实现的效果:填充渐变的矩形执行径向擦除清除画面,短暂延迟后渐变重新出现并循环。当前采用polygon类型的clip-path关键帧动画实现了近似效果,但动画在关键帧切换时出现明显卡顿,以下是两种无卡顿的解决方案:
当前实现代码
HTML
<div class="gradient"></div> <div class="reveal"></div>
CSS
.gradient { background: conic-gradient(rgba(177, 216, 224, 1), rgba(242, 231, 203)); width: 100%; height: 500px; position: absolute; top: 0; left: 0; } .reveal { width: 100%; height: 500px; position: absolute; top: 0; left: 0; animation: 8s rectangleDelay infinite; background: white; animation-delay: 2s; } @keyframes rectangleDelay { 0% { clip-path: polygon(50% 50%, 50% 0, 100% 0, 100% 100%, 0 100%, 0 0, 50% 0); } 10% { clip-path: polygon(50% 50%, 100% 0, 100% 0, 100% 100%, 0 100%, 0 0, 50% 0); } 20% { clip-path: polygon(50% 50%, 100% 100%, 100% 100%, 100% 100%, 0 100%, 0 0, 50% 0); } 30% { clip-path: polygon(50% 50%, 0 100%, 0 100%, 0 100%, 0 100%, 0 0, 50% 0); } 40% { clip-path: polygon(50% 50%, 0 0, 0 0, 0 0, 0 0, 0 0, 50% 0); } 50% { clip-path: polygon(50% 50%, 50% 0, 50% 0, 50% 0, 50% 0, 50% 0, 50% 0); } 100% { clip-path: polygon(50% 50%, 50% 0, 50% 0, 50% 0, 50% 0, 50% 0, 50% 0); } }
方案1:使用clip-path: circle()实现连续平滑动画
circle()类型的clip-path支持半径的连续数值过渡,浏览器可自动生成中间帧,避免关键帧卡顿。通过控制遮罩层的圆形裁剪范围,实现径向擦除效果:
.gradient { background: conic-gradient(rgba(177, 216, 224, 1), rgba(242, 231, 203)); width: 100%; height: 500px; position: absolute; top: 0; left: 0; } .reveal { width: 100%; height: 500px; position: absolute; top: 0; left: 0; background: white; animation: radialErase 8s infinite; animation-delay: 2s; } @keyframes radialErase { 0% { clip-path: circle(100% at 50% 50%); /* 初始覆盖整个容器 */ opacity: 1; } 40% { clip-path: circle(0% at 50% 50%); /* 缩小至中心,完全露出渐变 */ opacity: 1; } 41% { opacity: 0; /* 隐藏遮罩,预留延迟等待渐变重新出现 */ } 90% { opacity: 0; clip-path: circle(0% at 50% 50%); } 91% { opacity: 1; clip-path: circle(100% at 50% 50%); /* 重新展开遮罩,进入下一轮循环 */ } 100% { clip-path: circle(100% at 50% 50%); opacity: 1; } }
方案2:使用CSS Mask实现径向擦除(更简洁)
直接在渐变层上使用mask属性,结合径向渐变的尺寸变化实现平滑擦除,无需额外遮罩层:
.gradient { background: conic-gradient(rgba(177, 216, 224, 1), rgba(242, 231, 203)); width: 100%; height: 500px; position: absolute; top: 0; left: 0; animation: gradientReveal 8s infinite; animation-delay: 2s; } @keyframes gradientReveal { 0% { mask: radial-gradient(circle at 50% 50%, transparent 0%, black 0%); } 40% { mask: radial-gradient(circle at 50% 50%, transparent 100%, black 100%); } 41% { opacity: 0; } 90% { opacity: 0; } 91% { opacity: 1; mask: radial-gradient(circle at 50% 50%, transparent 0%, black 0%); } 100% { mask: radial-gradient(circle at 50% 50%, transparent 0%, black 0%); } }
卡顿原因说明
原方案使用polygon类型的clip-path,每个关键帧的多边形顶点位置是离散的,浏览器无法在关键帧之间进行平滑插值计算,导致切换时出现卡顿。而circle()裁剪或CSS Mask的渐变尺寸均为连续数值变化,浏览器可自动生成流畅的过渡帧,彻底解决卡顿问题。
内容的提问来源于stack exchange,提问作者Jana Kemmer
相关产品推荐
相关产品推荐

