代码之家  ›  专栏  ›  技术社区  ›  Simplicissimus

如何使用javascript为svg转换计时

  •  2
  • Simplicissimus  · 技术社区  · 2 年前

    在这个例子中,单击svg plus按钮时会转换为关闭按钮,反之亦然 svg.setAttribute("transform","rotate(45)");

    是否有可能对这种转变进行时间安排,使其不仅仅是一种转变,而是一种平稳的过渡?

    示例如下:

    function rotate() {
      var svg = document.getElementById("svgID");
      if (svg.getAttribute("transform") === "rotate(45)") {
        svg.setAttribute("transform", "rotate(0)");
      } else {
        svg.setAttribute("transform", "rotate(45)");
      }
    }
    #button {
      margin: 0;
      padding: 0;
      background: none;
      outline: none;
      box-shadow: none;
      border: none;
    }
    <button id="button" onclick="rotate()">
            <svg id="svgID"
            width="100%"
            height="100%"
            viewBox="0 0 142.40739 142.40991"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            xmlns:svg="http://www.w3.org/2000/svg">
           <defs
              id="defs6" />
            <path
              id="rect234"
              style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-miterlimit:0;stroke-dasharray:none;paint-order:stroke fill markers"
              d="m 85.223081,28.929132 a 4.2333333,4.2333333 0 0 0 -4.233333,4.233333 v 62.801852 l -65.486442,-0.24339 a 4.107912,4.107912 0 0 0 -4.247803,3.96255 4.2333333,4.2333333 0 0 0 4.217313,4.249353 l 65.516932,0.24339 v 62.9295 a 4.107912,4.107912 0 0 0 3.978568,4.23333 4.2333333,4.2333333 0 0 0 4.233334,-4.23333 v -62.89901 l 60.21338,0.22376 a 4.107912,4.107912 0 0 0 4.2478,-3.96255 4.2333333,4.2333333 0 0 0 -4.21731,-4.248833 L 89.20165,95.994807 V 33.162465 a 4.107912,4.107912 0 0 0 -3.978569,-4.233333 z"
              transform="translate(-11.255471,-28.929132)" />
            </svg>
         </button>

    svg transformation with setAttribute(“变换”,旋转(45)“)`:

    svg transformation with setAttribute("transform",rotate(45)")

    2 回复  |  直到 2 年前
        1
  •  2
  •   Jaromanda X    2 年前

    方法1: requestAnimationFrame

    function anim(from, to, cb, duration=100) {
      let startms;
      const frame = ms => {
        const x = (ms - startms) ;
        if (x > duration) {
          return cb(to);
        }
        cb(x / duration * (to - from) + from)
        requestAnimationFrame(frame);
      }
      requestAnimationFrame(ms => {
        startms = ms;
        requestAnimationFrame(frame);
      })
    }
    
    function rotate() {
      var svg = document.getElementById("svgID");
      if (svg.getAttribute("transform") === "rotate(45)") {
        anim(45, 0, v=> svg.setAttribute("transform", `rotate(${v})`));
      } else {
        anim(0, 45, v=> svg.setAttribute("transform", `rotate(${v})`));
      }
    }
    #button {
      margin: 0;
      padding: 0;
      background: none;
      outline: none;
      box-shadow: none;
      border: none;
    }
    <button id="button" onclick="rotate()">
            <svg id="svgID"
            width="100%"
            height="100%"
            viewBox="0 0 142.40739 142.40991"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            xmlns:svg="http://www.w3.org/2000/svg">
           <defs
              id="defs6" />
            <path
              id="rect234"
              style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-miterlimit:0;stroke-dasharray:none;paint-order:stroke fill markers"
              d="m 85.223081,28.929132 a 4.2333333,4.2333333 0 0 0 -4.233333,4.233333 v 62.801852 l -65.486442,-0.24339 a 4.107912,4.107912 0 0 0 -4.247803,3.96255 4.2333333,4.2333333 0 0 0 4.217313,4.249353 l 65.516932,0.24339 v 62.9295 a 4.107912,4.107912 0 0 0 3.978568,4.23333 4.2333333,4.2333333 0 0 0 4.233334,-4.23333 v -62.89901 l 60.21338,0.22376 a 4.107912,4.107912 0 0 0 4.2478,-3.96255 4.2333333,4.2333333 0 0 0 -4.21731,-4.248833 L 89.20165,95.994807 V 33.162465 a 4.107912,4.107912 0 0 0 -3.978569,-4.233333 z"
              transform="translate(-11.255471,-28.929132)" />
            </svg>
         </button>

    方法2: animate

    function anim(el, from, to, duration=100) {
      const animation = [
        { transform: `rotate(${from}deg)` },
        { transform: `rotate(${to}deg)` }
      ];
      const timing = {
        fill: 'both',
        duration,
        iterations: 1
      };
      el.animate(animation, timing);
    }
    
    function rotate() {
      var svg = document.getElementById("svgID");
      if (svg.dataset.rotated === "1") {
        svg.dataset.rotated = "0";
        anim(svg, 45, 0);
      } else {
        svg.dataset.rotated = "1";
        anim(svg, 0, 45);
      }
    }
    #按钮{
    边距:0;
    填充:0;
    背景:无;
    大纲:无;
    盒子阴影:无;
    边界:无;
    }
    <button id=“button”onclick=“rotate()”>
    <svg id=“svgID”
    宽度=“100%”
    高度=“100%”
    viewBox=“0 142.40739 142.40991”
    版本=“1.1”
    xmlns=“http://www.w3.org/2000/svg"
    xmlns:svg=“http://www.w3.org/2000/svg">
    <defs
    id=“defs6”/>
    <路径
    id=“rect234”
    style=“display:内联;不透明度:1;fill:#000000;fill不透明度:2;笔划:#000000;笔划宽度:0;笔划linecap:圆形;笔划miterlimit:0;笔划dasharray:无;绘制顺序:笔划填充标记”
    d=“m 85.223081,28.929132 a 4.233333,4.233333 0 0-4.233333,4.233333 v 62.801852 l-65.486442,-0.24339 a 4.107912 0 0-42.47803,3.96255 4.233333、4.233333 00 4.217313,4.249353 l 65.516932,0.24339 v 62.9295 a 4.107912,4.107912 0.3.978568,4.23333 4.23333,4.23333 0 0 4.233334,-4.233333 v-62.89901 l 60.21338,0.22376 a 4.107912,4.1 07912 0 0 4.2478,-3.96255 4.233333,4.233333 0 0-4.21731,-4.248833 l 89.20165,95.994807 v 33.162465 a 4.107912,4.107912 0-3.978569,-4.233333 z“
    transform=“翻译(-11.255471,-28.929132)”/>
    </svg>
    </按钮>
        2
  •  0
  •   NickSlash    2 年前

    需要 可以使用CSS属性 animate .

    以下显示了单向/一次性动画。(单击后不会返回或进一步设置动画)

    let svg = document.querySelector("#svg")
    svg.addEventListener("click", () => {
      if (!svg.classList.contains("animateSVG")) {
        svg.classList.add("animateSVG")
      }
    })
    #container {
        position: absolute;
        top: 0px;
        left: 0px;
        height: 100px;
        width: 100px;
        border: 1px solid black;
    }
    @keyframes frames {
        0% {
            transform: rotate(0deg);
        }
        100% {
            transform: rotate(45deg);
        }
    }
    
    .animateSVG {
        animation-name: frames;
        animation-duration: 1s;
        animation-fill-mode: forwards;
    }
    <div id="container">
        <svg id="svg" viewBox="0 0 3 3" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
            <path style="opacity: 0.468379; fill: none; stroke: #000000; stroke-width: 0.264583; stroke-linecap: round; stroke-linejoin: round;" d="M0.5,1.5h2zM1.5,0.5v2z" />
        </svg>
    </div>