回想
子どもの頃、ちゃんとパソコンを触ったのは、小学校の授業で「一太郎スマイル」を使って絵を描いたことでした。
https://pc.watch.impress.co.jp/docs/article/990118/just.htm
Canvas API でも絵を描くことができます。 アプローチ方法は異なりますが、「二次元の空間に、自分が表現したいと思うものを描く」という点では「一太郎スマイル」での体験も Canvas API での体験も同じです。
Canvas API を使えば、あの頃の体験を蘇らせることができます。
この記事の目的
Canvas APIでの描画速度を高めてくれる便利ハックや方法をご紹介します。
Canvas APIでは、描きたいものが複雑だったり、細かくなるほど、相応に手間がかかりがちかと思います。
3つほど方法をご紹介し、Canvas APIでこれから何かを描画しようとしている方、今後いつか描画するかもしれない方の力になれば幸いです。
クリックした位置の座標を表示させる
Canvas のDOM要素は、左上を基点として座標で位置を取得できるようになっています。
それを利用し、クリックした位置を画面に表示させます。
そうすることで、描きたい線の距離や位置を捉えやすくなり、描画速度が高まります。
Reactでは、以下のような関数を <Canvas />
タグに噛ませることで座標を取得できます。
const handleCoordinate = (
e: React.MouseEvent<HTMLCanvasElement, MouseEvent>
) => {
const rect = e.target.getBoundingClientRect();
const x = parseInt(`${e.clientX - rect.left}`);
const y = parseInt(`${e.clientY - rect.top}`);
setCordinateX(x); // useState_1
setCordinateY(y); // useState_2
};
座標数値をコピーできるようにする
前項で表示させた座標(x,y)を、区切りのカンマごとコピーできるようにします。
const handleCopy = (coordinate: string) => {
// coordinate = 442,65
navigator.clipboard.writeText(value);
};
こうすることで、コピーした値を、そのまま moveTo()
メソッド や lineTo()
メソッドの引数に貼り付けることができ、描きたい線の始点や終点などを簡単に捉えられるようになります。
backgroundImageで、ベース画像を差し込む
stylesのbackgroundImage属性を用いて、描きたい対象の、元データとなる画像をCanvasに予め差し込んでおきます。
※縦横のサイズ調整は必要です。
<canvas
width={800}
height={680}
id={"canvas"}
style={{
border: "solid 1px #383838",
background: "#e9e9e9",
backgroundImage: `url(${"/kduck.png"})`, // 描きたい対象の元画像を設定
backgroundRepeat: "no-repeat",
backgroundPosition: "100px",
}}
onClick={(e) => handleCoordinate(e)}
/>
こうすることで、Canvas APIによる、以下の赤線のような描画が可能になります。
ほとんど元のコダックの画像と同じ距離、曲がり具合を再現できているかと思います。
キュートなお腹の曲がり具合を完全に手中に収めました。
さらに前項まででご紹介した①座標を表示する機能と②座標のコピー機能と掛け合わせることで、座標の位置を正確かつ(比較的)迅速に取得し、描きたい元データにより忠実に描くことを可能にしてくれるかと思います。
(もっと良い方法あれば、ぜひコメント欄で教えてください)
まとめ
ポイントは以下です。
①クリックした位置の座標を表示させることで、相対的に線の位置を決められるようになる
②表示した座標の数値をコピーできるようにすることで、Canvas APIの各メソッドの引数に値を渡しやすくする
③backgroundImageで元データとなる画像を挿入し、その上に描画を施していくことで描画の精度を上げる
①・②・③を組み合わせることで、ちょっと複雑な絵なども、効率的に描画できるようになるかと思います。