Вернуть объект на прежнюю позицию SVG

102
23 мая 2019, 21:40

Есть объект, который я анимирую с помощью animateMotion. После клика на кнопку остановки анимации stop объект должен вернуться на прежнее место, где он бы отрендерился без той же анимации, в данном случае x & y = 0, но при остановке анимации объект сохраняет своё местоположение, чего фактически не должно быть. Может я неправильно пытаюсь отключить анимацию, изменяю атрибут(xlink:href), принимающий объект, который будет двигаться вдоль пути, то есть квадрат, который есть в примере ниже. Может быть есть какие-то встроенные функции для SVG, в чём я очень сильно сомневаюсь, хотелось бы услышать вразумительный ответ по этому поводу.

Минимальный пример:

document.querySelector('button').onclick = () => { 
  document.querySelector('#AM').setAttribute('xlink:href', '  '); 
};
<div class="wrapper"> 
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="border: 0.0625rem solid"> 
    <g class="main-area"> 
      <path d="M0 75L300 75" fill="none" stroke="red" id="AMP"/> 
      <rect x="0" y="0" width="50" height="50" id="TrO" transform="translate(0 -25)"/> 
      <animateMotion id="AM" xlink:href="#TrO" begin="0s" dur="3s" repeatCount="indefinite"> 
        <mpath xlink:href="#AMP"/> 
      </animateMotion> 
    </g> 
  </svg> 
  <button>Stop</button> 
</div>

Answer 1

Конечно, не самый лучший вариант, но работу свою делает.

document.querySelector('button').onclick = () => { 
  const am = document.querySelector('#AM'); 
  am.querySelector('mpath').setAttribute('xlink:href', '#AMP1'); 
  am.setAttribute('repeatCount', '0'); 
};
<div class="wrapper"> 
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="border: 0.0625rem solid"> 
    <g class="main-area"> 
      <path d="M0 75L300 75" fill="none" stroke="red" id="AMP"/> 
      <path d="M0 75" fill="none" stroke="red" id="AMP1"/> 
      <rect x="0" y="0" width="50" height="50" id="TrO" transform="translate(0 -25)"/> 
      <animateMotion id="AM" xlink:href="#TrO" begin="0s" dur="3s" repeatCount="indefinite" fill='freeze'> 
        <mpath xlink:href="#AMP"/> 
      </animateMotion> 
    </g> 
  </svg> 
  <button>Stop</button> 
</div>

Также есть специальный метод endElement(), который останавливает анимацию.

document.querySelector('button').onclick = () => { 
  document.querySelector('#AM').endElement(); 
};
<div class="wrapper"> 
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="border: 0.0625rem solid"> 
    <g class="main-area"> 
      <path d="M0 75L300 75" fill="none" stroke="red" id="AMP"/> 
      <path d="M0 75" fill="none" stroke="red" id="AMP1"/> 
      <rect x="0" y="0" width="50" height="50" id="TrO" transform="translate(0 -25)"/> 
      <animateMotion id="AM" xlink:href="#TrO" begin="0s" dur="3s" repeatCount="indefinite" fill='remove'> 
        <mpath xlink:href="#AMP"/> 
      </animateMotion> 
    </g> 
  </svg> 
  <button>Stop</button> 
</div>

Answer 2

Pure SVG

Можно попробовать другой вид анимации, где будет анимироваться атрибут "x" координата ыерхнего левого угла прямоугольника.

<animate id="AM" attributeName="x" values="0;300" begin="play.click" end="stop.click" dur="3s" repeatCount="indefinite">  

В зависимости от поставленной задачи кнопку Play можно убрать.

<div class="wrapper"> 
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="border: 0.0625rem solid"> 
   
<polyline points="0,75 300,75" stroke="crimson" /> 
 <g class="main-area"> 
  <rect x="0" y="50" width="50" height="50" id="TrO" > 
   <animate id="AM"  
    attributeName="x"  
    values="0;300" 
    begin="play.click"  
    end="stop.click"  
    dur="3s" 
    repeatCount="indefinite"> 
   </animate> 
  </rect> 
 </g> 
   <g id="stop"> 
     <rect id="btn1"  
      x="240" y="120"  
      width="50" height="20" 
      fill="#d3d3d3"  
      stroke="black"/> 
	<text x="250" y="135" font-size="16">Stop</text> 
   </g> 
	<g id="play"> 
	 <rect id="btn2" 
          x="180" y="120" 
          width="50" height="20" 
          fill="#d3d3d3"  
          stroke="black"/> 
	    <text x="190" y="135" font-size="16">Play</text> 
	</g> 
   
  </svg> 
  </div>

Вариант с анимацией animateMotion

<div class="wrapper"> 
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="border: 0.0625rem solid"> 
    <g class="main-area"> 
      <path d="M0 75L300 75" fill="none" stroke="red" id="AMP"/> 
        <rect id="TrO" 
         transform="translate(0 -25)" 
          x="0" y="0"  
          width="50" 
         height="50" /> 
      <animateMotion id="AM"  
          xlink:href="#TrO"  
	  begin="play.click"  
	  end="stop.click"  
	  dur="3s"  
	  repeatCount="indefinite"> 
        <mpath xlink:href="#AMP"/> 
      </animateMotion> 
    </g> 
     
	<g id="stop"> 
	  <rect id="btn1"  
	   x="240" y="120"  
           width="50" height="20"  
	  fill="#d3d3d3"  
	stroke="black"/> 
	<text x="250" y="135" font-size="16">Stop</text> 
	</g> 
	  <g id="play"> 
       	<rect id="btn2"  
	      x="180" y="120"  
	      width="50" 
              height="20"  
             fill="#d3d3d3" 
             stroke="black"/> 
	<text x="190" y="135" font-size="16">Play</text> 
	</g> 
	</svg> 
 
</div> 

Update 9.12.2018

Отформатирован SVG код в стиле CSS правил для более легкого восприятия

READ ALSO
Реализация highlight

Реализация highlight

Нужно реализовать подсветку текста в div при вводе в input без использования сторонних плагиновВ существующем коде надо решить две проблемы:

101
Анимация текста jQuery

Анимация текста jQuery

Как реализовать это условиеПодскажите: Заголовок красного цвета движется слева направо, уменьшается и увеличивается по 2 раза соответственно,...

151
Как работает .append в JS?

Как работает .append в JS?

Подскажите пожалуйста на примере такой разметки:

121
Как позиционировать slick slider абсолютно?

Как позиционировать slick slider абсолютно?

Доброго времени суток всем, суть проблемы: Имеется на странице slick sliderЕсть необходимость разместить его абсолютным позиционированием, но если...

131