Javascript プログラミング

「fabric.js、おそろしい子!」。たった1行(実質)書き加えるだけでお絵かきの編集が可能になった

手書き編集をオフにするだけでキャンバスの内容が編集可能になる!

ここんとこずっとお絵かきアプリの改良に励んでいます。

fabric.jsを使ったシンプルなお絵かきWebアプリ

fabric.jsライブラリを使ってブラウザ上でさくっとお絵かきができるwebアプリを作りました

続きを見る

お絵かきアプリにブラシサイズと色が反映されるドットカーソルを追加した

自作のお絵かきWebアプリを使いやすくするために、現在のブラシサイズと色が分かるドットカーソルを作ってみました

続きを見る

 

というか、fabric.jsって本当にすごいライブラリですね。

fabric.jsでは、canvas.isDrawingMode = true; で自由に手書きで描画できるようになります。

何か描いたあとで、このスイッチをオフにする、つまり

 javascript
canvas.isDrawingMode = false;

とすると、なんと手書きで書いた絵がオブジェクトごとに編集できるようになります。

canvas上で任意の図形をクリックするとコントロールハンドルが表示され、個別に拡大縮小、回転、移動が可能です。

以下のCodePenでは、何か手書きで絵を描いてからチェックボックスをオフにすると、描いたものがオブジェクトとして操作できます。

See the Pen
fabric.js free drawing edit on/off
by Ryoji Kimura (@ryjkmr)
on CodePen.

 

特に処理を追加したわけでなく、単に手書きモードをオフにしただけです。いやー簡単。

ちなみに、デフォルトではコントロールハンドルが細くて見づらいので、以下の設定を追加しています。

 javascript
fabric.Object.prototype.set({
borderScaleFactor: 6
})

 

公式のデモを見ると、ほかにもいろんなカスタマイズができるみたいです。

Fabric.js demos · Controls customization

 

削除は自分で実装する必要があるらしい

ただ、fabric.jsではオブジェクトの削除までは自動でやってくれないようです。

オブジェクトを選択してdeleteキーを押しても消えません。

削除機能は自分で実装する必要があるみたいです。

選択したオブジェクト(1つ)を消すには、以下のように書きます。

 javascript
const selection = canvas.getActiveObject();
canvas.remove(selection);
単に消すだけなら以下のコードでOK
canvas.remove(canvas.getActiveObject());

この方法だと複数のオブジェクトを一度に消すことはできません。

まぁでも最初はシンプルにいきましょう。

 

「canvas.on〜」でイベントへの処理を設定できる

キーボードのdeleteキーで消すのも良いですが、練習としてオブジェクトが選択されたときだけdeleteボタンを表示するようにします。

fabric.jsでは「canvas.on〜」という書き方でcanvas上のイベントに処理を割り当てることができます。

オブジェクトが選択されたときには、"selection:created"というイベントが発生し、選択が解除された時には"selection:cleared"というイベントが発生します。

id="delete"のボタンを表示・非表示するには以下のようなコードになります。

 javascript
const deleteBtn = document.getElementById("delete");
canvas.on("selection:created", function () {
deleteBtn.style.display = "inline-block";
});
canvas.on("selection:cleared", function () {
deleteBtn.style.display = "none";
});

ただ、キーボードイベントはfabric.jsでは取得できないようです。

なので、キーボードのdeleteキーで削除したいときには、例えば以下のようにdocumentのkeyupイベントに処理をセットします。

 javascript
document.addEventListener("keyup", function (e) {
console.log(e.keyCode);
if (e.keyCode == 8 |  e.keyCode == 46) {  // delete と backspaceに対応
canvas.remove(canvas.getActiveObject());
}
});

 

まとめると、こんな感じで選択したオブジェクトが消せるようになりました。

まず適当な線を描いてチェックボックスを外すと、編集モードになります。

消したい線をクリックするとdeleteボタンが表示されます。

deleteボタンをクリックすると線が消えます。

See the Pen
fabric.js free drawing edit on/off , delete selected object
by Ryoji Kimura (@ryjkmr)
on CodePen.

 

複数オブジェクトをまとめて消すにはcanvas.gentActiveObjectsを使う

上記のプログラムでは、複数のオブジェクトを一度に消すことができません。

複数オブジェクトを選択してdeleteボタンを押しても何も起きません。

複数のオブジェクトの削除に対応するには 選択オブジェクトの取得にcanvas.gentActiveObjectsを使うのが早いです。

"Object"じゃなくて"Objects"(複数形)です。

実際にはcanvas.gentActiveObjectでも複数オブジェクトの削除に対応できるのですが、選択オブジェクトが一つの場合と複数の場合で処理を分けるなど、ちょっと面倒になります。

ネット上で見かけたコードでは、 canvas.getActiveObject().type で複数オブジェクトが選択されているかどうかをチェックして、 selection.forEachObject という見慣れないメソッドを使ってひとつずつ消していました。

canvas.gentActiveObjectsを使えば、選択されたオブジェクトのリストが配列として得られます。

forEachでひとつずつ取り出して canvas.remove()で消します。

選択オブジェクトがひとつの時は単に配列の長さが1になるだけですから処理を分ける必要がありません。

複数オブジェクトの削除に対応したコードは以下の通りです。

See the Pen
fabric.js free drawing edit on/off , delete multiple objects
by Ryoji Kimura (@ryjkmr)
on CodePen.

 

ひとまずここまで。ちょいメモに組み込むにはキーボードで削除するときにテキストエディタ部分と干渉しないような処理が必要となります。

 

-Javascript, プログラミング
-