Как заставить совместно корректно работать анимации SVG и CSS?

Пытаюсь разобраться, как взаимодействуют анимации CSS и SVG. Для этого взял простейший сценарий:

  1. Персонаж перемещается справа налево с одновременными перемещениями вверх, вниз (svg)
  2. Поворот на 180 градусов (css) и
  3. движение назад слева-направо (css)

Вот код:

body { perspective: 1000px;}

  .container{
  width:80vw;
  height:80vh;
}  
#SnowMaiden {
transform-box:fill-box;
transform-origin: center center;
animation: Maiden_rotate 2s linear 8s  forwards, Maiden_translate 14s linear 16s forwards;
}
@keyframes Maiden_rotate {
0%{ transform:  rotate3d(0,1,0,20deg);}
50%{ transform:  rotate3d(0,1,0,80deg);}
100%{ transform:  rotate3d(0,1,0,180deg);}
}
@keyframes Maiden_translate {
0%{ transform:  translate3d(300px,10px,10px);}
50%{ transform:  translate3d(800px,10px,10px);}
100%{ transform:  translate3d(1400px,10px,10px);}
}
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
        xmlns:xlink="http://www.w3.org/1999/xlink"
            viewBox="0 0 1680 1050" preserveAspectRatio="xMinYMin meet" > 

       <!-- Фон с ёлочкой -->
    <image id="img1" xlink:href="https://i.sstatic.net/PBRad.jpg" width="100%" height="100%" opacity="1"   />  
    
    <image  id="SnowMaiden" x="1400" y="650"  xlink:href="https://i.sstatic.net/LU3Bvfdr.png" opacity="0">
                  <!-- Анимация появления девочки с корзинкой -->
   <animate id="op1_Maidan" attributeName="opacity"   values="0; 1" dur="2s" begin="svg1.click"  repeatCount="1" fill="freeze" restart="whenNotActive" />   
                            <!-- Перемещение  по горизонтали -->
  <animate id="Go_Maidan" attributeName="x"   values="1400;1300;1200;1100;1000;900;800;700;600;500;400;300" dur="5s" begin="op1_Maidan.end"  repeatCount="indefinity" fill="freeze"  restart="whenNotActive"  />   
                         <!-- Перемещение по вертикали -->    
   <animate id="Go_Maidan_y" attributeName="y"   values="650;670;650;630;650;670;650;630;650;670;650;630" dur="5s" begin="op1_Maidan.end"  repeatCount="indefinity" fill="freeze"   restart="whenNotActive"  />  
</image>  
</svg>

Как видно из результата работы снипета:
Этап анимации SVG до поворота на 180 всё нормально. Сбой начинается после поворота. Такое ощущение что CSS анимация вступила в конфликт с предыдущей анимацией SVG и поэтому не видно результата движения с помощью CSS.
Конечно можно реализовать анимации чисто на SVG или только с CSS.
И у меня вопрос, как заставить совместно корректно работать анимации SVG и CSS?


Ответы (2 шт):

Автор решения: puffleeck

тут дело не в SMIL vs CSS. просто выбранное свойство делает не совсем то что требуется.

body {perspective: 1000px}

