質問編集履歴

6 あふぁふぁ

canvas

canvas score 60

2016/08/13 18:34  投稿

円クラスをMVC的に実装したいです!
###質問
MVCについて質問です。HTML5のCanvasで円を描いて、その円をドラッグ出来るようにしたいのですが、円の描画のところでMVCになっていない気が凄いしてちょっと詰まりました。
.
コードはcodePenに載せました。
[http://codepen.io/anon/pen/zBZGPQ
](http://codepen.io/anon/pen/zBZGPQ).
ドラッグ処理の実装や円のヒット判定の実装はこれからなのですが、CircleオブジェクトはMVC的にはどのように書くべきなのでしょうか?
.
現状、円を描画するメソッドもヒット判定をするメソッドも、また、円の座標や半径の値を持つプロパティー、それらのsetter、getterも同一オブジェクトに書いており、これらはビューとモデルに分割すべきなのではないかと感じております。ただ、サーバーサイドMVC上がりの人間なのでいまいち、こういった場合のMVCがイメージできません。。。
.
凄く短いコードなので宜しければリファクタリングして頂けると非常に参考になるので有難いです。もちろんアドバイスだけでも大変有難いです。よろしくお願いいたします。
.
ちなみにメソッドは見易さの為、codePen上のコードではprototypeメソッドにはしておりません。
###該当のソースコード
```JavaScript
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var circle = new Circle(20, 20, 20);
var isDragging = false;
canvas.addEventListener("mousedown", function(event) {
 var isInCircle = circle.hitTest(event.offsetX, event.offsetY);
 if (isInCircle === true) {
   isDragging = true;
   console.log("ドラッグを開始");
 }
});
canvas.addEventListener("mousemove", function(event) {
 if (isDragging === true) {
   console.log("ドラッグ中"); 
 }
});
canvas.addEventListener("mouseup", function(event) {
 isDragging = false;
 console.log("ドラッグ終了");
});
function Circle(x, y, radius) {
 
 var positionX = x + radius;
 var positionY = y + radius;
 var radius = radius;
 
 this.getPositionX = function() {
   return positionX;
 }
 
 this.getPositionY = function(){
   return positionY
 }
 
 this.setPositionX = function(x) {
   positionX = x;
 }
 
 this.setPositionY = function(y) {
   positionY = y;
 }
 
 this.hitTest = function(x, y) {
   console.log("ヒット判定の実装をする");
   return true;
 }
 
 this.draw = function() {
   context.beginPath();
   context.arc(positionX, positionY, radius, 0, Math.PI*2, false);
   context.stroke();
 }
 
 this.draw();
 
}
```
###追記 - 改良してみました(2016-08-13 18:33)
[http://codepen.io/anon/pen/BzrzOb
](http://codepen.io/anon/pen/BzrzOb)
[http://codepen.io/anon/pen/RRvogR
](http://codepen.io/anon/pen/RRvogR)
ひとまずMVCに分割出来ていますでしょうか?
```JavaScript
//コントローラークラス
function ViewController(canvasElement, circleList) {
   
   var circleList = circleList;
   var canvas = canvasElement;
   var canvasView = new CanvasView(canvas.getContext("2d"));
   var stateMap = {
       isDragging: false
   }
 
   circleList.add(new Circle(20, 20, 20));
   circleList.add(new Circle(60, 60, 20));
   
   circleList.getList().forEach(function(circle) {
       canvasView.drawCircle(circle.getPosition(), circle.getRadius());
   })
   canvas.addEventListener("mousedown", function(event) {
       var isTouchedPointOnCircle = circle.hitTest(event.offsetX, event.offsetY);
   
       if (isPointInCircle === true) {
           stateMap.isDragging = true;
           console.log("ドラッグを開始");
       }
   });
   canvas.addEventListener("mousemove", function(event) {
       if (stateMap.isDragging === true) {
           console.log("ドラッグ中"); 
       }
   });
   canvas.addEventListener("mouseup", function(event) {
       stateMap.isDragging = false;
       console.log("ドラッグ終了");
   });
}
//ビュークラス
function CanvasView(context) {
   var context = context;
   
   this.drawCircle = function(position, radius) {
       context.beginPath();
       context.arc(position.x, position.y, radius, 0, Math.PI*2, false);
       context.fill();
   }
   
}
// circleの管理クラス
function CircleList() {
 
   var list = [];
 
   this.add = function(circle) {
       list.push(circle);
   }
 
     this.getList = function() {
       return list;
     }
 
}
// circleのモデルクラス
function Circle(x, y, radius) {
   
   var x = x + radius;
   var y = y + radius;
   var radius = radius;
   
   this.getPosition = function() {
       return {x: x, y: y};
   }
   
   this.getRadius = function() {
       return radius;
   }   
   
   this.hitTest = function(x, y) {
       console.log("ヒット判定の実装をする");
       return true;
   }
   
}
var controller = new ViewController(document.getElementById("canvas"), new CircleList());
```
###今後実装予定の処理
- サークル同士のヒット判定
- サークルとマウスダウン座標とのヒット判定
- 複数のサークルのドラッグ&ドロップに対応
- サークルの上でクリックをするとサークルが選択状態になる
- サークルが選択状態の時にサークルを囲う矩形をドラッグすると、サークルが拡大縮小される
###補足事項
下記のサイトでも質問を投稿しております。
こちらのteratailを見つける前に投稿したのですが、下記サイトに投稿した質問が削除出来なかった為、質問はそのままになっております。
[http://w3q.jp/t/10997](http://w3q.jp/t/10997)
  • JavaScript

    22791 questions

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

  • canvas

    353 questions

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

  • MVC

    293 questions

    MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

  • オブジェクト指向

    351 questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

  • リファクタリング

    19 questions

    リファクタリングとはコードの本体を再構築するための手法であり、外見を変更せずに内部構造を変更/改善させることを指します。

5 サークルの管理クラスを導入

canvas

canvas score 60

2016/08/13 18:34  投稿

円クラスをMVC的に実装したいです!
###質問
MVCについて質問です。HTML5のCanvasで円を描いて、その円をドラッグ出来るようにしたいのですが、円の描画のところでMVCになっていない気が凄いしてちょっと詰まりました。
.
コードはcodePenに載せました。
[http://codepen.io/anon/pen/zBZGPQ
](http://codepen.io/anon/pen/zBZGPQ).
ドラッグ処理の実装や円のヒット判定の実装はこれからなのですが、CircleオブジェクトはMVC的にはどのように書くべきなのでしょうか?
.
現状、円を描画するメソッドもヒット判定をするメソッドも、また、円の座標や半径の値を持つプロパティー、それらのsetter、getterも同一オブジェクトに書いており、これらはビューとモデルに分割すべきなのではないかと感じております。ただ、サーバーサイドMVC上がりの人間なのでいまいち、こういった場合のMVCがイメージできません。。。
.
凄く短いコードなので宜しければリファクタリングして頂けると非常に参考になるので有難いです。もちろんアドバイスだけでも大変有難いです。よろしくお願いいたします。
.
ちなみにメソッドは見易さの為、codePen上のコードではprototypeメソッドにはしておりません。
###該当のソースコード
```JavaScript
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var circle = new Circle(20, 20, 20);
var isDragging = false;
canvas.addEventListener("mousedown", function(event) {
 var isInCircle = circle.hitTest(event.offsetX, event.offsetY);
 if (isInCircle === true) {
   isDragging = true;
   console.log("ドラッグを開始");
 }
});
canvas.addEventListener("mousemove", function(event) {
 if (isDragging === true) {
   console.log("ドラッグ中"); 
 }
});
canvas.addEventListener("mouseup", function(event) {
 isDragging = false;
 console.log("ドラッグ終了");
});
function Circle(x, y, radius) {
 
 var positionX = x + radius;
 var positionY = y + radius;
 var radius = radius;
 
 this.getPositionX = function() {
   return positionX;
 }
 
 this.getPositionY = function(){
   return positionY
 }
 
 this.setPositionX = function(x) {
   positionX = x;
 }
 
 this.setPositionY = function(y) {
   positionY = y;
 }
 
 this.hitTest = function(x, y) {
   console.log("ヒット判定の実装をする");
   return true;
 }
 
 this.draw = function() {
   context.beginPath();
   context.arc(positionX, positionY, radius, 0, Math.PI*2, false);
   context.stroke();
 }
 
 this.draw();
 
}
```
###追記 - 改良してみました(2016-08-13 16:42)
###追記 - 改良してみました(2016-08-13 18:33)
[http://codepen.io/anon/pen/BzrzOb
](http://codepen.io/anon/pen/BzrzOb)
ひとまずMVCに分割出来ていますでしょうか?
```JavaScript
function ViewController(canvasElement) {
   
//コントローラークラス
function ViewController(canvasElement, circleList) {
   
   var circleList = circleList;
   var canvas = canvasElement;
   var canvasView = new CanvasView(canvas.getContext("2d"));
   var stateMap = {
       isDragging: false
   }
   var circle = new Circle(20, 20, 20);
   
   canvasView.drawCircle(circle.getPosition(), circle.getRadius());
 
   circleList.add(new Circle(20, 20, 20));
   circleList.add(new Circle(60, 60, 20));
   
   circleList.getList().forEach(function(circle) {
       canvasView.drawCircle(circle.getPosition(), circle.getRadius());
   })
   canvas.addEventListener("mousedown", function(event) {
       var isPointInCircle = circle.hitTest(event.offsetX, event.offsetY);
       var isTouchedPointOnCircle = circle.hitTest(event.offsetX, event.offsetY);
   
       if (isPointInCircle === true) {
           stateMap.isDragging = true;
           console.log("ドラッグを開始");
       }
   });
   canvas.addEventListener("mousemove", function(event) {
       if (stateMap.isDragging === true) {
           console.log("ドラッグ中"); 
       }
   });
   canvas.addEventListener("mouseup", function(event) {
       stateMap.isDragging = false;
       console.log("ドラッグ終了");
   });
}
 
//ビュークラス  
function CanvasView(context) {
   var context = context;
   
   this.drawCircle = function(position, radius) {
       context.beginPath();
       context.arc(position.x, position.y, radius, 0, Math.PI*2, false);
       context.stroke();
   }
   
}
       context.fill();
   }
   
}
// circleの管理クラス
function CircleList() {
 
   var list = [];
 
   this.add = function(circle) {
       list.push(circle);
   }
 
     this.getList = function() {
       return list;
     }
 
}
// circleのモデルクラス
function Circle(x, y, radius) {
   
   var x = x + radius;
   var y = y + radius;
   var radius = radius;
   
   this.getPosition = function() {
       return {x: x, y: y};
   }
   
   this.getRadius = function() {
       return radius;
   }   
   
   this.hitTest = function(x, y) {
       console.log("ヒット判定の実装をする");
       return true;
   }
   
   
   
}
var controller = new ViewController(document.getElementById("canvas"));
}
var controller = new ViewController(document.getElementById("canvas"), new CircleList());
```
###今後実装予定の処理
- 複数のサークルの描画  
- 複数のサークルを保持するクラスの導入  
- サークル同士のヒット判定
- サークルとマウスダウン座標とのヒット判定
- 複数のサークルのドラッグ&ドロップに対応
- サークルの上でクリックをするとサークルが選択状態になる
- サークルが選択状態の時にサークルを囲う矩形をドラッグすると、サークルが拡大縮小される
###補足事項
下記のサイトでも質問を投稿しております。
こちらのteratailを見つける前に投稿したのですが、下記サイトに投稿した質問が削除出来なかった為、質問はそのままになっております。
[http://w3q.jp/t/10997](http://w3q.jp/t/10997)
  • JavaScript

    22791 questions

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

  • canvas

    353 questions

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

  • MVC

    293 questions

    MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

  • オブジェクト指向

    351 questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

  • リファクタリング

    19 questions

    リファクタリングとはコードの本体を再構築するための手法であり、外見を変更せずに内部構造を変更/改善させることを指します。

4 追記キング

canvas

canvas score 60

2016/08/13 16:57  投稿

円クラスをMVC的に実装したいです!
###質問
MVCについて質問です。HTML5のCanvasで円を描いて、その円をドラッグ出来るようにしたいのですが、円の描画のところでMVCになっていない気が凄いしてちょっと詰まりました。
.
コードはcodePenに載せました。
[http://codepen.io/anon/pen/zBZGPQ
](http://codepen.io/anon/pen/zBZGPQ).
ドラッグ処理の実装や円のヒット判定の実装はこれからなのですが、CircleオブジェクトはMVC的にはどのように書くべきなのでしょうか?
.
現状、円を描画するメソッドもヒット判定をするメソッドも、また、円の座標や半径の値を持つプロパティー、それらのsetter、getterも同一オブジェクトに書いており、これらはビューとモデルに分割すべきなのではないかと感じております。ただ、サーバーサイドMVC上がりの人間なのでいまいち、こういった場合のMVCがイメージできません。。。
.
凄く短いコードなので宜しければリファクタリングして頂けると非常に参考になるので有難いです。もちろんアドバイスだけでも大変有難いです。よろしくお願いいたします。
.
ちなみにメソッドは見易さの為、codePen上のコードではprototypeメソッドにはしておりません。
###該当のソースコード
```JavaScript
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var circle = new Circle(20, 20, 20);
var isDragging = false;
canvas.addEventListener("mousedown", function(event) {
 var isInCircle = circle.hitTest(event.offsetX, event.offsetY);
 if (isInCircle === true) {
   isDragging = true;
   console.log("ドラッグを開始");
 }
});
canvas.addEventListener("mousemove", function(event) {
 if (isDragging === true) {
   console.log("ドラッグ中"); 
 }
});
canvas.addEventListener("mouseup", function(event) {
 isDragging = false;
 console.log("ドラッグ終了");
});
function Circle(x, y, radius) {
 
 var positionX = x + radius;
 var positionY = y + radius;
 var radius = radius;
 
 this.getPositionX = function() {
   return positionX;
 }
 
 this.getPositionY = function(){
   return positionY
 }
 
 this.setPositionX = function(x) {
   positionX = x;
 }
 
 this.setPositionY = function(y) {
   positionY = y;
 }
 
 this.hitTest = function(x, y) {
   console.log("ヒット判定の実装をする");
   return true;
 }
 
 this.draw = function() {
   context.beginPath();
   context.arc(positionX, positionY, radius, 0, Math.PI*2, false);
   context.stroke();
 }
 
 this.draw();
 
}
```
###追記 - 改良してみました(2016-08-13 16:42)
[http://codepen.io/anon/pen/BzrzOb
](http://codepen.io/anon/pen/BzrzOb)
ひとまずMVCに分割出来ていますでしょうか?
これから実装予定の処理としては以下があります。  
- 複数のサークルの描画  
- 複数のサークルを保持するクラスの導入  
- サークル同士のヒット判定  
- サークルとマウスダウン座標とのヒット判定  
- 複数のサークルのドラッグ&ドロップに対応  
 
```JavaScript
function ViewController(canvasElement) {
   
   var canvas = canvasElement;
   var canvasView = new CanvasView(canvas.getContext("2d"));
   var stateMap = {
       isDragging: false
   }
   var circle = new Circle(20, 20, 20);
   
   canvasView.drawCircle(circle.getPosition(), circle.getRadius());
   canvas.addEventListener("mousedown", function(event) {
       var isPointInCircle = circle.hitTest(event.offsetX, event.offsetY);
   
       if (isPointInCircle === true) {
           stateMap.isDragging = true;
           console.log("ドラッグを開始");
       }
   });
   canvas.addEventListener("mousemove", function(event) {
       if (stateMap.isDragging === true) {
           console.log("ドラッグ中"); 
       }
   });
   canvas.addEventListener("mouseup", function(event) {
       stateMap.isDragging = false;
       console.log("ドラッグ終了");
   });
}
function CanvasView(context) {
   var context = context;
   
   this.drawCircle = function(position, radius) {
       context.beginPath();
       context.arc(position.x, position.y, radius, 0, Math.PI*2, false);
       context.stroke();
   }
   
}
function Circle(x, y, radius) {
   
   var x = x + radius;
   var y = y + radius;
   var radius = radius;
   
   this.getPosition = function() {
       return {x: x, y: y};
   }
   
   this.getRadius = function() {
       return radius;
   }   
   
   this.hitTest = function(x, y) {
       console.log("ヒット判定の実装をする");
       return true;
   }
   
   
   
}
var controller = new ViewController(document.getElementById("canvas"));
```
###今後実装予定の処理  
- 複数のサークルの描画  
- 複数のサークルを保持するクラスの導入  
- サークル同士のヒット判定  
- サークルとマウスダウン座標とのヒット判定  
- 複数のサークルのドラッグ&ドロップに対応  
- サークルの上でクリックをするとサークルが選択状態になる  
- サークルが選択状態の時にサークルを囲う矩形をドラッグすると、サークルが拡大縮小される  
###補足事項
下記のサイトでも質問を投稿しております。
こちらのteratailを見つける前に投稿したのですが、下記サイトに投稿した質問が削除出来なかった為、質問はそのままになっております。
[http://w3q.jp/t/10997](http://w3q.jp/t/10997)
  • JavaScript

    22791 questions

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

  • canvas

    353 questions

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

  • MVC

    293 questions

    MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

  • オブジェクト指向

    351 questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

  • リファクタリング

    19 questions

    リファクタリングとはコードの本体を再構築するための手法であり、外見を変更せずに内部構造を変更/改善させることを指します。

3 追記

canvas

canvas score 60

2016/08/13 16:48  投稿

円クラスをMVC的に実装したいです!
###質問
MVCについて質問です。HTML5のCanvasで円を描いて、その円をドラッグ出来るようにしたいのですが、円の描画のところでMVCになっていない気が凄いしてちょっと詰まりました。
.
コードはcodePenに載せました。
[http://codepen.io/anon/pen/zBZGPQ
](http://codepen.io/anon/pen/zBZGPQ).
ドラッグ処理の実装や円のヒット判定の実装はこれからなのですが、CircleオブジェクトはMVC的にはどのように書くべきなのでしょうか?
.
現状、円を描画するメソッドもヒット判定をするメソッドも、また、円の座標や半径の値を持つプロパティー、それらのsetter、getterも同一オブジェクトに書いており、これらはビューとモデルに分割すべきなのではないかと感じております。ただ、サーバーサイドMVC上がりの人間なのでいまいち、こういった場合のMVCがイメージできません。。。
.
凄く短いコードなので宜しければリファクタリングして頂けると非常に参考になるので有難いです。もちろんアドバイスだけでも大変有難いです。よろしくお願いいたします。
.
ちなみにメソッドは見易さの為、codePen上のコードではprototypeメソッドにはしておりません。
###該当のソースコード
```JavaScript
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var circle = new Circle(20, 20, 20);
var isDragging = false;
canvas.addEventListener("mousedown", function(event) {
 var isInCircle = circle.hitTest(event.offsetX, event.offsetY);
 if (isInCircle === true) {
   isDragging = true;
   console.log("ドラッグを開始");
 }
});
canvas.addEventListener("mousemove", function(event) {
 if (isDragging === true) {
   console.log("ドラッグ中"); 
 }
});
canvas.addEventListener("mouseup", function(event) {
 isDragging = false;
 console.log("ドラッグ終了");
});
function Circle(x, y, radius) {
 
 var positionX = x + radius;
 var positionY = y + radius;
 var radius = radius;
 
 this.getPositionX = function() {
   return positionX;
 }
 
 this.getPositionY = function(){
   return positionY
 }
 
 this.setPositionX = function(x) {
   positionX = x;
 }
 
 this.setPositionY = function(y) {
   positionY = y;
 }
 
 this.hitTest = function(x, y) {
   console.log("ヒット判定の実装をする");
   return true;
 }
 
 this.draw = function() {
   context.beginPath();
   context.arc(positionX, positionY, radius, 0, Math.PI*2, false);
   context.stroke();
 }
 
 this.draw();
 
}
```
###追記 - 改良してみました(2016-08-13 16:42)
[http://codepen.io/anon/pen/BzrzOb
](http://codepen.io/anon/pen/BzrzOb)
ひとまずMVCに分割出来ていますでしょうか?  
 
これから実装予定の処理としては以下があります。  
- 複数のサークルの描画  
- 複数のサークルを保持するクラスの導入  
- サークル同士のヒット判定  
- サークルとマウスダウン座標とのヒット判定  
- 複数のサークルのドラッグ&ドロップに対応  
 
```JavaScript
function ViewController(canvasElement) {
   
   var canvas = canvasElement;
   var canvasView = new CanvasView(canvas.getContext("2d"));
   var stateMap = {
       isDragging: false
   }
   var circle = new Circle(20, 20, 20);
   
   canvasView.drawCircle(circle.getPosition(), circle.getRadius());
   canvas.addEventListener("mousedown", function(event) {
       var isPointInCircle = circle.hitTest(event.offsetX, event.offsetY);
   
       if (isPointInCircle === true) {
           stateMap.isDragging = true;
           console.log("ドラッグを開始");
       }
   });
   canvas.addEventListener("mousemove", function(event) {
       if (stateMap.isDragging === true) {
           console.log("ドラッグ中"); 
       }
   });
   canvas.addEventListener("mouseup", function(event) {
       stateMap.isDragging = false;
       console.log("ドラッグ終了");
   });
}
function CanvasView(context) {
   var context = context;
   
   this.drawCircle = function(position, radius) {
       context.beginPath();
       context.arc(position.x, position.y, radius, 0, Math.PI*2, false);
       context.stroke();
   }
   
}
function Circle(x, y, radius) {
   
   var x = x + radius;
   var y = y + radius;
   var radius = radius;
   
   this.getPosition = function() {
       return {x: x, y: y};
   }
   
   this.getRadius = function() {
       return radius;
   }   
   
   this.hitTest = function(x, y) {
       console.log("ヒット判定の実装をする");
       return true;
   }
   
   
   
}
var controller = new ViewController(document.getElementById("canvas"));
```
###補足事項
下記のサイトでも質問を投稿しております。
こちらのteratailを見つける前に投稿したのですが、下記サイトに投稿した質問が削除出来なかった為、質問はそのままになっております。
[http://w3q.jp/t/10997](http://w3q.jp/t/10997)
  • JavaScript

    22791 questions

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

  • canvas

    353 questions

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

  • MVC

    293 questions

    MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

  • オブジェクト指向

    351 questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

  • リファクタリング

    19 questions

    リファクタリングとはコードの本体を再構築するための手法であり、外見を変更せずに内部構造を変更/改善させることを指します。

2 改良コードを追記

canvas

canvas score 60

2016/08/13 16:45  投稿

円クラスをMVC的に実装したいです!
###質問
MVCについて質問です。HTML5のCanvasで円を描いて、その円をドラッグ出来るようにしたいのですが、円の描画のところでMVCになっていない気が凄いしてちょっと詰まりました。
.
コードはcodePenに載せました。
[http://codepen.io/anon/pen/zBZGPQ
](http://codepen.io/anon/pen/zBZGPQ).
ドラッグ処理の実装や円のヒット判定の実装はこれからなのですが、CircleオブジェクトはMVC的にはどのように書くべきなのでしょうか?
.
現状、円を描画するメソッドもヒット判定をするメソッドも、また、円の座標や半径の値を持つプロパティー、それらのsetter、getterも同一オブジェクトに書いており、これらはビューとモデルに分割すべきなのではないかと感じております。ただ、サーバーサイドMVC上がりの人間なのでいまいち、こういった場合のMVCがイメージできません。。。
.
凄く短いコードなので宜しければリファクタリングして頂けると非常に参考になるので有難いです。もちろんアドバイスだけでも大変有難いです。よろしくお願いいたします。
.
ちなみにメソッドは見易さの為、codePen上のコードではprototypeメソッドにはしておりません。
###該当のソースコード
```JavaScript
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var circle = new Circle(20, 20, 20);
var isDragging = false;
canvas.addEventListener("mousedown", function(event) {
 var isInCircle = circle.hitTest(event.offsetX, event.offsetY);
 if (isInCircle === true) {
   isDragging = true;
   console.log("ドラッグを開始");
 }
});
canvas.addEventListener("mousemove", function(event) {
 if (isDragging === true) {
   console.log("ドラッグ中"); 
 }
});
canvas.addEventListener("mouseup", function(event) {
 isDragging = false;
 console.log("ドラッグ終了");
});
function Circle(x, y, radius) {
 
 var positionX = x + radius;
 var positionY = y + radius;
 var radius = radius;
 
 this.getPositionX = function() {
   return positionX;
 }
 
 this.getPositionY = function(){
   return positionY
 }
 
 this.setPositionX = function(x) {
   positionX = x;
 }
 
 this.setPositionY = function(y) {
   positionY = y;
 }
 
 this.hitTest = function(x, y) {
   console.log("ヒット判定の実装をする");
   return true;
 }
 
 this.draw = function() {
   context.beginPath();
   context.arc(positionX, positionY, radius, 0, Math.PI*2, false);
   context.stroke();
 }
 
 this.draw();
 
}
```
###追記 - 改良してみました(2016-08-13 16:42)  
[http://codepen.io/anon/pen/BzrzOb  
](http://codepen.io/anon/pen/BzrzOb)  
```JavaScript  
function ViewController(canvasElement) {  
     
   var canvas = canvasElement;  
   var canvasView = new CanvasView(canvas.getContext("2d"));  
   var stateMap = {  
       isDragging: false  
   }  
   var circle = new Circle(20, 20, 20);  
     
   canvasView.drawCircle(circle.getPosition(), circle.getRadius());  
 
   canvas.addEventListener("mousedown", function(event) {  
       var isPointInCircle = circle.hitTest(event.offsetX, event.offsetY);  
     
       if (isPointInCircle === true) {  
           stateMap.isDragging = true;  
           console.log("ドラッグを開始");  
       }  
   });  
 
   canvas.addEventListener("mousemove", function(event) {  
       if (stateMap.isDragging === true) {  
           console.log("ドラッグ中");   
       }  
   });  
 
   canvas.addEventListener("mouseup", function(event) {  
       stateMap.isDragging = false;  
       console.log("ドラッグ終了");  
 
   });  
 
}  
 
 
function CanvasView(context) {  
   var context = context;  
     
   this.drawCircle = function(position, radius) {  
       context.beginPath();  
       context.arc(position.x, position.y, radius, 0, Math.PI*2, false);  
       context.stroke();  
   }  
     
}  
 
 
function Circle(x, y, radius) {  
     
   var x = x + radius;  
   var y = y + radius;  
   var radius = radius;  
     
   this.getPosition = function() {  
       return {x: x, y: y};  
   }  
     
   this.getRadius = function() {  
       return radius;  
   }     
     
   this.hitTest = function(x, y) {  
       console.log("ヒット判定の実装をする");  
       return true;  
   }  
     
 
     
     
}  
 
 
 
var controller = new ViewController(document.getElementById("canvas"));  
```  
 
 
###補足事項
下記のサイトでも質問を投稿しております。
こちらのteratailを見つける前に投稿したのですが、下記サイトに投稿した質問が削除出来なかった為、質問はそのままになっております。
[http://w3q.jp/t/10997](http://w3q.jp/t/10997)
  • JavaScript

    22791 questions

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

  • canvas

    353 questions

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

  • MVC

    293 questions

    MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

  • オブジェクト指向

    351 questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

  • リファクタリング

    19 questions

    リファクタリングとはコードの本体を再構築するための手法であり、外見を変更せずに内部構造を変更/改善させることを指します。

1 リファクタリングのタグを追加

canvas

canvas score 60

2016/08/13 03:16  投稿

円クラスをMVC的に実装したいです!
###質問
MVCについて質問です。HTML5のCanvasで円を描いて、その円をドラッグ出来るようにしたいのですが、円の描画のところでMVCになっていない気が凄いしてちょっと詰まりました。
.
コードはcodePenに載せました。
[http://codepen.io/anon/pen/zBZGPQ
](http://codepen.io/anon/pen/zBZGPQ).
ドラッグ処理の実装や円のヒット判定の実装はこれからなのですが、CircleオブジェクトはMVC的にはどのように書くべきなのでしょうか?
.
現状、円を描画するメソッドもヒット判定をするメソッドも、また、円の座標や半径の値を持つプロパティー、それらのsetter、getterも同一オブジェクトに書いており、これらはビューとモデルに分割すべきなのではないかと感じております。ただ、サーバーサイドMVC上がりの人間なのでいまいち、こういった場合のMVCがイメージできません。。。
.
凄く短いコードなので宜しければリファクタリングして頂けると非常に参考になるので有難いです。もちろんアドバイスだけでも大変有難いです。よろしくお願いいたします。
.
ちなみにメソッドは見易さの為、codePen上のコードではprototypeメソッドにはしておりません。
###該当のソースコード
```JavaScript
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var circle = new Circle(20, 20, 20);
var isDragging = false;
canvas.addEventListener("mousedown", function(event) {
var isInCircle = circle.hitTest(event.offsetX, event.offsetY);
if (isInCircle === true) {
isDragging = true;
console.log("ドラッグを開始");
}
});
canvas.addEventListener("mousemove", function(event) {
if (isDragging === true) {
console.log("ドラッグ中");
}
});
canvas.addEventListener("mouseup", function(event) {
isDragging = false;
console.log("ドラッグ終了");
});
function Circle(x, y, radius) {
var positionX = x + radius;
var positionY = y + radius;
var radius = radius;
this.getPositionX = function() {
return positionX;
}
this.getPositionY = function(){
return positionY
}
this.setPositionX = function(x) {
positionX = x;
}
this.setPositionY = function(y) {
positionY = y;
}
this.hitTest = function(x, y) {
console.log("ヒット判定の実装をする");
return true;
}
this.draw = function() {
context.beginPath();
context.arc(positionX, positionY, radius, 0, Math.PI*2, false);
context.stroke();
}
this.draw();
}
```
###補足事項
下記のサイトでも質問を投稿しております。
こちらのteratailを見つける前に投稿したのですが、下記サイトに投稿した質問が削除出来なかった為、質問はそのままになっております。
[http://w3q.jp/t/10997](http://w3q.jp/t/10997)
  • JavaScript

    22791 questions

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

  • canvas

    353 questions

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

  • MVC

    293 questions

    MVC(Model View Controller)は、オブジェクト指向プログラミングにおけるモデル・ビュー・コントローラーの総称であり、ソフトフェア開発で使われている構築パターンとしても呼ばれます。

  • オブジェクト指向

    351 questions

    オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

  • リファクタリング

    19 questions

    リファクタリングとはコードの本体を再構築するための手法であり、外見を変更せずに内部構造を変更/改善させることを指します。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る