17454


Javascriptとsvgの勉強として以下のコードを作成してみました。  
1週間程かけてsvgの仕組み,JavascriptのaddEventListener,jQueryのイベント関連関数など色々試してみましたが一番スムーズに動いたソースを張り付けておきます。

以下のリンクで確認できます。

エラーは出ませんがマウスを動かさないと中央部分がランダムに動かない

[code]

    $(document).ready(function() {
      var d = document;
      var mysvg = d.getElementById("mysvg");
    
      var mx, my, random, xmid, ymid, input;
    
      setInterval(function() {
        //svgのサイズ
        var svgw = $("svg").width();
        var svgh = $("svg").height();
    
        //画面の中央
        xmid = svgw / 2;
        ymid = svgh / 2;
    
        //ランダムな数値
        random = {
          a: Math.floor(Math.random() * 25),
          b: Math.floor(Math.random() * 25),
          c: Math.floor(Math.random() * 25)
        };
    
        //ｓｖｇniにイベントを追加
        mysvg.addEventListener("mousemove", function(e) {
          //マウスの座標を取得
          mx = e.clientX;
          my = e.clientY;
    
          //svgにパスを追加
          input = '<path d="M ' + xmid + ',' + ymid + ' l ' + 0 + ',' + 0 + ' ' + ((mx - xmid) / 2) + ',' + random.a + ' ' + ((mx - xmid) - ((mx - xmid) / 2)) + ',' + ((my - ymid) - random.a) + ' ' + '" stroke="orange" stroke-width="7" stroke-linejoin="round" fill="none" />';
        });
    
        //使用出来るデータを表示
        $("#status1").html("X 座標 : " + mx + "<br>Y 座標: " + my + "<br><br>画面の中央 X: " + xmid + "<br><br>画面の中央 Y: " + ymid + "<br><br>画面の横幅: " + svgw + "<br>画面の縦幅: " + svgh + "<br><br>ランダム値 a: " + random.a + "<br>ランダム値 b: " + random.b + "<br>ランダム値 c: " + random.c);
    
        $("#mysvg").html(input);
      }, 10);
    });
[/code]

[code]

    html,
    body {
      width: 100%;
      height: 100%;
      padding: 0;
      margin: 0;
    }
    
    body {
      overflow: hidden;
    }
    
    #wrapper {
      width: 100%;
      min-height: 100%;
      margin: 0 auto;
      position: relative;
    }
    
    svg {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      margin: 0 auto;
      width: 100%;
      height: 100%;
      outline: 1px solid blue;
    }
[/code]

[code]

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <div id="wrapper">
      <p id="status1"></p>
      <svg id="mysvg" width="300" height="300"></svg>
    </div>
[/code]

