animateMotion выполняется быстрее

Использую анимацию движения по пути animateMotion в SVG.

Розовый кружок движется по кругу, белый по полукругу.
Их скорость, кейфрейм и прочее совпадает, но есть одно конкретное отличие - анимация розового круга инвертированная, при помощи атрибутов keyPoints="1;0" keyTimes="0;1" (подсмотрел на SO).

Проблема заключается в том, что в FF всё работает как должно (нужный результат), а в Chrome и Opera возникает баг с тем, что розовый круг выполняет своё движение быстрее чем нужно.
У меня предположение, что это вызвано изменением кейфрема при инвертирование анимации.

Тут пример как это отображается:

Firefox Opera & Chrome
FF O

А тут код:

body {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  min-height: 100vh;
  background: #000;
  margin: 0;
}

svg {
  display: block;
}
<svg width="300" viewbox="0 0 200 200" style="background: rgba(255,0,0,.1)">
  <!-- circle big -->
  <g transform="rotate(-63 100 100)">
    <g>
      <defs>
       <path id="cb" d="M 100 190 A 1 1 0 0 1 100 10 A 1 1 0 0 1 100 190 Z" fill="none"/>
      </defs>
      <use xlink:href="#cb" stroke="white" stroke-width="4" stroke-dasharray="0 6" stroke-linecap="round" mask="url(#cbm)"/>
      <mask id="cbm">
        <rect x="0" y="0" width="100%" height="100%" fill="white"/>
        <use id="cba" xlink:href="#cb" stroke="black" stroke-width="5" stroke-dasharray="565.565" stroke-dashoffset="0"/>
        <animate xlink:href="#cba" attributeName="stroke-dashoffset" to="565.565" dur="1.5s" keySplines="0.33 1 0.68 1" calcMode="spline" fill="freeze"/>
      </mask>
    </g>

    <!-- Проблемное место -->
    <circle id="cbb" cx="0" cy="0" r="7" fill="#c4007b" filter="url(#blur)">
      <animateMotion dur="1.5s" restart="whenNotActive" fill="freeze" rotate="auto" keyPoints="1;0" keyTimes="0;1" keySplines="0.33 1 0.68 1" calcMode="spline"><mpath xlink:href="#cb"/></animateMotion>
    </circle>
    <!-- Проблемное место -->
    
    <defs>
      <filter id="blur">
        <feGaussianBlur in="SourceGraphic" stdDeviation=".5" />
      </filter>
    </defs>
  </g>
  
  <!-- circle small -->
  <g transform="rotate(-50 100 100)">
    <!-- left -->
    <g stransform="rotate(45 100 100)">
      <path id="cs-l" d="M 100 35 A 1 1 0 0 0 100 165" fill="none" stroke="#fed485" stroke-width="3" stroke-dasharray="204.232" mask="url(#scbm)"/>
      <animate xlink:href="#cs-l" attributeName="stroke-dashoffset" from="204.232" to="0" dur="1.5s" keySplines="0.33 1 0.68 1" calcMode="spline" fill="freeze"/>
      <!--  -->
      <circle id="scb-l" cx="-6" cy="0" r="6" fill="white">
        <animateMotion dur="1.5s" restart="whenNotActive" fill="freeze" rotate="auto" keySplines="0.33 1 0.68 1" calcMode="spline"><mpath xlink:href="#cs-l"/></animateMotion>
      </circle>
      
      <mask id="scbm">
        <rect x="0" y="0" width="100%" height="100%" fill="white"/>
        <circle cx="106" cy="35" r="9" fill="black"/>
        <circle cx="-6" cy="0" r="9" fill="black">
          <animateMotion dur="1.5s" restart="whenNotActive" fill="freeze" rotate="auto" keySplines="0.33 1 0.68 1" calcMode="spline"><mpath xlink:href="#cs-l"/></animateMotion>
        </circle>
        <circle cx="94" cy="165" r="9" fill="black"/>
        <circle cx="-6" cy="0" r="9" fill="black">
          <animateMotion dur="1.5s" restart="whenNotActive" fill="freeze" rotate="auto" keySplines="0.33 1 0.68 1" calcMode="spline"><mpath xlink:href="#cs-r"/></animateMotion>
        </circle>
      </mask>
    </g>
    
    <!-- right -->
    <g stransform="rotate(45 100 100)">
      <path id="cs-r" d="M 100 165 A 1 1 0 0 0 100 35" fill="none" stroke="#fed485" stroke-width="3" stroke-dasharray="204.232" mask="url(#scbm)"/>
      <animate xlink:href="#cs-r" attributeName="stroke-dashoffset" from="204.232" to="0" dur="1.5s" keySplines="0.33 1 0.68 1" calcMode="spline" fill="freeze"/>
      <!--  -->
      <circle id="scb-r" cx="-6" cy="0" r="6" fill="white">
        <animateMotion dur="1.5s" restart="whenNotActive" fill="freeze" rotate="auto" keySplines="0.33 1 0.68 1" calcMode="spline"><mpath xlink:href="#cs-r"/></animateMotion>
      </circle>
    </g>
  </g>
</svg>

