<p class="text">キャンバスの上をクリックすると、ボールが落下します</p>
<canvas id="canvas_area" width="300" height="300"></canvas>
html,body {
margin: 0;
padding: 0;
}
.text {
margin: 10px auto 20px;
text-align: center;
line-height: 1.3;
font-size: 14px;
}
#canvas_area {
display: block;
margin: 0 auto;
border: 1px solid #000;
}
window.addEventListener('DOMContentLoaded', function(e) {
new Draw(
"canvas_area",
"rgba( 200, 0, 30, 1 )"
);
});
/*----------------------------------
キャンバスクリック時に、落下
----------------------------------*/
function Draw( id, ballcolor ){
var self = this;
//キャンバスのDOMを取得
this.canvas_id = id;
this.ballcolor = ballcolor;
this.canvas = document.getElementById( self.canvas_id );//キャンバスの位置取得
this.ctx = this.canvas.getContext("2d");
this.init();
this.eventFun();
}
/*----------------------------------
初期値の設定
----------------------------------*/
Draw.prototype.init = function(){
var self = this;
this.g = 9.8; //重力加速度
this.v = 0; //加速度
this.y0 = 0; //ボールのy座標を保存
this.count = 0; //カウント
this.t = 0.2; //時間
this.radius = 20;//円弧の半径
this.e = - 0.7; //反発係数
}
/*----------------------------------
canvasで表示するパスの設定
----------------------------------*/
Draw.prototype.set = function(){
var self = this;
//現在のパスをリセットする
self.ctx.beginPath();
//円弧の中心のx座標値, 円弧の中心のy座標値, 円弧の半径, 円弧の開始角, 円弧の終了角, 円弧を時計回りに描画
self.ctx.arc( self.clickX, self.y, self.radius, 0, Math.PI * 2, false );
//ctxの着色を指定
self.ctx.fillStyle = self.ballcolor;
//ctxのfillStyleの色で塗りつぶす
self.ctx.fill();
//ctxの最終座標と開始座標を結んでパスを閉じる
self.ctx.closePath();
}
/*----------------------------------
位置を取得
----------------------------------*/
Draw.prototype.position = function(){
var self = this;
//描画クリア
self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height);
//パスの生成
self.set();
//速度 = 初速 + 重力 * 時間
self.v += self.g * self.t;
//距離 = 速度 * 時間
self.y += self.v * self.t;
//地面に接したとき(ctxが地面に食い込まないものとし、半径分引いてます)
if ( self.y > self.canvas.height - self.radius) {
self.y = self.canvas.height - self.radius;
//反発係数による速度の状態変化
self.v = self.v * self.e;
}
// 引数にthisを使うためにbind
//self.callbackIdに代入し、処理を繰り返します。
self.callbackId = requestAnimationFrame(self.position.bind(this));
//前回と今回で、ボールのy座標が一致しているか。
if( this.y0 == this.y ){
//100以上、カウントの場合は実行
if(this.count > 100){
//self.callbackIdの処理を停止します
cancelAnimationFrame( self.callbackId );
}
this.count++; //カウント
}
//前回のボールの高さを保存
this.y0 = this.y;
}
/*-----------------------------------------
canvas上をクリックイベントの登録
-----------------------------------------*/
Draw.prototype.eventFun = function(){
var self = this;
self.canvas.addEventListener("click", function ( event ) {
self.init();
// 要素の位置を取得
var clientRect = this.getBoundingClientRect();
self.positionX = clientRect.left + window.pageXOffset;
self.positionY = clientRect.top + window.pageYOffset;
self.x = event.pageX; //クリックした場所(x軸)
self.y = event.pageY; //クリックした場所(y軸)
// canvas内のクリックした位置を計算
self.clickX = self.x - self.positionX;
self.clickY = self.y - self.positionY;
self.position();
});
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.