如何用CSS实现SVG甜甜圈上下对称同步出现动画?
实现甜甜圈从上到下对称出现的CSS动画方案
原SVG代码
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="800" width="800"> <defs> <linearGradient id="Gradient1" gradientTransform="rotate(90)"> <stop offset="0%" stop-color="#000000"/> <stop offset="10%" stop-color="#000000"/> <stop offset="50%" stop-color="#8b9643"/> <stop offset="90%" stop-color="#000000"/> <stop offset="100%" stop-color="#000000"/> </linearGradient> <linearGradient id="Gradient2" gradientTransform="rotate(90)"> <stop offset="10%" stop-color="#000000"/> <stop offset="0%" stop-color="#000000"/> <stop offset="50%" stop-color="#dda885"/> <stop offset="90%" stop-color="#000000"/> <stop offset="100%" stop-color="#000000"/> </linearGradient> <pattern id="Pattern" x="0" y="0" width="600" height="600" patternUnits="userSpaceOnUse"> <g transform="rotate(0, 300, 300)"> <rect shape-rendering="crispEdges" x="0" y="0" width="300" height="600" fill="url(#Gradient1)"/> <rect shape-rendering="crispEdges" x="300" y="0" width="300" height="600" fill="url(#Gradient2)"/> </g> </pattern> </defs> <path id='arc5' class="animated" style="stroke: url(#Pattern);" fill='transparent' stroke-dasharray="1570 1570" stroke-dashoffset="0" stroke-width='100' d='M 300 58 A 250 250 0 1 1 299.99 58'/> </svg>
实现上下对称同步出现的动画方案
要实现甜甜圈从上到下对称出现、左右两半同步显示的效果,通过调整stroke-dasharray和stroke-dashoffset的CSS动画即可完成,具体操作如下:
拆分圆环显示段
原圆环周长约为1570(2 * π * 250),将stroke-dasharray设为785 785(半周长与间隔各占一半),把圆环拆分为左右两个独立半弧段;初始设置stroke-dashoffset: 1570,让整个圆环完全隐藏。编写生长动画
创建@keyframes关键帧,让stroke-dashoffset从1570过渡到785,这个过程会让左右半弧同时从顶部起点向下延伸,最终拼接成完整圆环。绑定动画到路径
给.animated类添加动画属性,控制时长、缓动效果等参数。
修改后的完整代码(包含CSS):
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="800" width="800"> <defs> <linearGradient id="Gradient1" gradientTransform="rotate(90)"> <stop offset="0%" stop-color="#000000"/> <stop offset="10%" stop-color="#000000"/> <stop offset="50%" stop-color="#8b9643"/> <stop offset="90%" stop-color="#000000"/> <stop offset="100%" stop-color="#000000"/> </linearGradient> <linearGradient id="Gradient2" gradientTransform="rotate(90)"> <stop offset="10%" stop-color="#000000"/> <stop offset="0%" stop-color="#000000"/> <stop offset="50%" stop-color="#dda885"/> <stop offset="90%" stop-color="#000000"/> <stop offset="100%" stop-color="#000000"/> </linearGradient> <pattern id="Pattern" x="0" y="0" width="600" height="600" patternUnits="userSpaceOnUse"> <g transform="rotate(0, 300, 300)"> <rect shape-rendering="crispEdges" x="0" y="0" width="300" height="600" fill="url(#Gradient1)"/> <rect shape-rendering="crispEdges" x="300" y="0" width="300" height="600" fill="url(#Gradient2)"/> </g> </pattern> <style> .animated { animation: growDonut 2s ease-in-out forwards; stroke-dasharray: 785 785; stroke-dashoffset: 1570; } @keyframes growDonut { to { stroke-dashoffset: 785; } } </style> </defs> <path id='arc5' class="animated" style="stroke: url(#Pattern);" fill='transparent' stroke-width='100' d='M 300 58 A 250 250 0 1 1 299.99 58'/> </svg>
效果说明
- 动画启动时甜甜圈完全隐藏;
- 动画过程中,左右两半弧从顶部中心点同步向下生长,最终拼接成完整的甜甜圈;
- 可通过修改
animation属性中的时长(如2s)和缓动函数(如ease-in-out)调整动画节奏。
内容的提问来源于stack exchange,提问作者부건혁
相关产品推荐
相关产品推荐

