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

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

新規登録して質問してみよう
ただいま回答率
85.48%
canvas

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

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

2404閲覧

canvasでボタンを押すと描画されるようにしたい

hectopascal1013

総合スコア466

canvas

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

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2019/11/11 18:49

お世話になります。
javascript canvasにて、それぞれのボタンを押すと、それぞれ別の図形が描画されるページを作りたく、以下のようなコードを書きました。
function で囲うと動作しなくなってしまいます。
(それぞれの動作をfunctionで囲う前は動作を確認しています。)

描画するx01などが定義されていないとエラーを吐きますが、
これはローカル関数、グローバル関数の関係なのでしょうか?
よろしくお願いいたします。

html,javascript

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="utf-8"> 5 <title>My Canvas</title> 6 7</head> 8<body> 9 <canvas width="1024" height="768"> 10 Canvas not supported. 11 </canvas> 12 13<script> 14 'use strict'; 15 16{ 17 let t=0; 18 19 function draw() { 20 const canvas = document.querySelector('canvas'); 21 if (typeof canvas.getContext === 'undefined') { 22 return; 23 } 24 const ctx = canvas.getContext('2d'); 25 26//解像度 27const CANVAS_WIDTH=1024; 28const CANVAS_HEIGHT=768; 29const dpr =window.devicePixelRatio || 1; 30canvas.width=CANVAS_WIDTH*dpr; 31canvas.height=CANVAS_HEIGHT*dpr; 32 33ctx.scale(dpr,dpr); 34canvas.style.width=CANVAS_WIDTH+'px'; 35canvas.style.height=CANVAS_HEIGHT+'px'; 36 37function rand(){ 38//triangle 39 var www=1024-768; 40 var x01=Math.random()*www; 41 var y01=Math.random()*www; 42 var x02=Math.random()*www; 43 var y02=Math.random()*www; 44 var x03=Math.random()*www; 45 var y03=Math.random()*www; 46 47 48} 49function tyo(){ 50//直角三角形 51 var x01=0; 52 var y01=0; 53 var x02=0+30; 54 var y02=0; 55 var x03=0+0; 56 var y03=0+40; 57 } 58function sei(){ 59//正三角形 60 var x01=200; 61 var y01=200; 62 var x02=200+100; 63 var y02=200; 64 var x03=200+50; 65 var y03=200-50*Math.pow(3,1/2); 66 } 67 68 ctx.beginPath(); 69 ctx.moveTo(x01, y01); 70 ctx.lineTo(x02, y02); 71 ctx.lineTo(x03, y03); 72 ctx.lineTo(x01, y01); 73 ctx.fillStyle='skyblue'; 74 ctx.stroke(); 75 } 76 77 draw(); 78} 79</script> 80 81 <input type="button" value="btn1" onclick="rand();"/> 82 <input type="button" value="btn2" onclick="tyo();"/> 83 <input type="button" value="btn3" onclick="sei();"/> 84 85</body> 86</html> 87コード

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

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

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

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

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

guest

回答1

0

ベストアンサー

canvasでボタンを押すと描画されるようにしたい

  1. draw() の外(input[onclick])から参照できない位置で関数が宣言されています。

rand(), tyo(), sei()
2. draw() 内で宣言されてない変数を参照しています。
x01,y01,...y03

次の骨格で書き換えてみてください。

javascript

1function draw(x01,y01, x02,y02, x03,y03) { 2 : 3}; 4function rand() { 5 : 6 draw(x01,y01, x02,y02, x03,y03); 7} 8function tyo() { 9 : 10 draw(x01,y01, x02,y02, x03,y03); 11} 12function sei(){ 13 : 14 draw(x01,y01, x02,y02, x03,y03); 15} 16

function で囲うと動作しなくなってしまいます。

ご質問の内容では無理に囲う必要はありません。動作しない理由は

  1. 関数を宣言しただけで実行していない
  2. 関数実行に必要な引数を与える記号 () を忘れている

x01などが定義されていないとエラー...

スコープ(変数や関数を参照できる範囲)の概念があります。
最初は、関数内で宣言された変数や関数は、宣言した関数内部でのみ参照でき、外部からは参照できないものと覚えましょう。

ローカル関数、グローバル関数の関係なのでしょうか

前述の通り外側、内側の考え方です
(用語の使い方は厳密じゃないですが、追々覚えましょう)。

投稿2019/11/12 01:45

AkitoshiManabe

総合スコア5432

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

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

hectopascal1013

2019/11/12 02:27

お返事ありがとうございます。 canvasは独特のようで、私なりにご指摘の書き方に直してみました。 できるだけ具体的なコードで、ご指摘いただけると大変助かります。 よろしくお願い申し上げます。 以下コードです。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>My Canvas</title> </head> <body> <canvas width="1024" height="256"> Canvas not supported. </canvas> <script> 'use strict'; { let t=0; function draw(x01,y01,x02,y02,x03,y03) { const canvas = document.querySelector('canvas'); if (typeof canvas.getContext === 'undefined') { return; } const ctx = canvas.getContext('2d'); //解像度 const CANVAS_WIDTH=1024; const CANVAS_HEIGHT=256; const dpr =window.devicePixelRatio || 1; canvas.width=CANVAS_WIDTH*dpr; canvas.height=CANVAS_HEIGHT*dpr; ctx.scale(dpr,dpr); canvas.style.width=CANVAS_WIDTH+'px'; canvas.style.height=CANVAS_HEIGHT+'px'; //function draw(x01,y01,x02,y02,x03,y03){ function rand(){ //triangle var www=1024-256; var x01=Math.random()*www; var y01=Math.random()*www; var x02=Math.random()*www; var y02=Math.random()*www; var x03=Math.random()*www; var y03=Math.random()*www; draw(x01,y01,x02,y02,x03,y03); } function tyo(){ //直角三角形 var x01=0; var y01=0; var x02=0+30; var y02=0; var x03=0+0; var y03=0+40; draw(x01,y01,x02,y02,x03,y03); } function sei(){ //正三角形 var x01=200; var y01=200; var x02=200+100; var y02=200; var x03=200+50; var y03=200-50*Math.pow(3,1/2); draw(x01,y01,x02,y02,x03,y03); } ctx.beginPath(); ctx.moveTo(x01, y01); ctx.lineTo(x02, y02); ctx.lineTo(x03, y03); ctx.lineTo(x01, y01); ctx.fillStyle='skyblue'; ctx.stroke(); } draw(); } </script> <input type="button" value="btn1" onclick="rand();"/> <input type="button" value="btn2" onclick="tyo();"/> <input type="button" value="btn3" onclick="sei();"/> </body> </html>
AkitoshiManabe

2019/11/12 02:51

まずインデント(桁)を揃えてコードを見直しましょう。外側、内側の関係がわかりやすくなります。次に rand(), tyo(), sei() を draw() 関数の外に書く。draw() は描画条件(3つの座標)は引数で受け取るので、解像度設定後、直ぐに描画すればいいですよ。 具体的にコードを示すと作業の丸投げになるので、そこはご自身で。
hectopascal1013

2019/11/12 03:16

drawの外に書けとのことですが、 functionを外した時の動作は確認していますので、外に書くとcanvasでは動作しない仕様になっております。 失礼ですが、動作確認されてから、ご回答いただいていますでしょうか? 具体的なご指摘なければ、解決にならないと思われますが。。。
hectopascal1013

2019/11/12 03:17

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>My Canvas</title> </head> <body> <canvas width="1024" height="256"> Canvas not supported. </canvas> <script> 'use strict'; { let t = 0; function draw(x01, y01, x02, y02, x03, y03) { const canvas = document.querySelector('canvas'); if (typeof canvas.getContext === 'undefined') { return; } const ctx = canvas.getContext('2d'); //解像度 const CANVAS_WIDTH = 1024; const CANVAS_HEIGHT = 256; const dpr = window.devicePixelRatio || 1; canvas.width = CANVAS_WIDTH * dpr; canvas.height = CANVAS_HEIGHT * dpr; ctx.scale(dpr, dpr); canvas.style.width = CANVAS_WIDTH + 'px'; canvas.style.height = CANVAS_HEIGHT + 'px'; //function draw(x01,y01,x02,y02,x03,y03){ } //function rand() { //triangle var www = 1024 - 256; var x01 = Math.random() * www; var y01 = Math.random() * www; var x02 = Math.random() * www; var y02 = Math.random() * www; var x03 = Math.random() * www; var y03 = Math.random() * www; draw(x01, y01, x02, y02, x03, y03); //} function tyo() { //直角三角形 var x01 = 0; var y01 = 0; var x02 = 0 + 30; var y02 = 0; var x03 = 0 + 0; var y03 = 0 + 40; draw(x01, y01, x02, y02, x03, y03); } function sei() { //正三角形 var x01 = 200; var y01 = 200; var x02 = 200 + 100; var y02 = 200; var x03 = 200 + 50; var y03 = 200 - 50 * Math.pow(3, 1 / 2); draw(x01, y01, x02, y02, x03, y03); } ctx.beginPath(); ctx.moveTo(x01, y01); ctx.lineTo(x02, y02); ctx.lineTo(x03, y03); ctx.lineTo(x01, y01); ctx.fillStyle = 'skyblue'; ctx.stroke(); draw(); } </script> <input type="button" value="btn1" onclick="rand();" /> <input type="button" value="btn2" onclick="tyo();" /> <input type="button" value="btn3" onclick="sei();" /> </body> </html> 動作しませんでした。
hectopascal1013

2019/11/12 03:18

具体的な改善案が示されず、求めている回答と違ってきています。
kei344

2019/11/12 03:24

'use strict';があるとその後のブロックスコープが生成されるのでonclickから参照できなくなりますよ。
hectopascal1013

2019/11/12 03:35

ありがとうございます。引き続きご回答よろしくお願いします。
AkitoshiManabe

2019/11/12 03:51

では、具体的なご指摘をさせていただきますね。 骨格通りに書き直してないんですよ。 { で始まり、 } で終わる部分は問題ないです。でも、終端付近に残された draw() は悪さをしてますね。 draw()関数の引数変更を回答させていただいたわけですから引数なしだとcanvas context の moveTo() や lineTo() メソッドでエラーになるはずです。この内容をもう一度確認してみてくださいね。 input[click] → rand(), tyo(), sei() のいずれか → draw() の順に関数が呼ばれ、処理するように回答させていただいてます。 この処理の流れを再確認してみてください。 試行用のファイルは簡単に複製できますので、ご不安でしたら必ずバックアップをとっておいてください。
AkitoshiManabe

2019/11/12 04:01

kei344 さん、助言ありがとうございます。 hectopascal さん、use strict は外してみてくださいね。
hectopascal1013

2019/11/12 04:41

ありがとうございます。 draw()関数の引数の有無については、両方試して見て、ダメでした。 その上で、動作確認していただいているか、質問させていただきました。 前後錯綜してしまい、 大変失礼しました。
AkitoshiManabe

2019/11/12 04:45

では、確認ですが、<script></script> には 回答差し上げた4つの関数だけになっているでしょうか?
hectopascal1013

2019/11/12 05:49

ありがとうございました。 こちらのjsと異なる点は >> // 引数に合わせて描画 の位置でした。 ご指摘いただいていたのに、気づけず、申し訳ございませんでした。
AkitoshiManabe

2019/11/12 07:56

こちらこそ、焦らせすぎてごめんなさい。Canvas は「楽しい機能」ですので堪能してくださいね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問