Help us understand the problem. What is going on with this article?

react-konvaでお絵描き

canvasを組み込んだwebサービスを作る機会があり、その際に利用したreact-konvaが使いやすかったので紹介です。

今回はreact-konvaとhookを利用して簡単なお絵描き機能を作っていきます。
以下のような感じです。
https://codesandbox.io/s/elastic-agnesi-pn76b
test.gif

react-konvaとは

canvasのjsフレームワークkonva.jsを名前の通りreactで利用できるものです。
konva.jsのオブジェクトクラスがコンポーネントとして提供されています。

konva.js

https://konvajs.org/docs/overview.html

react-konvaはStageというコンポーネントを土台に、その上にいろいろな要素を載せて実装を進めていきます。
例えば、LayerコンポーネントをStage上に複数載せることで、絵を描くときにあると嬉しいレイヤー機能を簡単に実装することができます。
イメージとして以下のようなコンポーネント階層を作っていきます(公式より抜粋)
スクリーンショット 2020-12-04 13.14.32.png

hookを使った実装ではstateにオブジェクト要素を詰め込んでいき、その内容をcanvas上に描画していきます。

canvas上に絵を描くという目的を達成するために必要な処理は大まかに以下です。
①mouseDownなどのeventに反応してstateに線の描画位置や色設定などを詰め込んでいく。
②Layerコンポーネント内でstateの値を走査し、オブジェクトを描画していく。

canvasの描画内容をstateで管理できるため、すごく楽に実装を進められます。

実装イメージ(いろいろ省いて抜粋)

sample.js
const App = () => {
  const [lines, setLines] = React.useState([]);
  const handleMouseDown = (e) => {
    const pos = e.target.getStage().getPointerPosition();
      // mouseDownなどのeventに反応してstateに値(線の描画位置や色設定など)を詰め込んでいきます。
      setLines([...lines,{points: [pos.x, pos.y], color, size}
    ]);
  };

  return (
    <>
       <Stage
         onMouseDown={handleMouseDown}
       >
          <Layer>
            {/* stateを走査して詰め込んだ値を描画していきます。 */}
            {lines.map((line, i) => (
              <Line
                key={i}
                points={line.points}
                stroke={line.color}
                strokeWidth={line.size}
                tension={0.5}
                lineCap="round"
              />
            ))}
          </Layer>
        </Stage>
      </>
  );
};
export default App;

最後に

業務はサーバーAPI構築がメインのためReactの勉強がてらと思いreact-konvaを選んだのですが、webは技術進歩が目覚ましく、すぐに置いていかれてしまいますね、、

(記事の内容と直接関係ないのですが)特に今では当たり前のように使われているオンラインエディター(今回はCodeSandbox)が使いやすく驚きました。

link-u
サーバープラットフォーム事業 現在はマンガサービスをメインに開発・運営をしております。
https://www.link-u.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away