I'm new at animating SVGs with CSS and I'm trying to create a "blinking eye" effect. This is what I've managed to do:
https://codepen.io/pablo-m/pen/jOGeMpJ.
(Edit 3: Code added)
SVG
<svg id="composicion" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 571.8 761.82">
<g id="Ojito">
<rect x="190.37" y="288.55" width="192.7" height="91.76" fill="#606060" />
<ellipse id="outer-eye" cx="292.3" cy="335.43" rx="44.72" ry="30.01" fill="#3caa56" />
<circle id="inner-eye" cx="291.69" cy="334.82" r="18.38" fill="#efefef" />
</g>
</svg>
SCSS
#composicion {
#Ojito {
@keyframes inner-eye-blink {
0%,
82%,
95%,
100% {
clip-path: ellipse(75% 55%);
}
90% {
clip-path: ellipse(75% 0);
}
}
@keyframes outer-eye-blink {
0%,
80%,
100% {
ry: 30.01px;
}
90% {
ry: 1px;
}
}
& #outer-eye {
animation: outer-eye-blink 8s ease infinite;
}
& #inner-eye {
animation: inner-eye-blink 8s infinite;
}
}
}
The animation works great on Firefox v95.0.2 and Safari v15.1. However, on Chrome/Chromium v97.0.4692.71 (as of today, the latest version) it does not. It looks like, whenever I apply a clip-path with css the white circle dissapears. I also noticed that this behaviour does not happen on Chrome/Chromium v96.0.4664.93. Am I doing something wrong or did something change in the latest version of Chrome/Chromium? Edit: If I did everything correctly, does anyone know a workaround?
This is my first question in SO, so please let me know if I missed any detail.
Thanks!
Edit: I have looked at Chromium's bug tracker but I've not found any relevant issues there.
Edit 2: Chromium bug reported
CodePudding user response:
It looks like it's a Chrome bug indeed. However, I managed to find a workaround which solves the issue: https://codepen.io/pablo-m/pen/WNZYeoB
SCSS
#composicion {
#Ojito {
@keyframes inner-eye-move {
0%,
5%,
20%,
25%,
40%,
45%,
50%,
60%,
65%,
80%,
85%,
100% {
cx: 291.69px;
cy: 334.82px;
}
10%,
15% {
cx: 273.69px;
cy: 328.82px;
}
30%,
35% {
cx: 291.69px;
cy: 342.82px;
}
70%,
75% {
cx: 310.69px;
cy: 328.82px;
}
90%,
95% {
cx: 307.69px;
cy: 338.82px;
}
}
@keyframes outer-eye-blink {
0%,
80%,
100% {
ry: 30.01px;
}
90% {
ry: 1px;
}
}
& .outer-eye {
animation: outer-eye-blink 8s ease infinite;
}
& #inner-eye {
clip-path: url(#eyeClip);
animation: inner-eye-move 50s ease infinite;
}
}
}
SVG
<svg id="composicion" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 571.8 761.82">
<g id="Ojito">
<rect x="190.37" y="288.55" width="192.7" height="91.76" fill="#606060" />
<clipPath id="eyeClip">
<ellipse cx="292.3" cy="335.43" rx="44.72" ry="30.01" />
</clipPath>
<ellipse cx="292.3" cy="335.43" rx="44.72" ry="30.01" fill="#3caa56" />
<circle id="inner-eye" cx="291.69" cy="334.82" r="18.38" fill="#efefef" />
</g>
</svg>
I'll edit my question and answer when I post the bug on the Chrome bug tracker.
Edit: Chromium bug reported
CodePudding user response:
In a situation like this it is a good idea to use either a clip-path or a mask. In this example I chose a clip-path because you started off with the animation in CSS. If you where going to use a SMIL animation I would have used a mask.
I used SvgPathEditor for constructing the path.
@keyframes eye-blink {
0%,
100% {
clip-path: path('M 3 5 C 6 6 9 7 13 5 C 9 2 6 3 3 5');
}
50% {
clip-path: path('M 3 5 C 6 5 9 5 13 5 C 9 5 6 5 3 5');
}
}
#Ojito g {
clip-path: path('M 3 5 C 6 6 9 7 13 5 C 9 2 6 3 3 5');
animation: eye-blink 4s ease infinite;
}
<svg id="composicion" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 10" width="400">
<g id="Ojito">
<rect width="16" height="10" fill="#606060" />
<g>
<rect width="16" height="10" fill="white" />
<circle id="inner-eye" cx="8" cy="4.8" r="2" fill="#333" />
<circle id="inner-eye" cx="8" cy="4.8" r="1.2" fill="black" />
</g>
</g>
</svg>
