<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();
    });
  }

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.