🖊️

React + fabric.jsで手書き表現

2021/04/04に公開

fabric.js を React 環境下で使う機会があったので、開発手順をまとめます。

作ったもの

手書きできます

文字の色・太さを変えられます

その他、ダウンロードもできます(デモでは動きません)。

デモ

状態管理について

状態管理にはunstated-nextと useReducer を利用しました。

キャンバスの初期化

fabric.js では、提供される変数 fabric のプロパティとして、いくつかのクラスを利用できます。今回は fabric.Canvas を利用し、コンストラクタには紐づける canvas 要素の ID を指定します。canvas 要素が先に必要なので、useEffect を利用して最初のレンダリング後にクラスを作成します。コンストラクタには canvas 要素自体を指定することもできるので、ID を割り振らず、useRef を使ってもいいかもしれません。

import { fabric } from "fabric";

const CANVAS_ID = "canvas";

const Component: VFC<Props> = memo(({ className, dispatch }) => {
  useEffect(() => {
    // キャンバスの初期化処理
    const initCanvas = new fabric.Canvas(CANVAS_ID, {
      isDrawingMode: true, // 手書きモード
      width: 800,
      height: 300,
      backgroundColor: "#80beaf",
    });

    // クラスをそのまま格納
    dispatch({ type: "init", canvas: initCanvas });
  }, []);

  // canvas要素に紐づけ
  return (
    <div className={className}>
      <canvas id={CANVAS_ID} />
    </div>
  );
});

手書きを実現するために最低限必要な設定はこれだけです。手書き用のキャンバス作成後、ペンの設定を変更したり、状態をクリアするために作成した fabric.Canvas クラスをそのまま状態として保存しておきます。

手書きするペンの設定

fabric.Canvas クラスの手書きモードを有効にした場合、描画されるペンの設定は freeDrawingBrush 以下のプロパティを変更することで可能です。

詳細な設定は、fabric.js 公式のデモが分かりやすいと思います。

state.canvas.freeDrawingBrush.color = "#fff";
state.canvas.freeDrawingBrush.width = 800;

書き込んだ内容をクリア

case "clear": {
  if (!state.canvas) {
    return state;
  }
  // クリア
  state.canvas.clear();
  // 背景情報もクリアされるので、再定義
  state.canvas.backgroundColor = "#80beaf";
  // 背景に画像を設定する場合は、読み込み後に再レンダリング
  state.canvas.setBackgroundImage(url, () => state.canvas!.renderAll());
  return state;
}

Discussion