Проблемное место выделил комментом, строка 16 в HTML

Вопрос:
Чем это вызвано и как это решить?

Мне что-то подсказывает, что проблема может быть ещё и в самом path, по которому происходит движение, возможно было бы проще инвертировать его, чем движение розового кружка.


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

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

Когда используется реверс направления движения с помощью атрибутов keyPoints="1;0" и keyTimes="0;1" Firefox это нормально воспринимает.
У браузеров на движке webkit :Chrome, Opera, Yandex, safari и др. наблюдается баг при совместном использовании calcMode="spline" и атрибутов keyPoints="1;0" и keyTimes="0;1"

Необходимо использовать calcMode="linear", в этом случае анимация будет работать во всех браузерах одинаково!

body {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  min-height: 100vh;
  background: #000;
  margin: 0;
}

svg {
  display: block;
}
<svg width="300" viewbox="0 0 200 200" style="background: rgba(255,0,0,.1)">
  <!-- circle big -->
  <g transform="rotate(-63 100 100)">
    <g>
      <defs>
       <path id="cb" d="M 100 190 A 1 1 0 0 1 100 10 A 1 1 0 0 1 100 190 Z" fill="none"/>
      </defs>
      <use xlink:href="#cb" stroke="white" stroke-width="4" stroke-dasharray="0 6" stroke-linecap="round" mask="url(#cbm)"/>
      <mask id="cbm">
        <rect x="0" y="0" width="100%" height="100%" fill="white"/>
        <use id="cba" xlink:href="#cb" stroke="black" stroke-width="5" stroke-dasharray="565.565" stroke-dashoffset="0"/>
        <animate xlink:href="#cba" attributeName="stroke-dashoffset" to="565.565" dur="1.5s" keySplines="0.33 1 0.68 1" calcMode="linear" fill="freeze"/>
      </mask>
    </g>

    <!-- Проблемное место -->
    <circle id="cbb" cx="0" cy="0" r="7" fill="#c4007b" filter="url(#blur)">
      <animateMotion dur="1.5s" restart="whenNotActive" fill="freeze" rotate="auto" keyPoints="1;0" keyTimes="0;1" keySplines="0.33 1 0.68 1" calcMode="linear"><mpath xlink:href="#cb"/></animateMotion>
    </circle>
    <!-- Проблемное место -->
    
    <defs>
      <filter id="blur">
        <feGaussianBlur in="SourceGraphic" stdDeviation=".5" />
      </filter>
    </defs>
  </g>
  
  <!-- circle small -->
  <g transform="rotate(-50 100 100)">
    <!-- left -->
    <g stransform="rotate(45 100 100)">
      <path id="cs-l" d="M 100 35 A 1 1 0 0 0 100 165" fill="none" stroke="#fed485" stroke-width="3" stroke-dasharray="204.232" mask="url(#scbm)"/>
      <animate xlink:href="#cs-l" attributeName="stroke-dashoffset" from="204.232" to="0" dur="1.5s" keySplines="0.33 1 0.68 1" calcMode="spline" fill="freeze"/>
      <!--  -->
      <circle id="scb-l" cx="-6" cy="0" r="6" fill="white">
        <animateMotion dur="1.5s" restart="whenNotActive" fill="freeze" rotate="auto" keySplines="0.33 1 0.68 1" calcMode="spline"><mpath xlink:href="#cs-l"/></animateMotion>
      </circle>
      
      <mask id="scbm">
        <rect x="0" y="0" width="100%" height="100%" fill="white"/>
        <circle cx="106" cy="35" r="9" fill="black"/>
        <circle cx="-6" cy="0" r="9" fill="black">
          <animateMotion dur="1.5s" restart="whenNotActive" fill="freeze" rotate="auto" keySplines="0.33 1 0.68 1" calcMode="spline"><mpath xlink:href="#cs-l"/></animateMotion>
        </circle>
        <circle cx="94" cy="165" r="9" fill="black"/>
        <circle cx="-6" cy="0" r="9" fill="black">
          <animateMotion dur="1.5s" restart="whenNotActive" fill="freeze" rotate="auto" keySplines="0.33 1 0.68 1" calcMode="spline"><mpath xlink:href="#cs-r"/></animateMotion>
        </circle>
      </mask>
    </g>
    
    <!-- right -->
    <g stransform="rotate(45 100 100)">
      <path id="cs-r" d="M 100 165 A 1 1 0 0 0 100 35" fill="none" stroke="#fed485" stroke-width="3" stroke-dasharray="204.232" mask="url(#scbm)"/>
      <animate xlink:href="#cs-r" attributeName="stroke-dashoffset" from="204.232" to="0" dur="1.5s" keySplines="0.33 1 0.68 1" calcMode="spline" fill="freeze"/>
      <!--  -->
      <circle id="scb-r" cx="-6" cy="0" r="6" fill="white">
        <animateMotion dur="1.5s" restart="whenNotActive" fill="freeze" rotate="auto" keySplines="0.33 1 0.68 1" calcMode="spline"><mpath xlink:href="#cs-r"/></animateMotion>
      </circle>
    </g>
  </g>
</svg>

→ Ссылка