[code]

    $(document).ready(function(){
        var d = document;
        var mysvg = d.getElementById("mysvg");
    
        var mx,my,random,xmid,ymid,input;
    
        setInterval(function() {
            //svgのサイズ
            var svgw = $("svg").width();
            var svgh = $("svg").height();
    
            //画面の中央
            xmid = svgw/2;
            ymid = svgh/2;
    
            //ランダムな数値
            random = {
                a: Math.floor(Math.random()*25),
                b: Math.floor(Math.random()*25),
                c: Math.floor(Math.random()*25)
            };
    
            //svgにイベントを追加
            mysvg.addEventListener("mousemove", function(e) {
                //マウスの座標を取得
                mx = e.clientX;
                my = e.clientY;
    
                //svgにパスを追加
                input = '<path d="M ' + xmid + ',' + ymid + ' l ' + 0 + ',' + 0 + ' ' + ((mx-xmid)/2) + ',' + random.a + ' ' + ((mx-xmid)-((mx-xmid)/2)) + ',' + ((my-ymid)-random.a) + ' ' + '" stroke="orange" stroke-width="7" stroke-linejoin="round" fill="none" />';
            });
    
            //使用出来るデータを表示
            $("#status1").html("X 座標 : " + mx + "<br>Y 座標: " + my + "<br><br>画面の中央 X: " + xmid + "<br><br>画面の中央 Y: " + ymid + "<br><br>画面の横幅: " + svgw + "<br>画面の縦幅: " + svgh + "<br><br>ランダム値 a: " + random.a + "<br>ランダム値 b: " + random.b + "<br>ランダム値 c: " + random.c);
    
            $("#mysvg").html(input);
        }, 10);
    
[/code]

やりたいことはマウスの動きに合わせてSVGの "path" を使用して蛇のようなアニメーションを再現したい。  
※Canvasも試してみましたがsvgの方が自由度が高いのでSVGを使用しました。

**問題**  
・マウスを動かさないとランダム値が変化されない  
※ランダム値が動かない理由は "mousemove" イベントが発生していないと "ランダム値" も変化されないというのは理解しております。

・"input =" の部分を addEventListener関数の外に出すこともできますがその場合マウスの座標が取得できない。  
※ブラウザの開発者モードの "Console" タブに行き "" の値を確認すると マウスの座標の部分が "NaN" になる。  
※一番下にリンクを張っておきます。

・マウスを止めた場合 "path" の中央の値が1秒ごとに動いている理由？

**最終的にやりたいこと**  
・pathに2，3点ほどランダムに値が変化する変数を追加してマウスを動かしていても止めている状態でもランダムに変化させたい

やりたいこととしてはこちらの方が望ましいですが開発者ツールのconsoleメッセージでエラーが出る

[code]

    $(document).ready(function() {
      var d = document;
      var mysvg = d.getElementById("mysvg");
    
      var mx, my, random, xmid, ymid, input;
    
      setInterval(function() {
        //svgのサイズ
        var svgw = $("svg").width();
        var svgh = $("svg").height();
    
        //画面の中央
        xmid = svgw / 2;
        ymid = svgh / 2;
    
        //ランダムな数値
        random = {
          a: Math.floor(Math.random() * 25),
          b: Math.floor(Math.random() * 25),
          c: Math.floor(Math.random() * 25)
        };
    
        //ｓｖｇniにイベントを追加
        mysvg.addEventListener("mousemove", function(e) {
          //マウスの座標を取得
          mx = e.clientX;
          my = e.clientY;
        });
    
        //svgにパスを追加
        input = '<path d="M ' + xmid + ',' + ymid + ' l ' + 0 + ',' + 0 + ' ' + ((mx - xmid) / 2) + ',' + random.a + ' ' + ((mx - xmid) - ((mx - xmid) / 2)) + ',' + ((my - ymid) - random.a) + ' ' + '" stroke="orange" stroke-width="7" stroke-linejoin="round" fill="none" />';
    
        //使用出来るデータを表示
        $("#status1").html("X 座標 : " + mx + "<br>Y 座標: " + my + "<br><br>画面の中央 X: " + xmid + "<br><br>画面の中央 Y: " + ymid + "<br><br>画面の横幅: " + svgw + "<br>画面の縦幅: " + svgh + "<br><br>ランダム値 a: " + random.a + "<br>ランダム値 b: " + random.b + "<br>ランダム値 c: " + random.c);
    
        $("#mysvg").html(input);
      }, 10);
    });
[/code]

[code]

    html,
    body {
      width: 100%;
      height: 100%;
      padding: 0;
      margin: 0;
    }
    
    body {
      overflow: hidden;
    }
    
    #wrapper {
      width: 100%;
      min-height: 100%;
      margin: 0 auto;
      position: relative;
    }
    
    svg {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      margin: 0 auto;
      width: 100%;
      height: 100%;
      outline: 1px solid blue;
    }
[/code]

[code]

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <div id="wrapper">
      <p id="status1"></p>
      <svg id="mysvg" width="300" height="300"></svg>
    </div>
[/code]

↑のようなやり方でも動くようですが "NaN" エラーが出ているのでやり方がおかしいのかもしれません。

Javascriptの経験はまだ浅い方なのでもっといい方法があるのかもしれません。  
宜しくお願い致します。


CC BY-SA 4.0
2015-10-07T07:35:12.940
17348
2019-12-13T17:53:10.453
2019-12-13T17:52:31.383
32986
12625
question
javascript jquery svg
SVG 要素をJavascriptのmousemoveイベントとsetIntervalとの組み合わせ


ざっくりですが修正してみました。  
<http://jsfiddle.net/kamem/x2c5gvb2/2/>

[code]

    $(document).ready(function() {
      var svg = document.getElementById("svg");
      var $stg = $("#mysvg");
    
      var mx, my, input;
      //svgのサイズ
      var svgWidth = $stg.width();
      var svgHeight = $stg.height();
    
      //画面の中央
      var xmid = svgWidth / 2;
      var ymid = svgHeight / 2;
      var random = [];
      var randomNum = 20;
    
      setInterval(function() {
        //ランダムな数値
        random = [{
            x: Math.floor(Math.random() * randomNum),
            y: Math.floor(Math.random() * randomNum)
          },
          {
            x: Math.floor(Math.random() * randomNum),
            y: Math.floor(Math.random() * randomNum)
          },
          {
            x: Math.floor(Math.random() * randomNum),
            y: Math.floor(Math.random() * randomNum)
          },
        ];
    
        //使用出来るデータを表示
        $("#status1").html("X 座標 : " + mx + "<br>Y 座標: " + my + "<br><br>画面の中央 X: " + xmid + "<br><br>画面の中央 Y: " + ymid + "<br><br>画面の横幅: " + svgWidth + "<br>画面の縦幅: " + svgHeight + "<br><br>ランダム値 a: " + random[0] + "<br>ランダム値 b: " + random[1] + "<br>ランダム値 c: " + random[2]);
    
        createPath();
      }, 10);
    
      //ｓｖｇniにイベントを追加
      mysvg.addEventListener("mousemove", function(e) {
        //マウスの座標を取得
        mx = e.clientX;
        my = e.clientY;
        createPath();
      });
    
      function createPath() {
        var height = my - ymid;
        var width = mx - xmid;
        var point1 = (xmid + width / 4 + random[0].x) + ' ' + (ymid + height / 4 + random[0].y);
        var point2 = (xmid + width / 3 + random[1].x) + ' ' + (ymid + height / 3 + random[1].y);
        var point3 = (xmid + width / 1.5 + random[2].x) + ' ' + (ymid + height / 1.5 + random[2].y);
        input =
          '<path d="M ' + xmid + ' ' + ymid + ',' +
          ' L ' + point1 +
          ' L ' + point2 +
          ' L ' + point3 +
          ' L ' + mx + ' ' + my +
          '" stroke="orange" stroke-width="7" stroke-linejoin="round" fill="none" />';
        $stg.html(input);
      }
    });
[/code]

[code]

    html,
    body {
      width: 100%;
      height: 100%;
      padding: 0;
      margin: 0;
    }
    
    body {
      overflow: hidden;
    }
    
    #wrapper {
      width: 100%;
      min-height: 100%;
      margin: 0 auto;
      position: relative;
    }
    
    svg {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      margin: 0 auto;
      width: 100%;
      height: 100%;
      outline: 1px solid blue;
    }
[/code]

[code]

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
    <div id="wrapper">
      <p id="status1"></p>
      <svg id="mysvg" width="300" height="300"></svg>
    </div>
[/code]

## やったこと

### setIntervalで毎回実行する必要が無い記述はわける。

毎回実行する必要があるのは下記項目なので、それ以外の記述はそとに移しました。

  1. randomの数字を撮り直す
  2. 情報の取得・描画
  3. svgのパスを生成し直す

### パスを作る処理を関数化

マウスを移動した時の処理と  
setIntervalの場合にパスを生成する処理を  
共通しそれぞれで実行するように修正しました。（`createPath`）

あとは見ていただければなんとくわかるのではないかと思います。  
Pathの生成部分などいまベタで描いてしまっているのですが  
for文で描いたほうが応用が効きそうかなとは思いました。


CC BY-SA 4.0
2015-10-09T02:37:23.463
17454
2019-12-13T17:53:10.453
2019-12-13T17:53:10.453
32986
7455
17348
answer