📝

SVGでマウス位置に要素を書く

2021/04/18に公開

あらかじめ要素を用意しておき、それを移動する場合

最初は cx, cy に直接値を代入しようとしていたがうまくいかず、検証ツールで確認すると baseVal.value という変数に値を保持していることがわかった。
そこに代入してしまえば、マウス位置に追従して要素が描けた。

インターフェースが直接的ではないことから、あまりいいやり方ではない気がする。

<html>
  <body>
    <svg id="canvas" width="600px" height="600px" viewbox="0 0 600 600">
    <circle id="cursor" cx="-99999" cy="-99999" r="10" stroke="red" fill="transparent" stroke-width="1" />
    </svg>
    <script>
      let svg = document.getElementById("canvas");
      let cursor =document.getElementById("cursor");
 
      svg.addEventListener("mousemove", eve => {
        cursor.cx.baseVal.value = eve.clientX - 0.5 * cursor.r.baseVal.value;
        cursor.cy.baseVal.value = eve.clientY - 0.5 * cursor.r.baseVal.value;
      });
    </script>
  </body>
</html>

要素を動的に生成する場合

以下が参考になった。
https://stackoverflow.com/questions/20539196/creating-svg-elements-dynamically-with-javascript-inside-html

<html>
  <body>
    <svg id="canvas" width="600px" height="600px" viewbox="0 0 600 600">
      <!--
      <circle id="cursor" cx="-99999" cy="-99999" r="10" stroke="red" fill="transparent" stroke-width="1" />
      -->
    </svg>
    <script>
      let svg = document.getElementById("canvas");
      let cursor =document.getElementById("cursor");
      let svgNS = svg.namespaceURI;

      svg.addEventListener("mousemove", eve => {
        let circle = document.getElementById('cursor');
        if( circle == null ) {
          circle = document.createElementNS(svgNS, 'circle');
          circle.setAttribute( "id", "cursor" );
          circle.setAttribute( "r", 10 ); 
          circle.setAttribute( "stroke", "red" );
          circle.setAttribute( "fill", "transparent" );
          circle.setAttribute( "stroke-width", 2 );
          svg.appendChild( circle );
        }
        let r = circle.getAttribute( "r" );
        circle.setAttribute( "cx", eve.clientX - 0.5 * r );
        circle.setAttribute( "cy", eve.clientY - 0.5 * r );
      });
    </script>
  </body>
</html>

Discussion