animateMotion выполняется быстрее
Использую анимацию движения по пути animateMotion в SVG.
Розовый кружок движется по кругу, белый по полукругу.
Их скорость, кейфрейм и прочее совпадает, но есть одно конкретное отличие - анимация розового круга инвертированная, при помощи атрибутов keyPoints="1;0" keyTimes="0;1" (подсмотрел на SO).
Проблема заключается в том, что в FF всё работает как должно (нужный результат), а в Chrome и Opera возникает баг с тем, что розовый круг выполняет своё движение быстрее чем нужно.
У меня предположение, что это вызвано изменением кейфрема при инвертирование анимации.
Тут пример как это отображается:
А тут код:
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 шт):
Когда используется реверс направления движения с помощью атрибутов 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>

