canvasを組み込んだwebサービスを作る機会があり、その際に利用したreact-konvaが使いやすかったので紹介です。
今回はreact-konvaとhookを利用して簡単なお絵描き機能を作っていきます。
以下のような感じです。
https://codesandbox.io/s/elastic-agnesi-pn76b
#react-konvaとは
canvasのjsフレームワークkonva.jsを名前の通りreactで利用できるものです。
konva.jsのオブジェクトクラスがコンポーネントとして提供されています。
####konva.js
https://konvajs.org/docs/overview.html
react-konvaはStageというコンポーネントを土台に、その上にいろいろな要素を載せて実装を進めていきます。
例えば、LayerコンポーネントをStage上に複数載せることで、絵を描くときにあると嬉しいレイヤー機能を簡単に実装することができます。
イメージとして以下のようなコンポーネント階層を作っていきます(公式より抜粋)
hookを使った実装ではstateにオブジェクト要素を詰め込んでいき、その内容をcanvas上に描画していきます。
canvas上に絵を描くという目的を達成するために必要な処理は大まかに以下です。
①mouseDownなどのeventに反応してstateに線の描画位置や色設定などを詰め込んでいく。
②Layerコンポーネント内でstateの値を走査し、オブジェクトを描画していく。
canvasの描画内容をstateで管理できるため、すごく楽に実装を進められます。
実装イメージ(いろいろ省いて抜粋)
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)が使いやすく驚きました。