如何实现矩形填充沿任意对角线方向的clip-path动画?
问题描述
我已经实现了一个clip-path从左到右消失的动画效果:
svg { height: 100vh; } #myClip { animation: anime 2s ease infinite; } @keyframes anime { 0% { transform: scaleX(0); transform-origin: left center; } 25% { transform: scaleX(1); transform-origin: left center; } 50% { transform: scaleX(1); transform-origin: right center; } 100% { transform-origin: right center; transform: scaleX(0); } }
<svg viewBox="-20 -20 140 140" xmlns="http://www.w3.org/2000/svg"> <clipPath id="myClip" clipPathUnits="objectBoundingBox"> <rect width="1" height="1" /> </clipPath> <rect x="0" width="100" height="100" rx="15" clip-path="url(#myClip)" /> </svg>
现在我希望实现相同的动画,但沿任意角度的对角线方向执行。
类似如下效果,但需要旋转的是clip-path而非图形:
svg { height: 100vh; } #myClip { animation: anime 2s ease infinite; } @keyframes anime { 0% { transform: scaleX(0); transform-origin: left center; } 25% { transform: scaleX(1); transform-origin: left center; } 50% { transform: scaleX(1); transform-origin: right center; } 100% { transform-origin: right center; transform: scaleX(0); } }
<svg viewBox="-20 -20 140 140" xmlns="http://www.w3.org/2000/svg"> <clipPath id="myClip" clipPathUnits="objectBoundingBox"> <rect width="1" height="1" /> </clipPath> <g transform="rotate(-30 50 50)" clip-path="url(#myClip)"> <rect transform="rotate(30 50 50)" x="0" width="100" height="100" rx="15" /> </g> </svg>
我已尝试的方法
旋转
<rect>元素 - 导致矩形变形:svg { height: 100vh; } #myClip { animation: anime 2s ease infinite; } @keyframes anime { 0% { transform: scaleX(0); transform-origin: left center; } 25% { transform: scaleX(1); transform-origin: left center; } 50% { transform: scaleX(1); transform-origin: right center; } 100% { transform-origin: right center; transform: scaleX(0); } }<svg viewBox="-20 -20 140 140" xmlns="http://www.w3.org/2000/svg"> <clipPath id="myClip" clipPathUnits="objectBoundingBox"> <rect transform="rotate(30)" width="1" height="1" /> </clipPath> <rect x="0" width="100" height="100" rx="15" clip-path="url(#myClip)" /> </svg>将
scaleX改为scale并修改transform-origin- 未达到预期效果:svg { height: 100vh; } #myClip { animation: anime 2s ease infinite; } @keyframes anime { 0% { transform: scale(0); transform-origin: 0 0; } 25% { transform: scale(1); transform-origin: 0 0; } 50% { transform: scale(1); transform-origin: 100% 70%; } 100% { transform-origin: 100% 70%; transform: scale(0); } }<svg viewBox="-20 -20 140 140" xmlns="http://www.w3.org/2000/svg"> <clipPath id="myClip" clipPathUnits="objectBoundingBox"> <rect width="1" height="1" /> </clipPath> <rect x="0" width="100" height="100" rx="15" clip-path="url(#myClip)" /> </svg>用
<g>包裹<rect>以实现独立旋转 - 页面内容全部消失:svg { height: 100vh; } #myClip rect { animation: anime 2s ease infinite; } @keyframes anime { 0% { transform: scaleX(0); transform-origin: left center; } 25% { transform: scaleX(1); transform-origin: left center; } 50% { transform: scaleX(1); transform-origin: right center; } 100% { transform-origin: right center; transform: scaleX(0); } }<svg viewBox="-20 -20 140 140" xmlns="http://www.w3.org/2000/svg"> <clipPath id="myClip" clipPathUnits="objectBoundingBox"> <g> <rect width="1" height="1" /> </g> </clipPath> <rect x="0" width="100" height="100" rx="15" clip-path="url(#myClip)" /> </svg>
解决方案
核心思路是在clip-path内部对矩形先旋转,再执行缩放动画,同时调整变换原点,确保动画沿指定对角线方向展开/收缩。
实现代码
svg { height: 100vh; } #clipRect { /* 先旋转到目标角度,这里以30度为例 */ transform: rotate(30deg); transform-origin: center; animation: diagonalAnime 2s ease infinite; } @keyframes diagonalAnime { 0% { /* 缩放X轴,变换原点设为旋转后的左上角 */ transform: rotate(30deg) scaleX(0); transform-origin: 0% 50%; } 25% { transform: rotate(30deg) scaleX(1); transform-origin: 0% 50%; } 50% { transform: rotate(30deg) scaleX(1); /* 切换变换原点到旋转后的右上角 */ transform-origin: 100% 50%; } 100% { transform: rotate(30deg) scaleX(0); transform-origin: 100% 50%; } }
<svg viewBox="-20 -20 140 140" xmlns="http://www.w3.org/2000/svg"> <clipPath id="myClip" clipPathUnits="objectBoundingBox"> <!-- 给clip内的矩形单独设置ID,方便控制动画 --> <rect id="clipRect" width="1" height="1" /> </clipPath> <rect x="0" width="100" height="100" rx="15" clip-path="url(#myClip)" /> </svg>
关键说明
- 变换顺序:必须先执行
rotate再执行scaleX,否则缩放会沿着原始坐标轴方向进行,无法得到对角线效果。 - 变换原点调整:旋转后矩形的边角位置发生变化,需要将
transform-origin设置为旋转后的对应端点(比如0% 50%对应旋转后的左上角,100% 50%对应旋转后的右上角)。 - 任意角度适配:只需修改
rotate中的角度值,同时保持transform-origin的百分比设置,即可适配不同的对角线方向。
如果需要沿从左下到右上的对角线动画,只需将旋转角度改为-30deg,并调整变换原点为0% 100%和100% 0%即可:
@keyframes diagonalAnime { 0% { transform: rotate(-30deg) scaleX(0); transform-origin: 0% 100%; } 25% { transform: rotate(-30deg) scaleX(1); transform-origin: 0% 100%; } 50% { transform: rotate(-30deg) scaleX(1); transform-origin: 100% 0%; } 100% { transform: rotate(-30deg) scaleX(0); transform-origin: 100% 0%; } }
内容的提问来源于stack exchange,提问作者Konrad
相关产品推荐
相关产品推荐

