作成日:2025年05月19日
手書きツールを作ろう(1)


どうも、にゃん太です
Webビューアを使用すれば手書き処理が実現できます
ここまでのメモ書きではフリーハンドの線を引くだけでしたが、ちゃんと設定すれば、フリーハンドだけでなく色々と描くことができるのです
今回のメモでは、少しだけ機能を追加した手書きツールを作成してみます
手書きで欲しい機能
さて、FileMakerで手書きツールを作成するとして、どんな機能が欲しいでしょうか
パッと思いついたのは、下記の様な機能です
- 取り消しする
- 色を変更する
- 直線を引く
- 図形を描く
もう少し考えれば他にもあるかもしれませんが、今回はこの4つの機能を作成してみます
取り消しする
取り消しとして考えられるのは、全部クリアする方法と1手戻す方法です
全部クリアするには「clearRect」を使用します
Clearボタンを押すと、それまでに書いたものが全部消えるのが分かります
しかし、間違えるたびに全部やり直しはちょっと困ります
そこで、1手戻すUndo機能です
具体的な方法としては、描画する前の段階のデータを保存しておき、指示があった場合に描画データを前の内容に差し替える、という方法となります
まずは描画データの履歴を保管する方法です
Javascript
const STACK_MAX = 5; function beforeDraw() { if (undoDataStack.length >= STACK_MAX) { undoDataStack.pop(); }; undoDataStack.unshift(ctx.getImageData(0, 0, hwb.width, hwb.height)); };
この処理で5回分まで履歴データが保存できます
次に、Undoを実行する処理です
Javascript
function undo () { if (undoDataStack.length <= 0) return; var imageData = undoDataStack.shift(); ctx.putImageData(imageData, 0, 0); };
現在の描画データを履歴データで上書きし、履歴データの配列をスライドさせています
実際に試してみましょう
どうでしょうか
5回分だけ元に戻せる様になっていると思います
戻せる回数はメモリとの相談となりますが、好きに変更できます
線の色を変更する
線の色は「strokeStyle」で変更できます
Javascript
ctx.strokeStyle = '#FF0000';
こんなスクリプトを追加すれば、線の色が赤色(#FF0000)に変わります
線の色が変更できました
これだと固定の色になってしまいますが、もちろんユーザーが任意に指定して色を変える事も可能です
HTML
<input type='color' id='colorPicker' value='#000' style='width:60px; height:32px;'>
Javascript
document.getElementById('colorPicker').onchange = function(){ ctx.strokeStyle = document.getElementById('colorPicker').value; };
この様に記述すれば、カラーピッカーの選択に応じて線の色を変更する事ができます
直線を引く
マウスを使って手書きすると、中々思うように書けません
きれいな直線を書きたい! と思う事もあるでしょう
1回目のクリックで始点を決め、2回目のクリックで終点を決める処理とすれば、始点から終点までの直線を引かせることができます
Javascript
hwb.addEventListener('mouseup', (e) => { if(writing){ ctx.closePath(); draw( e.layerX - hwb.getBoundingClientRect().left, e.layerY - hwb.getBoundingClientRect().top ); writing = false; }else{ ctx.beginPath(); lastPosition.x = e.layerX - hwb.getBoundingClientRect().left; lastPosition.y = e.layerY - hwb.getBoundingClientRect().top; writing = true; } });
こんな風にクリック毎に始点、終点を切り替えて描画する様な仕組みですね
これで直線が引ける様になりました
とはいえ、どんな感じに線画引かれるのかがこれでは分かりづらいです
2回目のクリックまでの間、マウスの位置まで線を仮表示し、クリックしたら確定する、という動きにすると分かりやすそうです
Javascript
let baseImage = null; // 描画 function draw(x, y) { ctx.putImageData(baseImage, 0, 0); ctx.beginPath(); ctx.moveTo(lastPosition.x, lastPosition.y); ctx.lineTo(x, y); ctx.stroke(); }; // 枠外 function lineCancel() { if(writing && baseImage !== null) { ctx.putImageData(baseImage, 0, 0); } writing = false; }; function beforeDraw() { baseImage = ctx.getImageData(0, 0, hwb.width, hwb.height); }; hwb.addEventListener('mouseout', lineCancel); hwb.addEventListener('mouseup', (e) => { if(writing){ draw( e.layerX - hwb.getBoundingClientRect().left, e.layerY - hwb.getBoundingClientRect().top ); writing = false; }else{ beforeDraw(); lastPosition.x = e.layerX - hwb.getBoundingClientRect().left; lastPosition.y = e.layerY - hwb.getBoundingClientRect().top; writing = true; } }); hwb.addEventListener('mousemove', function(e) { if(writing){ draw( e.layerX - hwb.getBoundingClientRect().left, e.layerY - hwb.getBoundingClientRect().top ); } });
マウスを動かす度に元の状態に戻して線を引いています
これにより、線のイメージをつけながら確定する事ができる様になります
図形を描く
基本的には先ほどの直線と同じ記述で、DRAW処理だけを変更すればOKです
四角形を描くなら「fillRect」もしくは「strokeRect」を使用します
「fillRect」なら塗りつぶされた四角形となります
Javascript
function draw(x, y) { ctx.putImageData(baseImage, 0, 0); ctx.fillRect(lastPosition.x, lastPosition.y, x - lastPosition.x, y - lastPosition.y); };
「strokeRect」なら輪郭のみの四角形となります
Javascript
function draw(x, y) { ctx.putImageData(baseImage, 0, 0); ctx.strokeRect(lastPosition.x, lastPosition.y, x - lastPosition.x, y - lastPosition.y); };
円を描く場合は「arc」を使用します
Javascript
function draw(x, y) { ctx.putImageData(baseImage, 0, 0); let w = Math.abs(x - lastPosition.x); let h = Math.abs(y - lastPosition.y); let size = Math.max(w, h); ctx.beginPath(); ctx.arc(lastPosition.x, lastPosition.y, size, 0, 2 * Math.PI); ctx.closePath(); };
FileMakerサンプル
とりあえず、今回はここまでとします
今回、クリックごとに動作が進むように設計しましたが、タッチ操作では上手く機能しないなどの問題があります
次回はドラッグ操作で動く様に設計し、その辺りを改善してみましょう
手書きツールを作ろう(2)へ続きます
一応、ここまでのまとめで作成したサンプルを公開していますので、ご興味がありましたらこちらからダウンロードしてご確認ください

以上で今日のメモ書きは終了です
内容はいかがでしたか?
もしご意見やご要望、誤りの指摘などありましたら、下記フォームよりお気軽にご連絡ください