Анимация пути SVG с использованием CSS вместо <animateMotion> - PullRequest
0 голосов
/ 05 мая 2020

Я пытаюсь поместить стрелку в середину кривой Безье. Решение, использующее <animateMotion> в вопросе Как правильно сдвинуть стрелку на кубе c Безье в SVG в его центр , который перемещает <path>, который является стрелкой, и фиксирует ее в середине кривая Безье, работает только в Firefox. Поскольку в моем случае точки кривой постоянно меняются, я не хотел использовать marker-mid, так как для меня каждый раз дорого рассчитывать среднюю точку кривой Безье.

<svg viewBox="0 0 500 500">
<g>
    <path id="path1" d="M291.698 268.340 C321.698 268.340, 411.904 93.133 441.904 93.133"></path>
    <path class="path_arrow" d="M0,0 L6,6 L0,12" transform="translate(-3,-6)">
        <animateMotion dur="0s" rotate="auto" fill="freeze" keyTimes="0;1" keyPoints="0.5;0.5">
            <mpath xlink:href="#path1"></mpath>
        </animateMotion>
    </path> 
</g>
<g transform="translate(166.698,243.340)">
    <circle r="5" class="p1"></circle>
</g>
<g transform="translate(441.904,68.133)" >
 <circle r="5" class="p2"></circle>
</g>
</svg>

Есть ли способ чтобы сделать это с помощью CSS Animations, чтобы избежать использования <animateMotion>?

EDIT 1:

Конечные точки кривой здесь можно перетаскивать, поэтому точки кривой имеют тенденцию часто меняться. Анимация заключается в перемещении стрелки к центру кривой без вычисления средних точек. enter image description here

EDIT 2:

Thanks to Kaiido's comment, I added calcMode="linear" and the arrow is now placed on the path as expected. But When I reposition the end point by dragging, the arrow stays in its initial position(as shown) in Chrome but it is expected to move along the parent path. In Firefox this is working fine as before.

введите описание изображения здесь

Ответы [ 2 ]

2 голосов
/ 06 мая 2020

Вы можете добиться того же с помощью CSS offset-path, offset-distance и offset-rotate свойств:

#path1 {
  fill: none;
  stroke: black;
}
.path_arrow {
  transform: translate( -3px, -6px );
  offset-path: path("M220 104C220 144,400 180,400 224");
  offset-rotate: auto;
  offset-distance: 50%;
}
body { background: white; }
<svg width="500" height="500" >
  <path id="path1" d="M 220 104 C 220 144 400 180 400 224"
        fill="none" stroke-width="2" stroke="black" />
  <path class="path_arrow" d="M0,0 L0,12 L12,6 z" />
</svg>

Но поддержка их браузером намного ниже, чем у SMIL , поэтому я бы не рекомендовал его .

Обратите внимание, что я исправил ответ там , где отсутствовал атрибут calcMode="linear", чтобы порадовать браузеры Blink.

Если вам нужна поддержка IE, вы можете попробовать эту js реализацию , которая, кажется, поддерживает <animateMotion> и rotate, имея в виду, что я не тестировал ее сам.

Что касается вопроса «РЕДАКТИРОВАТЬ 2»:

Chrome действительно, кажется, нужен явный вызов для обновления <mpath>. Это можно сделать, вызвав метод beginElement() элемента <animationMotion> после каждого обновления:

document.querySelector('svg').onmousemove = function(e) {
  const rect = this.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;
  path1.setAttribute( 'd', `M ${x} ${y} C 220 144 400 180 400 224` );
  // Chrome requires an explicit update
  document.querySelector('animateMotion').beginElement();
}
move your mouse to change the path
0 голосов
/ 06 мая 2020

Вы должны использовать анимацию webkit внутри css. Также я бы рекомендовал https://codepen.io/collection/yivpx/. Это проект с открытым исходным кодом для оптимизации SVG. Я также рекомендую вам назвать все свои классы в SVG, чтобы делать классные CSS вещи с анимацией, например:

animation: kaboom 5s ease alternate infinite;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...