JS.4 Canvasで遊んでみる

HTML5から追加されたCanvasというものを使って、お絵かきアプリを作成しました。

イベントドリブンのものは jquery で、それ以外のものは直のJavaScriptで書いたつもりです。だいぶ JavaScript にも慣れてきた!!

作ったもの

color: #000000
background-color: #ffffff

コード

<div class="canvas">
  <!-- canvasのサイズを変更する場合、スタイルではなく属性で変更しないとおかしくなる! -->
  <canvas id="drawing-pad" width="400px" height="400px" style="border: 1.5px solid #000; background-color: #ffffff"></canvas>
  <div>
    <input id="pen-color" type="color" value="#000000">
    color: <span id="color1">#000000</span>
  </div>
  <div>
    <input id="pad-color" type="color" value="#ffffff">
    background-color: <span id="color2">#ffffff</span>
  </div>
  <button id="download" class="btn-blue">download</button>
  <button id="clear-button" class="btn-red">Clear All</button>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
  // Canvasの情報
  var canvas;
  var context;

  // 線の情報
  var color;

  // ページの読み込みが完了したらコールバック関数が呼ばれる
  window.addEventListener('load', function() {
    canvas = document.querySelector('#drawing-pad');
    context = canvas.getContext('2d');

    const lastPosition = { x: null, y: null }; // nullで初期化。
    let isDrag = false; // 線を描き続けているかを判断するためのフラグ

    var draw = function(x, y){
      if(!isDrag) {
        return;
      }
      /* 線の情報 */
      context.lineCap = 'round';    // 丸みを帯びた線にする
      context.lineJoin = 'round';   // 丸みを帯びた線にする
      context.lineWidth = 5;        // 線の太さ
      context.strokeStyle = color;  // 線の色

      // 開始位置の調整
      if (lastPosition.x === null || lastPosition.y === null) {
        context.moveTo(x, y);
      } else {
        context.moveTo(lastPosition.x, lastPosition.y);
      }
      // 開始位置から現在の位置を線で結ぶ。
      context.lineTo(x, y);

      // 実際に描画する。
      context.stroke();

      // 現在の点を次回の開始点にする。
      lastPosition.x = x;
      lastPosition.y = y;
    }
    var dragStart = function(e) {
      // 描画開始を宣言
      context.beginPath();
      isDrag = true;
    }
    var dragEnd = function(e) {
      // 描画終了を宣言
      context.closePath();
      isDrag = false;

      // 開始点をリセット。
      lastPosition.x = null; lastPosition.y = null;
    }
    // canvas上に書いた絵を全部消す
    var clear = function() {
      context.clearRect(0, 0, canvas.width, canvas.height);
      document.querySelector('#drawing-pad').style.backgroundColor = '#ffffff'; // canvasの背景色
      document.querySelector('#color2').innerHTML = '#ffffff'; // 表示されているカラーコード
      document.querySelector('#color2').style.color = '#ffffff'; // 上の文字色
      document.querySelector('#pad-color').value = '#ffffff'; // ボタンの色
    }

    // マウス操作やボタンクリック時のイベント処理を定義する
    var initEventHandler = function() {
      canvas.addEventListener('mousedown', dragStart); // マウスボタンを押した時。
      canvas.addEventListener('mouseup',   dragEnd);   // マウスボタンを離した時。
      canvas.addEventListener('mouseout',  dragEnd);   // マウスカーソルが外に出た時。
      canvas.addEventListener('mousemove', function(e) { // マウスカーソルが動いた時
        draw(e.layerX, e.layerY);
      });

      const clearButton = document.querySelector('#clear-button');
      clearButton.addEventListener('click', clear);
    }
    // イベント処理を初期化する
    initEventHandler();
  });

  $(function(){
    // ペンの色を変更
    $(function(){
      $('#pen-color').on('change', function(){
        $('#color1').text($('#pen-color').val()).css('color', $('#pen-color').val());
        color = $('#pen-color').val();
      })
    });

    // 背景色を変更
    $('#pad-color').on('change', function(){
      $('#color2').text($('#pad-color').val()).css('color', $('#pad-color').val());
      $('#drawing-pad').css('background-color', $('#pad-color').val());
      // 以下の手法だと、描画した画像が上書きされてしまう!
      // context.fillStyle = $('#pad-color').val();
      // context.fillRect(0, 0, canvas.width, canvas.height);
    })

    // ダウンロード
    $('#download').on('click', function(){
      // メモリ内で新しく画像を描画し、ダウンロードしている。
      var mem_canvas = document.createElement("canvas");
      mem_canvas.width = canvas.width;
      mem_canvas.height = canvas.height;
      var mem_context = mem_canvas.getContext('2d');
      // まず、背景色として指定されている色で塗りつぶす。
      mem_context.fillStyle = $('#pad-color').val();
      mem_context.fillRect(0, 0, canvas.width, canvas.height);
      // 次に、現在描かれている絵(線)をコピーする。
      mem_context.drawImage(canvas,0,0);
      // それをダウンロード。
      let link = document.createElement("a");
      link.href = mem_canvas.toDataURL("image/png");
      link.download = "canvas.png";
      link.click();
    })
  });
</script>
<style>
  .canvas {
    text-align: center;
    margin: 30px auto;
  }
  .btn-blue {
    background-color: rgba(68, 122, 178);
    color: #fff;
    padding: 10px;
    border-radius: 3px;
  }
  .btn-red {
    background-color: rgb(252, 92, 84);
    color: #fff;
    padding: 10px;
    border-radius: 3px;
  }
</style>
other contents
social