#girl {
  transform-box:fill-box;
  transform-origin: center center;
  animation: 
    mR 2s linear 9.5s forwards,
    mT 5s linear 12s forwards,
    mR 2s linear 17s reverse forwards;
}
@keyframes mR {
  0%    {transform: rotate3d(0,1,0,20deg)}
  50%   {transform: rotate3d(0,1,0,80deg)}
  100%  {transform: rotate3d(0,1,0,180deg)}
}
@keyframes mT {
/* transform: translate не меняет исходные координаты,
а смещает от них(300px+300px = 600px) */
  0%  {x: 300px;  y: 630px}
  10% {x: 410px;  y: 650px}
  20% {x: 520px;  y: 670px}
  30% {x: 630px;  y: 650px}
  40% {x: 740px;  y: 630px}
  50% {x: 850px;  y: 650px}
  60% {x: 960px;  y: 670px}
  70% {x: 1070px; y: 650px}
  80% {x: 1180px; y: 630px}
  90% {x: 1290px; y: 650px}
  100%{x: 1400px; y: 670px}
}
<svg id="xyz" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1680 1050"
xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMinYMin meet" > 
  <image width="100%" height="100%" xlink:href="https://i.sstatic.net/PBRad.jpg"/>
  <image id="girl" x="1400" y="650" opacity="0"
    xlink:href="https://i.sstatic.net/LU3Bvfdr.png">

    <animate id="spawn"
      attributeName="opacity"
      begin="xyz.click" values="0; 1"
      dur="2s" repeatCount="1" fill="freeze" restart="whenNotActive" />

    <animate
      attributeName="x"
      begin="spawn.end"
      values="1400;1300;1200;1100;1000;900;800;700;600;500;400;300"
      dur="5s" repeatCount="indefinity" fill="freeze" restart="whenNotActive"/>

    <animate
      attributeName="y"
      begin="spawn.end"
      values="650;670;650;630;650;670;650;630;650;670;650;630"
      dur="5s" repeatCount="indefinity" fill="freeze" restart="whenNotActive"/>
  </image>  
</svg>

→ Ссылка
Автор решения: Alexandr_TT

Решение SVG

Добавлено зацикливание пакета анимаций: движения + поворота.
Зацикливание достигается условием:
begin="op1_Maidan.end;scale_M2.end", где
scale_M2.end" - окончание анимации поворота персонажа в начальной точке после первого цикла.

.container{
  width:80vw;
  height:80vh;
}  
#SnowMaiden {
transform-box:fill-box;
transform-origin: center center;
}
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
        xmlns:xlink="http://www.w3.org/1999/xlink"
            viewBox="0 0 1680 1050" preserveAspectRatio="xMinYMin meet" > 

       <!-- Фон с ёлочкой -->
    <image id="img1" xlink:href="https://i.sstatic.net/PBRad.jpg" width="100%" height="100%" opacity="1"   />  
    
    <image  id="SnowMaiden" x="1400" y="650"  xlink:href="https://i.sstatic.net/LU3Bvfdr.png" opacity="0">
                  <!-- Анимация появления девочки с корзинкой -->
   <animate id="op1_Maidan" attributeName="opacity"   values="0; 1" dur="2s" begin="svg1.click"  repeatCount="1" fill="freeze" restart="whenNotActive" />   
                            <!-- Перемещение  по горизонтали -->
   <animate id="Go_Maidan" attributeName="x"   values="1400;1300;1200;1100;1000;900;800;700;600;500;400;300" dur="5s" begin="op1_Maidan.end;scale_M2.end"  repeatCount="1" fill="freeze"  restart="whenNotActive"  />   
                         <!-- Перемещение по вертикали -->    
    <animate id="Go_Maidan_y" attributeName="y"   values="650;670;650;630;650;670;650;630;650;670;650;630" dur="5s" begin="Go_Maidan.begin"  repeatCount="1" fill="freeze"   restart="whenNotActive"  />  
                              <!-- Поворот -->
      <animateTransform id="scale_M" attributeName="transform" type="scale" values="-1 1" begin="Go_Maidan_y.end" dur="0.1s" fill="freeze" />  
                               <!-- Назад по Х     -->
    <animate id="Go_back_x" attributeName="x"   values="300;400;500;600;700;800;900;1000;1100;1200;1300;1400" dur="5s" begin="scale_M.end"  repeatCount="1" fill="freeze"  restart="whenNotActive"  />    
                                    <!-- Назад по Y -->
     <animate id="Go_back_y" attributeName="y"   values="650;670;650;630;650;670;650;630;650;670;650;630" dur="5s" begin="scale_M.end"  repeatCount="1" fill="freeze"   restart="whenNotActive"  />
     
                             <!-- Поворот -->
      <animateTransform id="scale_M2" attributeName="transform" type="scale" values="1 1" begin="Go_back_y.end" dur="0.1s" fill="freeze" />  
    
</image>  
</svg>

→ Ссылка