为什么这个 SVG 蒙版动画在 Firefox 中不连贯,但在 Chrome 中却很流畅?

j08*_*691 6 html css firefox svg css-animations

我将我正在处理的 SVG 动画(应该看起来像一个正在填充的容器)简化为下面的示例,该动画在 Chrome 中运行流畅,但在 Firefox 中运行不顺畅/卡顿。这是一个具有三层的 SVG:第一层是<mask>最后一层,它是一个红色圆圈。SVG 的中间层是一个灰色圆圈。因此,红色圆圈位于灰色圆圈的顶部,并且通过通过 CSS 进行动画处理的蒙版使其可见:

#color-mask {
  fill: white;
}

#color-mask path {
  animation: waves .75s infinite linear;
}

@keyframes waves {
  from {
    transform: translateX(17rem);
  }
  to {
    transform: translateX(-17rem);
  }
}

#color-mask g {
  animation: raise 6s infinite ease-in-out;
  animation-direction: alternate;
}

@keyframes raise {
  from {
    transform: translateY(11rem);
  }
  to {
    transform: translateY(-18rem);
  }
}
Run Code Online (Sandbox Code Playgroud)
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="400px" height="400px" viewBox="0 0 400 400">
    <mask id="color-mask">
        <g>
            <path d="m 909.1,353.4 0,-67.6 c -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 -71,0 -107.2,14.8 -142.1,29 -34.8,14.2 -70.9,29 -141.7,29 -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 -71.1,0 -107.2,14.8 -142.1,29 -34.8,14.2 -70.9,29 -141.7,29 -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 l 0,632.2 1419,0 z"/>
        </g>
    </mask>
    <g id="grey">
        <circle  id="top_grey" style="fill: rgb(180, 180, 180);" cx="200" cy="200" r="200"></circle>
    </g>
    <g id="color" mask="url(#color-mask)">
        <circle id="top_color" style="fill: rgb(196, 3, 3);" cx="200" cy="200" r="200"></circle>
    </g>
</svg>
Run Code Online (Sandbox Code Playgroud)

CSS 动画会<mask>水平和垂直平移,但速度不同。

我也尝试过使用 a<clipPath>代替 a<mask>并得到相同的结果。我在 Windows 和 Linux 上的 Firefox 中得到了相同的断断续续/卡顿的结果。

我在 Firefox 中注意到的一个非常奇怪的现象是,如果我打开开发工具,动画有时会顺利运行。Firefox 的开发工具似乎也没有指出任何问题,但我不是 SVG 动画方面的专家。为什么 Firefox 会被这个问题卡住,而 Chrome 却不会?

Tem*_*fif 5

使用 CSS mask 的不同想法不会出现问题。我使用您提供的路径作为掩码。只需确保为 viewBox 设置正确的值

.box {
  display:inline-flex;
  width:300px;
  background: rgb(180, 180, 180);
  border-radius:50%;
  position:relative;
  overflow:hidden;
}
.box:after {
  content:"";
  padding-top:100%;
}
.box:before {
  content:"";
  position:absolute;
  left:0%;
  width:200%;
  height:30%;
  bottom:-10%;
  background:rgb(196, 3, 3);
  -webkit-mask:url('data:image/svg+xml;utf8,<svg version="1.1" xmlns="http://www.w3.org/2000/svg"  viewBox="-500 0 1100 900"><path d="m 909.1,353.4 0,-67.6 c -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 -71,0 -107.2,14.8 -142.1,29 -34.8,14.2 -70.9,29 -141.7,29 -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 -71.1,0 -107.2,14.8 -142.1,29 -34.8,14.2 -70.9,29 -141.7,29 -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 l 0,632.2 1419,0 z"/></svg>') top/100% auto;
          mask:url('data:image/svg+xml;utf8,<svg version="1.1" xmlns="http://www.w3.org/2000/svg"  viewBox="-500 0 1200 900"><path d="m 909.1,353.4 0,-67.6 c -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 -71,0 -107.2,14.8 -142.1,29 -34.8,14.2 -70.9,29 -141.7,29 -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 -71.1,0 -107.2,14.8 -142.1,29 -34.8,14.2 -70.9,29 -141.7,29 -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 l 0,632.2 1419,0 z"/></svg>') top/100% auto; 
   animation:raise 6s infinite ease-in-out alternate,waves .75s infinite linear;
}
@keyframes waves {
  to {
    transform: translateX(-50%);
  }
}
@keyframes raise {
  to {
    height:160%;
  }
}
Run Code Online (Sandbox Code Playgroud)
<div class="box">
</div>
<div class="box" style="width:200px;">
</div>
Run Code Online (Sandbox Code Playgroud)

要仅使用转换,您可以添加额外的元素:

.box {
  width:300px;
  display:inline-block;
  background: rgb(180, 180, 180);
  border-radius:50%;
  overflow:hidden;
}
.box div {
  padding-top:100%;
  position:relative;    
  animation: raise 6s infinite ease-in-out alternate;
}
.box div:before {
  content:"";
  position:absolute;
  left:0%;
  width:200%;
  height:160%;
  bottom:-10%;
  background:rgb(196, 3, 3);
  -webkit-mask:url('data:image/svg+xml;utf8,<svg version="1.1" xmlns="http://www.w3.org/2000/svg"  viewBox="-500 0 1100 900"><path d="m 909.1,353.4 0,-67.6 c -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 -71,0 -107.2,14.8 -142.1,29 -34.8,14.2 -70.9,29 -141.7,29 -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 -71.1,0 -107.2,14.8 -142.1,29 -34.8,14.2 -70.9,29 -141.7,29 -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 l 0,632.2 1419,0 z"/></svg>') top/100% auto;
          mask:url('data:image/svg+xml;utf8,<svg version="1.1" xmlns="http://www.w3.org/2000/svg"  viewBox="-500 0 1200 900"><path d="m 909.1,353.4 0,-67.6 c -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 -71,0 -107.2,14.8 -142.1,29 -34.8,14.2 -70.9,29 -141.7,29 -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 -71.1,0 -107.2,14.8 -142.1,29 -34.8,14.2 -70.9,29 -141.7,29 -70.8,0 -106.9,-14.7 -141.7,-29 -34.9,-14.3 -71,-29 -142.1,-29 l 0,632.2 1419,0 z"/></svg>') top/100% auto; 
   animation:waves .75s infinite linear;
}
@keyframes waves {
  to {
    transform: translateX(-50%);
  }
}
@keyframes raise {
  from {
    transform:translateY(120%);
  }
}
Run Code Online (Sandbox Code Playgroud)
<div class="box">
<div></div>
</div>
<div class="box" style="width:200px;">
<div></div>
</div>
Run Code Online (Sandbox Code Playgroud)