• Как правильно сбросить svg анимацию?

    Dr_Elvis
    @Dr_Elvis
    В гугле забанен
    Предлагаю к каждой анимации добавить "анти анимацию", которая при выключении тумблера будет делать то же самое, только наоборот, ну и конечно очень быстро.
    Итого:
    Добавить анимацию наоборот к каждому элементу:
    <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="731"
                  height="366"
                  viewBox="0 0 731 366"
                >
                  <g fill="none" fill-rule="evenodd">
                    <!--ЛИНИЯ-->
                    <path
                      id="graph"
                      stroke-linejoin="round"
                      stroke-width="4"
                      d="M24 359.5c337.042-37 563.376-143.167 679-318.5"
                      style="stroke:#D3D802;stroke-width:3px;stroke-dasharray:1358;stroke-dashoffset:1358;"
                    />
                    <animate
                      xlink:href="#graph"
                      begin="click"
                      id="ani-graph"
                      dur="3s"
                      attributeName="stroke-dashoffset"
                      to="0"
                      fill="freeze"
                    />
                    <!--анимация наоборот-->
                    <animate
                      xlink:href="#graph"
                      begin="click"
                      id="ani2-graph"
                      dur="0.01s"
                      attributeName="stroke-dashoffset"
                      to="1358"
                      fill="freeze"
                    />
                    <!--КРУЖКИ-->
                    <circle
                      id="point1"
                      cx="23"
                      cy="359"
                      r="5"
                      fill="#FFF"
                      stroke="#EF7D01"
                      stroke-width="4"
                      opacity="0"
                    />
                    <animate
                      xlink:href="#point1"
                      begin="click"
                      restart="whenNotActive"
                      id="ani-point1"
                      attributeName="opacity"
                      to="1"
                      fill="freeze"
                      dur="0.25s"
                    />
                    <!--анимация наоборот-->
                    <animate
                      xlink:href="#point1"
                      begin="click"
                      restart="whenNotActive"
                      id="ani2-point1"
                      attributeName="opacity"
                      to="0"
                      fill="freeze"
                      dur="0.01s"
                    />
    
                    <circle
                      id="point3"
                      cx="703"
                      cy="41"
                      r="5"
                      fill="#FFF"
                      stroke="#EF7D01"
                      stroke-width="4"
                      opacity="0"
                    />
                    <animate
                      xlink:href="#point3"
                      begin="click"
                      restart="whenNotActive"
                      id="ani-point3"
                      attributeName="opacity"
                      to="1"
                      fill="freeze"
                      dur="0.25s"
                    />
                    <!--анимация наоборот-->
                    <animate
                      xlink:href="#point3"
                      begin="click"
                      restart="whenNotActive"
                      id="ani2-point3"
                      attributeName="opacity"
                      to="0"
                      fill="freeze"
                      dur="0.01s"
                    />
    
                    <circle
                      id="point2"
                      cx="383"
                      cy="279"
                      r="5"
                      fill="#FFF"
                      stroke="#EF7D01"
                      stroke-width="4"
                      opacity="0"
                    />
                    <animate
                      xlink:href="#point2"
                      begin="click"
                      restart="always"
                      id="ani-point2"
                      attributeName="opacity"
                      to="1"
                      fill="freeze"
                      dur="0.25s"
                    />
                    <!--анимация наоборот-->
                    <animate
                      xlink:href="#point2"
                      begin="click"
                      restart="always"
                      id="ani2-point2"
                      attributeName="opacity"
                      to="0"
                      fill="freeze"
                      dur="0.01s"
                    />
                  </g>
                </svg>

    А далее запускаем эти анимации при выключении тумблера:
    document.addEventListener("DOMContentLoaded", function() {
            let radioBtn = document.querySelector("#checkbox");
            let badImg = document.querySelector(".graph__img--bad");
            let goodImg = document.querySelector(".graph__svg");
            //let graphInfo = document.querySelector(".graph-info"); Тут закомментировал, так как элемента нет
            let graphMark = document.querySelector(".graph__mark");
            let graphBody = document.querySelector(".graph__radio");
            let graphSection = document.querySelector(".graph");
    
            let svgLine = document.getElementById("ani-graph");
            let svgPoint1 = document.getElementById("ani-point1");
            let svgPoint2 = document.getElementById("ani-point2");
            let svgPoint3 = document.getElementById("ani-point3");
    
            let animate = document.querySelectorAll("animate");
            const toggleGraph = () => {
              let isChecked = radioBtn.checked;
    
              if (isChecked) {
                svgLine.beginElement();
    
                setTimeout(() => svgPoint1.beginElement(), 100);
                setTimeout(() => svgPoint2.beginElement(), 800);
                setTimeout(() => svgPoint3.beginElement(), 1730);
    
                badImg.classList.add("hide");
                goodImg.classList.add("show");
                //graphInfo.classList.add("show"); Тут закомментировал, так как элемента нет
                graphMark.classList.add("show");
                graphBody.classList.add("show");
                graphSection.classList.add("active");
              } else {
                animate.forEach(item => {
                  item.onend = () => {
                    console.log("endEvent fired");
                  };
                });
                badImg.classList.remove("hide");
                goodImg.classList.remove("show");
                //graphInfo.classList.remove("show"); Тут закомментировал, так как элемента нет
                graphMark.classList.remove("show");
                graphBody.classList.remove("show");
                graphSection.classList.remove("active");
    
                document.getElementById("ani2-graph").beginElement();// Запуск анимации наоборот
                document.getElementById("ani2-point1").beginElement();// Запуск анимации наоборот
                document.getElementById("ani2-point2").beginElement();// Запуск анимации наоборот
                document.getElementById("ani2-point3").beginElement();// Запуск анимации наоборот
              }
            };
    
            radioBtn.addEventListener("click", toggleGraph);
          });
    Ответ написан
    Комментировать
  • Как правильно сбросить svg анимацию?

    RAX7
    @RAX7
    beginElement и onend новые фичи и еще плохо поддерживаются браузерами. Нормальным способом сделать анимацию на svg можно с помощью библиотек на js (animejs, kutejs, gsap).
    Я не знаю нормального способа как сбросить smil анимацию, можно клонировать тег animate, заменить оригинал клоном и клону задать атрибут begin = performance.now().
    https://codesandbox.io/s/graph-animation-yglnz?fil...
    P.s. свойства stroke-dashoffset и opacity должны нормально анимироваться через css (keyframes/transition), так что от smil анимации можно вообще избавиться.
    Ответ написан
    1 комментарий