如何使用SVG <animate> 实现精灵动画及Safari兼容问题解决
问题根因
Safari对SMIL动画中动态修改<image>元素的href属性支持存在兼容缺陷,即便静态图片可以正常加载,也无法通过<animate>标签动态切换href值实现帧动画,属于Safari内核的SMIL实现兼容问题。
可行解决方案
方案1:JS定时器切换图片(兼容性最佳)
完全避开SMIL的兼容问题,用原生JS定时切换图片地址,适配所有主流浏览器,可替代原有的SMIL动画逻辑:
const bird = document.getElementById('bird'); // 按顺序填写所有帧的资源地址 const birdFrames = [ 'SVG/Birds/bird_1.svg', 'SVG/Birds/bird2.svg', 'SVG/Birds/bird3.svg' ]; let frameIndex = 0; // 原动画总时长0.8s共3帧,单帧间隔约267ms,可按需调整速度 setInterval(() => { frameIndex = (frameIndex + 1) % birdFrames.length; bird.setAttribute('href', birdFrames[frameIndex]); }, 267);
使用时删除原有<animate>标签即可,需要控制动画启停可以替换setInterval为自定义控制逻辑。
方案2:纯SVG显隐动画(无JS依赖)
把所有帧的图片都放到SVG结构中,通过SMIL控制opacity属性实现帧切换,Safari对opacity的SMIL动画支持完善:
<image id="bird1" href="SVG/Birds/bird_1.svg" height="250" width="500" x="7%" y="1%" opacity="1"> <animate attributeName="opacity" values="1;0;0" dur="0.8s" repeatCount="indefinite" /> </image> <image id="bird2" href="SVG/Birds/bird2.svg" height="250" width="500" x="7%" y="1%" opacity="0"> <animate attributeName="opacity" values="0;1;0" dur="0.8s" repeatCount="indefinite" /> </image> <image id="bird3" href="SVG/Birds/bird3.svg" height="250" width="500" x="7%" y="1%" opacity="0"> <animate attributeName="opacity" values="0;0;1" dur="0.8s" repeatCount="indefinite" /> </image>
该方案无需额外引入JS,所有逻辑都在SVG内部实现,兼容性稳定。
方案3:补充xlink:href动画声明(备选)
如果希望保留原有动态切换href的SMIL逻辑,可以额外新增针对xlink:href属性的动画声明,适配部分支持该属性的Safari版本:
首先要确保你的SVG根标签已经声明xlink命名空间:
<svg xmlns:xlink="http://www.w3.org/1999/xlink" ...>
然后修改原有动画部分,新增xlink:href的动画:
<animate id="birdAnim2" attributeName="href" values="SVG/Birds/bird_1.svg;SVG/Birds/bird2.svg;SVG/Birds/bird3.svg;" dur="0.8s" begin="indefinite" repeatCount="indefinite" /> <animate id="birdAnimXlink" attributeName="xlink:href" values="SVG/Birds/bird_1.svg;SVG/Birds/bird2.svg;SVG/Birds/bird3.svg;" dur="0.8s" begin="indefinite" repeatCount="indefinite" />
该方案对高版本Safari的适配率不如前两个方案,优先推荐前两种实现。
内容的提问来源于stack exchange,提问作者Yuvispace
相关产品推荐
相关产品推荐

