🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

HTML5

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

JavaScript

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

Q&A

解決済

1回答

483閲覧

値が違う同じ命令をまとめる方法を教えていただきたいです。

momomomon

総合スコア13

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

HTML5

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

JavaScript

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

0グッド

0クリップ

投稿2021/01/02 10:04

色とスタート地点の違う円がcanvas内を跳ね返りながら移動するコードを書きました。しかし同じような命令が重複してしまっていて見にくく、関数などでまとめようと試行錯誤しましたが正常に作動せず困っています。まとめる前のコードは以下です(こちらのコードは正常に作動しました)。

HTML

1<!DOCTYPE html> 2<html><head> 3<meta charset="utf-8"> 4<title></title> 5<style> 6#canvas { 7 background-color: #000000; 8 border: 1px solid #999999; 9} 10</style> 11<script> 12var spdx=2.0; //横(x軸)方向への円の移動速度 13var spdy=2.0; //縦(y軸)方向への円の移動速度 14var spdx2=2.0; //横(x軸)方向への円の移動速度 15var spdy2=2.0; //縦(y軸)方向への円の移動速度 16var spdx3=2.0; //横(x軸)方向への円の移動速度 17var spdy3=2.0; //縦(y軸)方向への円の移動速度 18var spdx4=2.0; //横(x軸)方向への円の移動速度 19var spdy4=2.0; //縦(y軸)方向への円の移動速度 20var spdx5=2.0; //横(x軸)方向への円の移動速度 21var spdy5=2.0; //縦(y軸)方向への円の移動速度 22var coox=200; //円中心のx座標 23var cooy=200; //円中心のy座標 24var coox2=380; //円2中心のx座標 25var cooy2=450; //円2中心のy座標 26var coox3=5; //円3中心のx座標 27var cooy3=120; //円3中心のy座標 28var coox4=25; //円4中心のx座標 29var cooy4=360; //円4中心のy座標 30var coox5=300; //円5中心のx座標 31var cooy5=20; //円5中心のy座標 32 33var canvas, context, context2, context3, context4, context5; 34 35function init() { 36 //canvasを使えるかどうか判定 37 canvas=document.getElementById("canvas"); 38 context=canvas.getContext("2d"); 39 context2=canvas.getContext("2d"); 40 context3=canvas.getContext("2d"); 41 context4=canvas.getContext("2d"); 42 context5=canvas.getContext("2d"); 43 44 if (!context) return; 45 46 //30ミリ秒ごとにdrawing()を実行するようにタイマーを設定 47 setInterval(drawing,30); 48} 49 50function drawing() { 51 //Canvasを塗りつぶす 52 context.globalCompositeOperation="source-over"; 53 context.fillStyle="rgba(0,0,0,0.2)"; 54 context.fillRect(0,0,canvas.width,canvas.height); 55 context.globalCompositeOperation="lighter"; 56 57 //円の中心位置を更新 58 coox=coox+spdx; 59 cooy=cooy+spdy; 60 coox2=coox2+spdx2; 61 cooy2=cooy2+spdy2; 62 coox3=coox3+spdx3; 63 cooy3=cooy3+spdy3; 64 coox4=coox4+spdx4; 65 cooy4=cooy4+spdy4; 66 coox5=coox5+spdx5; 67 cooy5=cooy5+spdy5; 68 69 //左右(横方向)の移動方向を反転 70 if (coox<0 || canvas.width<coox) { 71 spdx=spdx*(-1); 72 } 73 if (coox2<0 || canvas.width<coox2) { 74 spdx2=spdx2*(-1); 75 } 76 if (coox3<0 || canvas.width<coox3) { 77 spdx3=spdx3*(-1); 78 } 79 if (coox4<0 || canvas.width<coox4) { 80 spdx4=spdx4*(-1); 81 } 82 if (coox5<0 || canvas.width<coox5) { 83 spdx5=spdx5*(-1); 84 } 85 86 //上下(縦方向)の移動方向を反転 87 if (cooy<0 || canvas.height<cooy) { 88 spdy=spdy*(-1); 89 } 90 if (cooy2<0 || canvas.height<cooy2) { 91 spdy2=spdy2*(-1); 92 } 93 if (cooy3<0 || canvas.height<cooy3) { 94 spdy3=spdy3*(-1); 95 } 96 if (cooy4<0 || canvas.height<cooy4) { 97 spdy4=spdy4*(-1); 98 } 99 if (cooy5<0 || canvas.height<cooy5) { 100 spdy5=spdy5*(-1); 101 } 102 103 104 //更新後の位置に円を描画 105 context.beginPath(); 106 context.fillStyle="#ff0066"; 107 context.arc(coox,cooy,3,0,Math.PI*2.0,true); 108 context.fill(); 109 110 context2.beginPath(); 111 context2.fillStyle="red"; 112 context2.arc(coox2,cooy2,3,0,Math.PI*2.0,true); 113 context2.fill(); 114 115 context3.beginPath(); 116 context3.fillStyle="blue"; 117 context3.arc(coox3,cooy3,3,0,Math.PI*2.0,true); 118 context3.fill(); 119 120 context4.beginPath(); 121 context4.fillStyle="green"; 122 context4.arc(coox4,cooy4,3,0,Math.PI*2.0,true); 123 context4.fill(); 124 125 context5.beginPath(); 126 context5.fillStyle="white"; 127 context5.arc(coox5,cooy5,3,0,Math.PI*2.0,true); 128 context5.fill(); 129} 130</script> 131</head> 132<body onload="init()"> 133<canvas id="canvas" width="640" height="480"> 134</body> 135</html>

