如何修复Safari中SVG变换产生的未知线条问题
Safari中SVG加载图标出现异常线条的解决方法
问题描述
我有一个由3个圆形组成的顺时针旋转加载SVG图标,在Chrome和Firefox中显示正常,但在Safari浏览器中,圆形会在特定位置出现奇怪的线条(问题截图:
)。
原SVG代码如下:
<div class="flex flex-row justify-center items-center w-full h-full fixed select-none z-50" style="left: 50%;top: 50%;transform: translateX(-50%) translateY(-50%);background: rgba(255,255,255,0.7);" x-show="isLoading" x-transition:enter="ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"> <svg width="57" height="57" viewBox="0 0 57 57" xmlns="http://www.w3.org/2000/svg" stroke="#fff" class="stroke-current text-primary" style="/* stroke: salmon; */"> <g fill="none" fill-rule="evenodd" style="fill: color();"> <g transform="translate(1 1)" stroke-width="2" style="translate: (0,1);transform: translate();transform: translate(112341122121,5);"> <circle cx="5" cy="50" r="5"> <animate attributeName="cy" begin="0s" dur="2.2s" values="50;5;50;50" calcMode="linear" repeatCount="indefinite"></animate> <animate attributeName="cx" begin="0s" dur="2.2s" values="5;27;49;5" calcMode="linear" repeatCount="indefinite"></animate> </circle> <circle cx="27" cy="5" r="5"> <animate attributeName="cy" begin="0s" dur="2.2s" from="5" to="5" values="5;50;50;5" calcMode="linear" repeatCount="indefinite"></animate> <animate attributeName="cx" begin="0s" dur="2.2s" from="27" to="27" values="27;49;5;27" calcMode="linear" repeatCount="indefinite"></animate> </circle> <circle cx="49" cy="50" r="5"> <animate attributeName="cy" begin="0s" dur="2.2s" values="50;50;5;50" calcMode="linear" repeatCount="indefinite"></animate> <animate attributeName="cx" from="49" to="49" begin="0s" dur="2.2s" values="49;5;27;49" calcMode="linear" repeatCount="indefinite"></animate> </circle> </g> </g> </svg> <div class="ml-10 text-primary text-xl"> Loading... </div> </div>
解决方法
这个问题是Safari对SVG动画渲染的精度问题导致的,尤其是在圆形位置突变或动画节点衔接处容易出现渲染瑕疵,可通过以下方案修复:
- 优化动画过渡模式:将
calcMode="linear"改为calcMode="spline",添加平滑的贝塞尔曲线过渡,避免硬切换带来的渲染断层。给所有<animate>标签添加keySplines和keyTimes参数,让圆形移动更顺滑。 - 添加渲染修正属性:给每个圆形添加
stroke-linecap="round"和stroke-miterlimit="1",修正Safari的描边渲染逻辑。 - 清理冗余样式:删除SVG中无效的冗余
transform和style属性,避免干扰浏览器渲染。
优化后的完整代码
<div class="flex flex-row justify-center items-center w-full h-full fixed select-none z-50" style="left: 50%;top: 50%;transform: translateX(-50%) translateY(-50%);background: rgba(255,255,255,0.7);" x-show="isLoading" x-transition:enter="ease-out duration-200" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"> <svg width="57" height="57" viewBox="0 0 57 57" xmlns="http://www.w3.org/2000/svg" stroke="#fff" class="stroke-current text-primary"> <g fill="none" fill-rule="evenodd"> <g transform="translate(1 1)" stroke-width="2"> <circle cx="5" cy="50" r="5" stroke-linecap="round" stroke-miterlimit="1"> <animate attributeName="cy" begin="0s" dur="2.2s" values="50;5;50;50" calcMode="spline" keySplines="0.42 0 0.58 1; 0.42 0 0.58 1; 0.42 0 0.58 1" keyTimes="0;0.33;0.66;1" repeatCount="indefinite"></animate> <animate attributeName="cx" begin="0s" dur="2.2s" values="5;27;49;5" calcMode="spline" keySplines="0.42 0 0.58 1; 0.42 0 0.58 1; 0.42 0 0.58 1" keyTimes="0;0.33;0.66;1" repeatCount="indefinite"></animate> </circle> <circle cx="27" cy="5" r="5" stroke-linecap="round" stroke-miterlimit="1"> <animate attributeName="cy" begin="0s" dur="2.2s" values="5;50;50;5" calcMode="spline" keySplines="0.42 0 0.58 1; 0.42 0 0.58 1; 0.42 0 0.58 1" keyTimes="0;0.33;0.66;1" repeatCount="indefinite"></animate> <animate attributeName="cx" begin="0s" dur="2.2s" values="27;49;5;27" calcMode="spline" keySplines="0.42 0 0.58 1; 0.42 0 0.58 1; 0.42 0 0.58 1" keyTimes="0;0.33;0.66;1" repeatCount="indefinite"></animate> </circle> <circle cx="49" cy="50" r="5" stroke-linecap="round" stroke-miterlimit="1"> <animate attributeName="cy" begin="0s" dur="2.2s" values="50;50;5;50" calcMode="spline" keySplines="0.42 0 0.58 1; 0.42 0 0.58 1; 0.42 0 0.58 1" keyTimes="0;0.33;0.66;1" repeatCount="indefinite"></animate> <animate attributeName="cx" begin="0s" dur="2.2s" values="49;5;27;49" calcMode="spline" keySplines="0.42 0 0.58 1; 0.42 0 0.58 1; 0.42 0 0.58 1" keyTimes="0;0.33;0.66;1" repeatCount="indefinite"></animate> </circle> </g> </g> </svg> <div class="ml-10 text-primary text-xl"> Loading... </div> </div>
内容的提问来源于stack exchange,提问作者LosMos
相关产品推荐
相关产品推荐

