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>