Safari错误.当试图用模糊过滤器动画svg变换时,safari是非常滞后的



我花了很多时间寻找类似的问题,但一无所获。请帮助解决这个差距的狩猎。

我正在尝试在svg中使用模糊过滤器来设置图片的动画。这在除safari之外的所有浏览器中都很有效。我准备了一把小提琴:https://jsfiddle.net/7pne23Lk/11/

如果有任何帮助或想法,我将不胜感激!谢谢

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 250">
<defs>
<mask id="circleClip" clipPathUnits="userSpaceOnUse">
<circle cx="100" cy="100" r="80" fill="#fff"></circle>
</mask>

<circle id="circleA" cx="100" cy="100" r="80"></circle>
<circle id="circleC" cx="100" cy="100" r="80"></circle>
<filter id="circleB" width="123%" height="123%" x="-11.5%" y="-11.5%" filterUnits="objectBoundingBox">
<feGaussianBlur in="SourceAlpha" result="shadowBlurInner1" stdDeviation="4"></feGaussianBlur>
<feOffset dy="8" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" k2="-1" k3="1" operator="arithmetic" result="shadowInnerInner1"></feComposite>
<feColorMatrix in="shadowInnerInner1" result="shadowMatrixInner1" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"></feColorMatrix>
<feGaussianBlur in="SourceAlpha" result="shadowBlurInner2" stdDeviation="4"></feGaussianBlur>
<feOffset dy="-8" in="shadowBlurInner2" result="shadowOffsetInner2"></feOffset>
<feComposite in="shadowOffsetInner2" in2="SourceAlpha" k2="-1" k3="1" operator="arithmetic" result="shadowInnerInner2"></feComposite>
<feColorMatrix in="shadowInnerInner2" result="shadowMatrixInner2" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.2 0"></feColorMatrix>
<feMerge>
<feMergeNode in="shadowMatrixInner1"></feMergeNode>
<feMergeNode in="shadowMatrixInner2"></feMergeNode>
</feMerge>
</filter>
<filter id="motionBlur" x="0" y="0" width="100%" height="100%"><feGaussianBlur in="SourceGraphic" stdDeviation="0,0"></feGaussianBlur></filter>
</defs>

<g fill="none" fill-rule="evenodd">
<use fill="#222731" xlink:href="#circleA"></use>
<g stroke-linejoin="round">
<use fill="#000" filter="url(#circleB)" xlink:href="#circleC"></use>
<circle cx="100" cy="100" r="86" stroke="#272d39" stroke-width="10.764"></circle>
</g>
</g>


<g transform="translate(0,0)" mask="url(#circleClip)">
<g class="items" transform="translate(36, 36)" filter="url(#motionBlur)">
<image width="128px" height="128px" xlink:href="https://i.imgur.com/xSpsoPm.png"></image>
<image width="128px" height="128px" y="-128" xlink:href="https://i.imgur.com/JuG5GrL.png"></image>
<image width="128px" height="128px" y="-256" xlink:href="https://i.imgur.com/BB2GgC6.png"></image>
<image width="128px" height="128px" y="-384" xlink:href="https://i.imgur.com/xSpsoPm.png"></image>
<image width="128px" height="128px" y="-512" xlink:href="https://i.imgur.com/JuG5GrL.png"></image>
<image width="128px" height="128px" y="-640" xlink:href="https://i.imgur.com/BB2GgC6.png"></image>
<image width="128px" height="128px" y="-768" xlink:href="https://i.imgur.com/xSpsoPm.png"></image>
<image width="128px" height="128px" y="-896" xlink:href="https://i.imgur.com/JuG5GrL.png"></image>
<image width="128px" height="128px" y="-1024" xlink:href="https://i.imgur.com/BB2GgC6.png"></image>
<image width="128px" height="128px" y="-1152" xlink:href="https://i.imgur.com/xSpsoPm.png"></image>
<image width="128px" height="128px" y="-1280" xlink:href="https://i.imgur.com/JuG5GrL.png"></image>
<image width="128px" height="128px" y="-1408" xlink:href="https://i.imgur.com/BB2GgC6.png"></image>
<image width="128px" height="128px" y="-1536" xlink:href="https://i.imgur.com/xSpsoPm.png"></image>
<image width="128px" height="128px" y="-1664" xlink:href="https://i.imgur.com/JuG5GrL.png"></image>
<image width="128px" height="128px" y="-1792" xlink:href="https://i.imgur.com/BB2GgC6.png"></image>           
</g>
</g>

</svg>
<button id="play">
play
</button>
const blur = document.querySelector("#motionBlur");
const blurFilter = blur.firstElementChild;
const items = document.querySelector('.items');
const button = document.querySelector('#play');

function animate() {
gsap.set(items, { y: 140 });
const tl = gsap.timeline();
tl.to(items, {duration: 0.5, y: 1195, onUpdate: () => {
const progress = tl.progress() * 20;
blurFilter.setAttribute('stdDeviation', `0,${20 - progress}`);
if (tl.progress() >= 0.9) {
blurFilter.setAttribute('stdDeviation', `0,0`);
}
}})
}
button.addEventListener("click", animate, false);

Safari中的SVG过滤器动画性能可能很差,所以这并不完全出乎意料。我有几个建议。

  1. 添加颜色插值滤波器=";sRGB";到您的svg元素

  2. 神奇的建议-将SVG分解为两个独立的SVG元素,其中一个元素中包含非动画过滤器和内容,另一个元素则包含动画过滤器和属性。我不知道这是否可行,但值得一试。你的第一个过滤器非常复杂,如果Safari在你的动画的每一个节拍上都重新渲染它(即使它没有动画(,它可能会影响你的性能。

  3. 另一种方法是使用";使用";元素预渲染以不同模糊级别绘制在彼此之上的图像的20个副本,然后使用不透明度动画来逐步公开&隐藏每一层。不透明动画通常很快,即使在Safari上也是如此,所以这可能是一个有效的破解方法,尽管它会使标记更加复杂。(还有另一个提示-不要将不透明度从0设置为1-从0.01或0.04设置为1的动画-webkit有时会通过不渲染0不透明度内容来优化-在这种情况下,你试图强制它这样做。(

最新更新