この記事は C3 Advent Calendar 2022 14日目の記事です
はじめに
ふぃるです。
C3 では Web フロントエンドを中心で色々開発したり、曲を作ったりしています。
最近、原神にはまって卒業研究がなかなか進みません。助けてください。
Fabric.jsとは
その名の通り、JavaScript のライブラリです。
お絵かきをすることができます。
使い方としては、お題をもとにどんな絵を書いてるか当てるゲームや、お絵かき伝言ゲームなどがあります。なんか聞いたことがあるゲームだって?気のせいじゃないですか?
公式のホームページはこちら
Tutorial や Docs などがありますが微妙に見づらいので、ここで色々紹介します。
デモ
React + TypeScript + MUI でデモを作りました。
https://handwritten-app.vercel.app/
Github の URL も一応載せておきます。
git clone
して煮るなり焼くなり好きにしてもらっても大丈夫です。
https://github.com/citrus-candy/handwritten-app
デモでは以下の機能を実装しています。
- Undo & Redo
- Clear
- ブラシの色変更
- ブラシの太さ変更
この機能について、どのような実装をしているのか紹介していきます。
Undo & Redo
Undo と Redo に関しては Fabric.js に実装されていないので、自前で実装する必要があります。
Undo
const undo = () => {
if (canvas !== undefined && canvas._objects.length > 0) {
const copyArray = [...canvasHistory]
copyArray.push(canvas._objects.pop()!)
canvasHistory = copyArray
canvas.renderAll()
}
}
canvas._objects
には今までに書いた線がオブジェクトとして保存されているので、それを利用します。
Redo
useEffect(() => {
canvas?.on('object:added', () => {
if (!isRedoing) {
canvasHistory = []
}
isRedoing = false
})
}, [canvas])
const redo = () => {
if (canvas !== undefined && canvasHistory.length > 0) {
isRedoing = true
canvas.add(canvasHistory.pop()!)
}
}
canvas.add
を使って、Undo した線をもとに戻します。
add(...object) → {self}
Adds objects to collection, Canvas or Group, then renders canvas (ifrenderOnAddRemove
is notfalse
). in case of Group no changes to bounding box are made. Objects should be instances of (or inherit from) fabric.Object Use of this function is highly discouraged for groups. you can add a bunch of objects with the add method but then you NEED to run a addWithUpdate call for the Group class or position/bbox will be wrong.
Parameters:
Name Type Attributes Description object fabric.Object < repeatable > Zero or more fabric instances Returns:
thisArg
Type: Self
また、object:added
で線を書くイベントを取得することができます。
Object related
- object:added — fired after object has been added
https://github.com/fabricjs/fabric.js/wiki/Working-with-events
Clear
const clear = () => {
if (canvas !== undefined) {
canvas.clear()
canvasHistory = []
canvas.setBackgroundImage(bgImageUrl, () => canvas.renderAll())
}
}
canvas.clear()
でキャンバスを初期化します。
clear() → {fabric.Canvas}
Clears all contexts (background, main, top) of an instance
Returns:
thisArg
Type: fabric.Canvas
また、デモでは使っていませんが canvas.setBackgroundImage()
でキャンバスに背景画像を設定することができます。
setBackgroundImage(image, callback, optionsopt) → {fabric.Canvas}
Sets background image for this canvas
Parameters:
Name Type Attributes Description image fabric.Image or String fabric.Image instance or URL of an image to set background to callback function Callback to invoke when image is loaded and set as background options Object < optional > Optional options to set for the background image. Returns:
thisArg
Type: fabric.Canvashttp://fabricjs.com/docs/fabric.Canvas.html#setBackgroundImage
線の色の変更
useEffect(() => {
if (canvas !== undefined) {
canvas.freeDrawingBrush.color = selectColor
}
}, [canvas, selectColor])
canvas.freeDrawingBrush.color
の値を変更することで、線の色を変えることができます。
color :String
Color of a brush
Type:
- String
線の太さの変更
useEffect(() => {
if (canvas !== undefined) {
canvas.freeDrawingBrush.width = brushwidth
}
}, [canvas, brushwidth])
canvas.freeDrawingBrush.width
の値を変更することで、線の太さを変えることができます。
width :Number
Width of a brush, has to be a Number, no string literals
Type:
- Number
おわりに
Fabric.js を使えば、お絵かきが簡単に実装できます。
他にも、キャンバスのオブジェクトを JSON でエクスポートしたり、逆にインポートができたりします。
明日は、西園寺やきしゃもさんの「C言語におけるポインタの文法について」です!