線分を繋ぐ
一筆書きにはベジェ曲線を使いますが、まずは直線を描きます。頂点とコントロールポイントの座標が全く同じなら直線になります。その後でマウスドラッグに対応して曲線を描けるようにします。マウスドラッグでコントロールポイントを移動させますが、コントロールポイントは視覚的に表示しません。
直線を繋いで一筆書き
次のサンプルコードのように追記してプロジェクトをデバッグビルドして実行したら、直線も描きます。点とベジェ曲線の線の太さ(lineWidthプロパティ)をそれぞれ変更していることに気を付けてください。
もう一度言いますが、_pos配列にベジェ曲線の情報が入り[コントロールポイントX1,コントロールポイントY1,頂点X1,頂点Y1,コントロールポイントX2,コントロールポイントY2,頂点X2,頂点Y2,・・・]と繰り返されます。ただし1個目のコントロールポイント(X1,Y1)はダミーで使いません。
(前略)
// 図形の描画
function line() {
_context.clearRect(0,0,_canvas.width,_canvas.height);
_context.strokeStyle = 'rgb(0,0,0)';
_context.lineWidth = 1;
// 1クリックした頂点
for ( let i = 0; i < _current; i++ ) _context.strokeRect(_pos[i*4+2],_pos[i*4+3],1,1);
// ベジェ曲線を引いていく
_context.lineWidth = 3;
_context.beginPath();
for ( let i = 1; i < _current; i++ ) {
_context.moveTo(_pos[i*4-2],_pos[i*4-1]);
_context.quadraticCurveTo(_pos[i*4],_pos[i*4+1],_pos[i*4+2],_pos[i*4+3]);
}
_context.stroke();
}
(後略)
サンプルコードの解説
line関数で頂点の矩形を描画したり、ベジェ曲線を描画(moveToメソッドとquadraticCurveToメソッド)したりします。ベジェ曲線のforループはi = 1から始まっていることに注意してください。
曲線を繋いで一筆書き
次のサンプルコードをコーディングしてプロジェクトをデバッグビルドして実行したら、マウスクリックとマウスドラッグでベジェ曲線でお絵描きができます。もうほとんどプロトタイプは完成したと言っても過言ではありません。
// TAURI
const { invoke } = window.__TAURI__.core;
// 変数
let _canvas = document.querySelector('canvas');
let _context = _canvas.getContext('2d');
let _click = false;
let _pos = [];
let _current = 0;
// 全てのDOMが読み込み完了したら
window.addEventListener("DOMContentLoaded", () => {
// マウスがクリックされたら頂点描画
_canvas.addEventListener("mousedown", (e) => {
_click = true;
let pos = getPos(e);
_pos.push(pos[0],pos[1],pos[0],pos[1]);
_current = _pos.length/4;
line();
});
// マウスがドラッグされたら
window.addEventListener("mousemove", (e) => {
if ( _click ) {
let pos = getPos(e);
_pos[_pos.length-4] = pos[0];
_pos[_pos.length-3] = pos[1];
line();
}
});
// マウスが離されたら
window.addEventListener("mouseup", (e) => { _click = false; });
});
(後略)
サンプルコードの解説
htmlファイルのDOMが全て読み込み完了したら、マウスドラッグとマウスリリースをフックします。
マウスが押されている間だけ_clickがtrueになるのでマウスドラッグでコントロールポイントの座標を更新し線を曲げます。それから「line」関数を呼んで一筆書きします。
マウスリリースで曲線の描画を終了します。
おわりに
今回はフロントエンドでお絵描きだけするプログラムをHTML5+CSS+JavaScriptで作りました。マウスクリックで線を一筆書きするだけでなく、マウスドラッグで曲線も描きました。
次回はマウスホイールでアンドゥやリドゥして、一筆書きのプロセスをアニメーションに似た操作をする実装をします。
