Почему эта анимация маски SVG прерывистая в Firefox, но плавная в Chrome?
Я упростил анимацию 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);
}
}
<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>
CSS-анимация translates (смещает) как по горизонтали, так и по вертикали, но с разной скоростью.
Я также пробовал использовать <clipPath> вместо <mask> и получил те же результаты, такие же прерывистые аннимации в Firefox в Windows и Linux.
Одна очень странная особенность, которую я заметил в Firefox, заключается в том, что если у меня открыты инструменты разработчика, анимация иногда будет работать плавно. Инструменты разработчика Firefox тоже, похоже, не указывают на какие-либо проблемы, но я не эксперт в SVG-анимации. Почему Firefox подавляется этим, а Chrome - нет?
Свободный перевод вопроса Why is this SVG mask animation choppy in Firefox but smooth in Chrome? от участника @j08691.
Ответы (1 шт):
Другая идея с использованием маски CSS, где у вас не будет проблемы. Я использовал путь, указанный вами, как маску. Просто убедитесь, что вы установили правильное значение для 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%;
}
}
<div class="box">
</div>
<div class="box" style="width:200px;">
</div>
Чтобы использовать только transformation, вы можете добавить дополнительный элемент:
.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%);
}
}
<div class="box">
<div></div>
</div>
<div class="box" style="width:200px;">
<div></div>
</div>
Свободный перевод ответа от участника @Temani Afif.