質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • JavaScript

    20334questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML5

    5103questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

【canvas要素】2Dグラフをゆっくり表示したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 616

himejiy3

score 67

下記はリサジュー曲線を描くプログラムで、一応、表示してくれるものを書けたのですが

自分の理想としては、angle(角度)360でパッと表示されるのではなく、
0.5度設定刻みでダラ~というかビロ~ンというか、
ラインが描画されていく様子を楽しみたいのです。

そこでsetTimeoutかなと思い、いろいろ試したのですが
どうしても上手く動いてくれませんでした。

どのように改造すれば良いでしょうか。
ご教授よろしくお願いいたします。

(余談ですが
やっぱり「a=2,b=5」または「a=3,b=8」が面白いと思います。)

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Lissajous curve</title>
</head>
<body>
  値a<input id="data1" type="number">
  値b<input id="data2" type="number">
  <input id="drawBtn" type="button" value="描画する"><br>
  <canvas id="xyPlane" width="640" height="580"></canvas>
  <script src="js/main1.js"></script>
</body>
</html>
document.addEventListener("DOMContentLoaded", () => {
  "use strict";

  let graph;
  const xWidth = 640;
  const xHalf = xWidth / 2;
  const yHeight = 580;
  const yHalf = yHeight / 2;

  function axis2d() {
    graph.strokeStyle = "black";
    graph.beginPath();
    graph.moveTo(0, yHalf);
    graph.lineTo(xWidth, yHalf);
    graph.moveTo(xHalf, 0);
    graph.lineTo(xHalf, yHeight);
    graph.stroke();
  }
  function draw() {
    let angle = 0;
    const a = document.getElementById("data1").value;
    const b = document.getElementById("data2").value;
    graph.beginPath();
    while (angle <= 360) {
      const x = 150 * Math.sin(a * angle * Math.PI / 180);
      const y = 150 * Math.sin(b * angle * Math.PI / 180);
      if (angle === 0) {
        graph.moveTo(xHalf + x, yHalf - y);
      } else {
        graph.lineTo(xHalf + x, yHalf - y);
      }
      graph.strokeStyle = "blue";
      graph.stroke();
      angle += 0.5;
    }
  }

  const xyPlane = document.getElementById("xyPlane");
  if (xyPlane.getContext) {
    graph = xyPlane.getContext("2d");
    axis2d();
  }

  const drawBtn = document.getElementById("drawBtn");
  drawBtn.addEventListener("click", draw);

});

(追記)2017-09-04-0:08
分かり難い質問になってしまい、すみません。追記します。

以下の部分で、
angle0.5度でいったん表示、angle1度でまた表示、1.5度で表示、2度で表示・・・
と繰り返せばラインが伸びていく様子が描画されるかな、と思っています。

while (angle <= 360) {
  const x = 150 * Math.sin(a * angle * Math.PI / 180);
  const y = 150 * Math.sin(b * angle * Math.PI / 180);
  if (angle === 0) {
    graph.moveTo(xHalf + x, yHalf - y);
  } else {
    graph.lineTo(xHalf + x, yHalf - y);
  }
  graph.strokeStyle = "blue";
  graph.stroke();
  angle += 0.5;
}


イメージとしては下から3行目を
setTimeout(graph.stroke(), 300); とか  setInterval(graph.stroke(), 300);
のようにする感じです。
(あくまでイメージです。これでは動きません。)

それをangle360度まで繰り返せば、
じわじわ伸びるラインが表示されるのではないかと。

もしくは、
while (angle <= 360) {
の360の部分を100にしたり180にしたりすると途中経過が表示されることは分かっているので、ここが引数で渡される関数を作る方法にもチャレンジしましたがダメでした。

いずれにせよ処理を遅延させるメソッドの理解が乏しいようで、
ネット検索で出てくる例文は理解出来たつもりでも、それを真似して組み込むと失敗します。
変更前同様、グラフが一瞬で表示されてしまうか、まったく表示されなくなってしまうか。

この作業中、ESLintには
Don't make functions within a loop. (no-loop-func)
(ループ内で関数を作成しないでください)
と、よく怒られているところです。

グラフの『完成図形』が目的ではなく、
グラフのドットが伸びていく『過程』を見られるようにしたいです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2017/09/03 22:59

    ご自身で試されたコードを質問文に追記し、「何」が「どのように」わからないのか、コードのどの部分で詰まっているのかなどを具体的に追記されたほうが回答が望めると思います。

    キャンセル

回答 1

checkベストアンサー

+2

とりあえず while を関数化してしまえば setTimeout しやすいと思いますよ。

draw_angle( 0 );
function draw_angle( angle ) {
    const x = 150 * Math.sin(a * angle * Math.PI / 180);
    const y = 150 * Math.sin(b * angle * Math.PI / 180);
    if (angle === 0) {
        graph.moveTo(xHalf + x, yHalf - y);
    } else {
        graph.lineTo(xHalf + x, yHalf - y);
    }
    graph.strokeStyle = "blue";
    graph.stroke();
    angle += 0.5;
    if (angle <= 360) {
        setTimeout( function() { draw_angle( angle ); }, 300 );
    }
}

【Canvasアニメーションの要点 - Qiita】
http://qiita.com/nekoneko-wanwan/items/33afa5d20264c83b2bd1

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/09/04 11:42

    なるほど・・・これで動くものだったのですね。

    自分はwhileの部分を関数化しようとしたとき、
    drawの外に出しておこうとして、動かなくて諦めました。
    今考えると、変数の引き渡しが出来ていなかっただけのような気がします。
    あまりにも失敗が続き、いろいろと勘違いも重なっていたようです。

    紹介リンクも読んで、勉強しておきます。
    ありがとうございました。

    キャンセル

同じタグがついた質問を見る

  • JavaScript

    20334questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML5

    5103questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。