この場合、どのようにまとめるのが最善なのでしょうか?またはまとめる必要はないのでしょうか?初心者なのでコードや詳しい解説を添えていただけたら非常に嬉しいです。よろしくお願い致します。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

  1. 複数の配列を使ってまとめる方法

spdx, spdy, coox, cooy と、fillStyle に指定する color を配列にしてみました。
また、context は分ける必要がないのでひとつにまとめました。

js

1var spdx = [2.0, 2.0, 2.0, 2.0, 2.0]; 2var spdy = [2.0, 2.0, 2.0, 2.0, 2.0]; 3var coox = [200, 380, 5, 25, 300]; 4var cooy = [200, 450, 120, 360, 20]; 5var color = ["#ff0066", "red", "blue", "green", "white"]; 6 7var canvas, context; 8 9function init() { 10 //canvasを使えるかどうか判定 11 canvas = document.getElementById("canvas"); 12 context = canvas.getContext("2d"); 13 14 if (!context) return; 15 16 //30ミリ秒ごとにdrawing()を実行するようにタイマーを設定 17 setInterval(drawing, 30); 18} 19 20function drawing() { 21 //Canvasを塗りつぶす 22 context.globalCompositeOperation = "source-over"; 23 context.fillStyle = "rgba(0,0,0,0.2)"; 24 context.fillRect(0, 0, canvas.width, canvas.height); 25 context.globalCompositeOperation = "lighter"; 26 27 for (var i = 0; i < coox.length; i++) { 28 //円の中心位置を更新 29 coox[i] += spdx[i]; 30 cooy[i] += spdy[i]; 31 32 //左右(横方向)の移動方向を反転 33 if (coox[i] < 0 || canvas.width < coox[i]) { 34 spdx[i] = - spdx[i]; 35 } 36 37 //上下(縦方向)の移動方向を反転 38 if (cooy[i] < 0 || canvas.height < cooy[i]) { 39 spdy[i] = - spdy[i]; 40 } 41 42 //更新後の位置に円を描画 43 context.beginPath(); 44 context.fillStyle = color[i]; 45 context.arc(coox[i], cooy[i], 3, 0, Math.PI * 2.0, true); 46 context.fill(); 47 } 48}

  1. オブジェクトの配列を作る方法

配列を 5 つ作る代わりに、5 つの情報をひとつにまとめたオブジェクトを考えて、その配列を作ります。

js

1var circles = [ 2 { x: 200, y: 200, spdx: 2.0, spdy: 2.0, color: "#ff0066" }, 3 { x: 380, y: 450, spdx: 2.0, spdy: 2.0, color: "red" }, 4 { x: 5, y: 120, spdx: 2.0, spdy: 2.0, color: "blue" }, 5 { x: 25, y: 360, spdx: 2.0, spdy: 2.0, color: "green" }, 6 { x: 360, y: 20, spdx: 2.0, spdy: 2.0, color: "white" }, 7]; 8 9var canvas, context; 10 11function init() { 12 //canvasを使えるかどうか判定 13 canvas = document.getElementById("canvas"); 14 context = canvas.getContext("2d"); 15 16 if (!context) return; 17 18 //30ミリ秒ごとにdrawing()を実行するようにタイマーを設定 19 setInterval(drawing, 30); 20} 21 22function drawing() { 23 //Canvasを塗りつぶす 24 context.globalCompositeOperation = "source-over"; 25 context.fillStyle = "rgba(0,0,0,0.2)"; 26 context.fillRect(0, 0, canvas.width, canvas.height); 27 context.globalCompositeOperation = "lighter"; 28 29 for (var i = 0; i < circles.length; i++) { 30 var circle = circles[i]; 31 32 //円の中心位置を更新 33 circle.x += circle.spdx; 34 circle.y += circle.spdy; 35 36 //左右(横方向)の移動方向を反転 37 if (circle.x < 0 || canvas.width < circle.x) { 38 circle.spdx = - circle.spdx; 39 } 40 41 //上下(縦方向)の移動方向を反転 42 if (circle.y < 0 || canvas.height < circle.y) { 43 circle.spdy = - circle.spdy; 44 } 45 46 //更新後の位置に円を描画 47 context.beginPath(); 48 context.fillStyle = circle.color; 49 context.arc(circle.x, circle.y, 3, 0, Math.PI * 2.0, true); 50 context.fill(); 51 } 52}

  1. オブジェクトの数を増やす

オブジェクトにすると何がいいかと言うと、簡単に数を増やせることです。
例えば、ランダムに 100 個表示してみましょう。

js

1var circles = Array(100); 2var canvas, context; 3 4function init() { 5 //canvasを使えるかどうか判定 6 canvas = document.getElementById("canvas"); 7 context = canvas.getContext("2d"); 8 9 if (!context) return; 10 11 // ランダムな位置と色のオブジェクトを 100 個作る。 12 for (var i = 0; i < circles.length; i++) { 13 var r = Math.floor(Math.random() * 256); 14 var g = Math.floor(Math.random() * 256); 15 var b = Math.floor(Math.random() * 256); 16 circles[i] = { 17 x: Math.floor(Math.random() * canvas.width), 18 y: Math.floor(Math.random() * canvas.height), 19 spdx: 2.0, 20 spdy: 2.0, 21 color: `rgb(${r}, ${g}, ${b})` 22 }; 23 } 24 25 //30ミリ秒ごとにdrawing()を実行するようにタイマーを設定 26 setInterval(drawing, 30); 27} 28 29// function drawing() は 2 と同じなので、省略。

投稿2021/01/02 11:25

hoshi-takanori

総合スコア7899

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

momomomon

2021/01/09 07:24

ありがとうございます!今回は1番の方法で実行しました。本当に分かりやすくて勉強になりました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問