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

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

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

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

JavaScript

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

Q&A

解決済

1回答

851閲覧

Javascriptとcanvasを使ってドラッグ&ドロップでアイコンを指定範囲内で自由に動かせるようにしたい

mamakokoko

総合スコア1

canvas

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

JavaScript

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

0グッド

1クリップ

投稿2022/06/20 11:11

Javascriptとcanvasを使ってドラッグ&ドロップで複数のアイコンを別々に指定範囲内で動かせるようなものを作成したいです。

下記のサイトを参考にして四角形をドラッグ&ドロップで動かせるようにしました。
https://itecnote.com/tecnote/javascript-drag-and-drop-multiple-objects-in-html5-canvas/

サッカーのフォーメーションを自分で作るような仕様にしたいです。
下の画像のように四角形は並べて、自由にドラッグ&ドロップで動かせるようにしたのですが、この四角形をアイコン画像に置き換えたいです。
イメージ説明

コードを書いてみたのですが、思ったように動かず、エラーが出ています

Javascript

1 2window.onload=function(){ 3const path = require('path'); 4console.log(path); 5const board = document.getElementById("board"); 6const ctx=board.getContext("2d"); 7const chara = new Image(); 8chara.src="/images/uni.jpg"; 9chara.onload = ()=>{ 10 ctx.drawImage(chara,0,0,100,100) 11 12var BB=board.getBoundingClientRect(); 13var offsetX=BB.left; 14var offsetY=BB.top; 15var WIDTH = board.width; 16var HEIGHT = board.height; 17var dragok = false; 18var startX; 19var startY; 20 21canvas.onmousedown = myDown; 22canvas.onmouseup = myUp; 23canvas.onmousemove = myMove; 24 25function clear() { 26ctx.clearRect(0, 0, WIDTH, HEIGHT); 27} 28 29function draw() { 30clear(); 31ctx.fillStyle = "#FAF7F8"; 32chara(0,0,WIDTH,HEIGHT); 33// redraw each rects in the rects[] array 34for(var i=0;i<charas.length;i++){ 35 var r=charas[i]; 36 ctx.fillStyle=r.fill; 37 chara(r.x,r.y,r.width,r.height); 38 console.log("い"); 39} 40} 41}; 42function myDown(e){ 43 44 45e.preventDefault(); 46e.stopPropagation(); 47 48var mx=parseInt(e.clientX-offsetX); 49var my=parseInt(e.clientY-offsetY); 50 51dragok=false; 52for(var i=0;i<charas.length;i++){ 53 var r=charas[i]; 54 if(mx>r.x && mx<r.x+r.width && my>r.y && my<r.y+r.height){ 55 56 dragok=true; 57 r.isDragging=true; 58 } 59} 60startX=mx; 61startY=my; 62} 63 64function myUp(e){ 65 66e.preventDefault(); 67e.stopPropagation(); 68 69dragok = false; 70for(var i=0;i<charas.length;i++){ 71 charas[i].isDragging=false; 72} 73} 74 75function myMove(e){ 76if (dragok){ 77 78 e.preventDefault(); 79 e.stopPropagation(); 80 81 var mx=parseInt(e.clientX-offsetX); 82 var my=parseInt(e.clientY-offsetY); 83 84 var dx=mx-startX; 85 var dy=my-startY; 86 87 for(var i=0;i<charas.length;i++){ 88 var r=charas[i]; 89 if(r.isDragging){ 90 r.x+=dx; 91 r.y+=dy; 92 } 93 } 94 95 draw(); 96 97 startX=mx; 98 startY=my; 99 100} 101} 102};

エラー内容は以下です。
uncaught ReferenceError: charas is not defined at HTMLCanvasElement.myUp(new.js:170:1)

Uncaught ReferenceError: dragok is not defined at HTMLCanvasElement.myMove (new.js:176:1)

現在はWebページにアイコン画像が一つだけ映っており、アイコンを動かそうとすると上記のエラーが出ます。

Javascriptを触り始めてから間もないため、解決方法に辿り着くまでの検索の仕方などもわかっておりません。

こちらに記載したコードのおかしな点がありましたらご教示いただけると幸いです。

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

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

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

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

  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。

guest

回答1

1

ベストアンサー

uncaught ReferenceError: charas is not defined at HTMLCanvasElement.myUp(new.js:170:1)

charas という変数が宣言されていません。質問文のコードには本当に charas という変数は宣言されていないので、どう直すのがよいのかは助言できません。

Uncaught ReferenceError: dragok is not defined at HTMLCanvasElement.myMove (new.js:176:1)

dragokchara.onload に指定された関数の中で宣言されているので、その関数の外では利用できません。宣言をトップレベルに移動するか、dragok を利用したい関数を chara.onload の中に移動するか、です。
ソースコードのインデントをきちんとした方がこういうバグは少なくなります。

投稿2022/06/20 23:30

int32_t

総合スコア19665

mamakokoko👍を押しています

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

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

このような回答には修正を依頼しましょう。

また依頼した内容が修正された場合は、修正依頼を取り消すようにしましょう。

回答へのコメント

mamakokoko

2022/06/21 11:21

ありがとうございます。とても参考になり、理解が一歩進みました。 個人的には参考にしたサイトの四角形を画像にするだけなので、四角形を表す式を変更していけばできると考えていました。 下記のコードのrectとrectsのところを画像用のコードに置き換えていけばできるんでしょうか? <script> window.onload=function(){ // get canvas related references var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var BB=canvas.getBoundingClientRect(); var offsetX=BB.left; var offsetY=BB.top; var WIDTH = canvas.width; var HEIGHT = canvas.height; // drag related variables var dragok = false; var startX; var startY; // an array of objects that define different rectangles var rects=[]; rects.push({x:75-15,y:50-15,width:30,height:30,fill:"#444444",isDragging:false}); rects.push({x:75-25,y:50-25,width:30,height:30,fill:"#ff550d",isDragging:false}); rects.push({x:75-35,y:50-35,width:30,height:30,fill:"#800080",isDragging:false}); rects.push({x:75-45,y:50-45,width:30,height:30,fill:"#0c64e8",isDragging:false}); // listen for mouse events canvas.onmousedown = myDown; canvas.onmouseup = myUp; canvas.onmousemove = myMove; // call to draw the scene draw(); // draw a single rect function rect(x,y,w,h) { ctx.beginPath(); ctx.rect(x,y,w,h); ctx.closePath(); ctx.fill(); } // clear the canvas function clear() { ctx.clearRect(0, 0, WIDTH, HEIGHT); } // redraw the scene function draw() { clear(); ctx.fillStyle = "#FAF7F8"; rect(0,0,WIDTH,HEIGHT); // redraw each rect in the rects[] array for(var i=0;i<rects.length;i++){ var r=rects[i]; ctx.fillStyle=r.fill; rect(r.x,r.y,r.width,r.height); } } // handle mousedown events function myDown(e){ // tell the browser we're handling this mouse event e.preventDefault(); e.stopPropagation(); // get the current mouse position var mx=parseInt(e.clientX-offsetX); var my=parseInt(e.clientY-offsetY); // test each rect to see if mouse is inside dragok=false; for(var i=0;i<rects.length;i++){ var r=rects[i]; if(mx>r.x && mx<r.x+r.width && my>r.y && my<r.y+r.height){ // if yes, set that rects isDragging=true dragok=true; r.isDragging=true; } } // save the current mouse position startX=mx; startY=my; } // handle mouseup events function myUp(e){ // tell the browser we're handling this mouse event e.preventDefault(); e.stopPropagation(); // clear all the dragging flags dragok = false; for(var i=0;i<rects.length;i++){ rects[i].isDragging=false; } } // handle mouse moves function myMove(e){ // if we're dragging anything... if (dragok){ // tell the browser we're handling this mouse event e.preventDefault(); e.stopPropagation(); // get the current mouse position var mx=parseInt(e.clientX-offsetX); var my=parseInt(e.clientY-offsetY); // calculate the distance the mouse has moved // since the last mousemove var dx=mx-startX; var dy=my-startY; // move each rect that isDragging // by the distance the mouse has moved // since the last mousemove for(var i=0;i<rects.length;i++){ var r=rects[i]; if(r.isDragging){ r.x+=dx; r.y+=dy; } } // redraw the scene with the new rect positions draw(); // reset the starting mouse position for the next mousemove startX=mx; startY=my; } } }; // end $(function(){}); </script>
int32_t

2022/06/21 13:15

> 下記のコードのrectとrectsのところを画像用のコードに置き換えていけばできるんでしょうか? 基本的にはそういうことですけども、四角の描画と画像の描画の違いをチキンと理解してないと達成するのは厳しいですよ。 自分ならこうするかな、というのをざくっと書いておきます。 ・HTML中に、canvas描画に利用する画像を <img> で置いておき、id= を付ける。 ・rectsの要素の設定は以下のように <img> を参照する rects.push({x:75-15, y:50-15, width:30, height:30, img:document.getElementById(<img>のid属性値), isDragging:false}); ・関数rect()のような画像描画用の関数を追加して、然るべきところで使用する
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.68%

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

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

質問する

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

canvas

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

JavaScript

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