手書きして保存する
指・ペン・マウスのどれでも描けます。 描いた絵はこの端末から出ません(送りも保存もしていないので、 ページを離れると消えます)。
消しゴムはなぞった線を1本まるごと消します。線の途中だけを消せないのは、 絵を点ではなく線で持っているからです。まちがえても「1つ取り消す」で戻せます。
まだ1本も描いていません。四角の中を指かマウスでなぞるか、数を入れて線を足してください。
同じ絵を、2つの形で保存できます
- PNG(点の絵)
- 560 × 420 = 235,200 個の粒線が0本でも235,200個です。粒の数は描いた量と関係なく決まっていて、拡大するとこの粒が四角く見えます。
- SVG(線の記録)
- 線 0 本・通った場所 0 個 = 157 バイト描いた量そのものが大きさになります。粒ではなく道順なので、 何倍に拡大しても線のふちは粗くなりません。
- この画面の粒の細かさ
- 測っています…canvas の実体をこの倍率で作り、
ctx.scaleで戻しています。 掛け忘れると、少ない粒で描いた絵を引き伸ばすことになり、線がぼやけます。 - 外に取りに行くもの
- 0個(1ファイルだけで開けます)書き出した SVG に、画像・外のスタイル・字体など外を見に行くものが混ざっていないかを、その場で数えています。
いま保存される SVG の中身
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 280 210" width="280" height="210"> <rect x="0" y="0" width="280" height="210" fill="#ffffff"/> </svg>
これが線の記録そのものです。Mが「ここから」、Lが「ここまで線を引く」。 数字は絵の中の座標で、画面の大きさとは関係ありません。 だからどんな大きさで開いても同じ絵になります。
よくある質問
描いた絵は、どこかに送られますか?
送りません。線の座標も、保存するPNGもSVGも、すべてこのページの中で作っています。通信は1回も起きませんし、保存先はあなたの端末の中だけです。ページを閉じれば描いたものは消えるので、続きを描きたいときは保存してから閉じてください。
PNGとSVGは、どちらで保存すればいいですか?
写真と混ぜたいときや、絵をそのまま貼りたいときはPNGです。あとから大きく引き伸ばす予定があるとき、印刷したいとき、線の色や太さを直したいときはSVGです。SVGは絵ではなく「どこからどこへ線を引くか」という指示書なので、何倍に拡大しても線のふちが粗くなりません。迷ったら両方保存しておけます。
どうして線の途中だけを消せないのですか?
このページが絵を「粒の色」ではなく「線の記録」で持っているからです。記録にあるのは1本ずつの線なので、消しゴムは線を1本まるごと取り除きます。かわりに、消した線は「1つ取り消す」でそのまま戻ってきます。粒で持っていると逆になり、途中だけ白く塗れますが、塗ったものは二度と戻せません。
取り消しは何回までできますか?
描き始めたところまで、何回でも戻れます。描いた線だけでなく、消しゴムで消した線も、「全部消す」で消した絵も戻せます。記録に「何をしたか」が順に残っているためで、消したものも取ってあるからです。ただしページを閉じると記録ごと消えます。
線がぼやけて見えるのはなぜですか?
canvasの粒の数が、画面の粒の数より少ないと起きます。いまの画面はCSSの1ピクセルを2個や3個の粒で描いていることが多く、canvasを見た目の大きさと同じ数で作ると、少ない絵を引き伸ばすことになります。このページはピクセル比を掛けた数でcanvasを作り、描くときに同じ数で割り戻しています。上の欄に、あなたの画面の倍率が出ています。
保存したSVGは何で開けますか?
ブラウザの窓にファイルを落とせば、そのまま絵として開きます。中身は文字なので、テキストエディタで開いて数字を書き換えることもできます。外の画像や字体を1つも参照していない1枚のファイルなので、線がないのに何かが読み込まれる、ということは起こりません。
指・ペン・マウスで手書きして、PNGとSVGの両方で保存できます。1本ずつ取り消せるのは、絵を「点の集まり」ではなく「線の記録」で持っているからです。
canvasに描いた瞬間、絵は「粒の集まり」になります
ここがこのページの本体です。ブラウザで絵を描く場所をcanvas(キャンバス)といいます。 決まりを作っているWHATWGは、canvasをこう説明しています ──「解像度に依存する、ビットマップの画布」。ビットマップというのは「小さな四角い粒を並べて絵にしたもの」のことです。
つまりcanvasに線を引いた瞬間、その線は「この粒は青、となりの粒はうすい青、その次は白」という色の一覧になります。 引いたのが線だったという事実は、どこにも残りません。
だから、あとから「さっきの1本だけ消したい」と言っても、もう手遅れです。 どの粒がその線のものだったのかを、canvasは覚えていないからです。 線が交わっているところは、もっと分かりません。同じ理由で、あとからSVGにすることもできません。線の通り道を知らないものが、線の通り道を書けるはずがないからです。
だから、絵の本体を「線の記録」のほうに置きました
このページは、指が動いた場所を座標の列として覚えます。 1本の線は「何色で・どれだけ太くて・どこを通ったか」というただのデータです。 そしてcanvasは、それを描き直すだけの 面にします。 画面に見えているものは、記録の写しであって本体ではありません。
この順番を入れ替えると、できることが3つ増えます。どれも同じ1つの作りから出てきます。
- 1本ずつ取り消せる。記録は線の並びなので、最後の1本を外すだけです。 消しゴムで消した線も、どこにあった何本目かを覚えているので、元の重なり順のまま戻せます。
- SVGで書き出せる。「ここから、ここへ線を引く」をそのまま文字にすれば、それがSVGです。 上の欄にいま保存される中身が出ているので、描きながら文字が増えていくのが見られます。
- 画面の大きさが変わっても描き直せる。座標を画面のピクセルではなく、絵の中の目もり(よこ280・たて210)で持っているので、窓の幅を変えても、記録から描き直すだけで済みます。 粒で持っていたら、引き伸ばしてぼやけるところです。
指・ペン・マウスのどれでも同じように描けるのは、Pointer eventsという受け取り方を使っているからです。 その決まり自体の話は画面のどこをさわったかのページにあります。
PNGは「粒の絵」、SVGは「道順の書き置き」です
同じ絵を2つの形で保存できるようにしたのは、違いを自分の目で見てもらうためです。
PNGは粒の絵です。このページが保存するPNGはよこ560・たて420の粒でできていて、その数は線を1本も描いていなくても同じです。 絵の中身ではなく、面積で決まるからです。 大きく引き伸ばすと、粒そのものが四角く見えてきます。
SVGは道順の書き置きです。中身は「M(ここから)」「L(ここまで線を引く)」という短い指示の並びで、 大きさは描いた量そのものになります。 線が1本なら数十バイト、 たくさん描けばそのぶん増えます。粒が1つも書かれていないので、拡大しても粗くなりようがありません。 開いた大きさに合わせて、その場で線が引き直されるからです。
絵の中の座標をまとめているviewBoxの読み方や、四角や丸を数字で組んでSVGを作る道具は、図形を描いてSVGで書き出すのほうにあります。
点をひとつ打っただけの線は、端がまるいときだけ点になります
画面をちょんと1回だけ押したときの話です。 このとき記録に残る線は、 通った場所が1つだけ。つまり長さが0の線です。
長さが0のものをどう描くのか、W3Cの決まりはちゃんと書いています。線の端の形(stroke-linecap)によって、答えが変わります。
- 端がまるい(
round)とき ──「その線は、その点を中心とした完全な円だけになる」。 つまりまるい点が描かれます。 - 端が四角い(
square)とき ── 線の太さと同じ辺の正方形が描かれます。 - 端を伸ばさない(
butt)とき ──「長さ0の線は、したがって何も描かれない」。 押したのに、何も出ません。
このページが線の端をまるくしているのは、見た目の好みだけではありません。ちょんと押したときに点が出るかどうかが、ここで決まるからです。 ややこしいことに、canvasのほうは同じようにはいきません。長さ0の線を引いても何も描かれないので、点だけは丸として描き足しています。 SVGとcanvasで書き方が違うのに、見た目をそろえる必要があるところです。
線がぼやけるのは、粒の数を数えまちがえたときです
手書きの道具でいちばん多い困りごとが「線がぼやける」です。 原因はたいてい 1つで、canvasの粒の数が足りていないことです。
いまの画面の多くは、CSSの1ピクセルを2個や3個の粒で描いています。 canvasの決まりにも、「座標の広さは、ブラウザが内部で使う実際のビットマップの大きさとは限らない。高精細な画面では、座標1つあたり4個の端末ピクセルを内部で使うことがある」と書かれています。
ここで、canvasを見た目の大きさと同じ数で作ってしまうと、少ない粒で描いた絵を引き伸ばして表示することになります。 これがぼやけの正体です。 直し方はcanvasの実体をピクセル比の倍だけ大きく作り、描くときに同じ倍率で割り戻すこと。 上の欄に、あなたの画面の倍率が出ています。
CSSのピクセルと画面の粒が別物である話そのものは、画面の大きさとピクセル比のページで、 掛け算の式ごと確かめられます。
キーボードだけで使う人に、できることとできないこと
正直に書きます。手書きは、キーボードだけでは同じようにはできません。WCAGの達成基準2.1.1(キーボード)は、すべての機能をキーボードで操作できる ことを求めていますが、「利用者の動きの軌跡に依存し、始点と終点だけでは決まらない機能」を例外として除いています。 手書きの線はまさにその軌跡そのものなので、 この例外に当たります。
そのうえで、できることは全部キーボードでできるようにしてあります。 色と太さを選ぶ・消しゴムに持ち替える・1つ取り消す・全部消す・PNGで保存・SVGで保存は すべてボタンです。 さらに始点と終点を数で入れて線を1本足せる欄を付けました。 始点と終点だけで決まる線は軌跡ではないので、例外に頼る必要がありません。
canvasの中身は、読み上げソフトからは見えません。 決まりも「canvasを使うときは、そのビットマップと本質的に同じ役目を伝える中身を必ず用意しなければならない」と定めています。 だから、いま何本描かれていて記録が何個あるかを文字でも出しています。 選んでいる色や太さも色や見た目だけで示さず、「✓」と名前と太さの数を 並べています(WCAGの達成基準1.4.1)。
描いた絵は、お使いのブラウザの中だけで処理します
線の座標も、書き出したPNGもSVGも、全部この画面の中で作っています。通信は1回も起きません。保存を押したときも、送ってから返ってくるのではなく、ブラウザの中で組み立てた文字を、そのまま端末に書き出しているだけです。
そのかわり、ページを閉じると記録は消えます。 保存もしていないので、 続きを描きたいときはSVGで保存しておくのが確実です。 書き出したSVGには、外の画像も、外の字体も、外のスタイルも1つも入っていません。 上の欄で、外を見に行くものが何個混ざっているかをその場で数えています。 いつでも0個のはずです。
決まりの出どころは、canvasの説明(解像度に依存するビットマップの画布)・内部のビットマップの 大きさ・代わりの中身を用意する義務がWHATWG HTML Standard の canvas の章(新しいタブで開きます)、長さ0の線と端の形の関係がW3C の SVG 2(painting)(新しいタブで開きます)、キーボードと色の話がWCAG 2.2(新しいタブで開きます)(達成基準 2.1.1 と 1.4.1)です。 引用した文はすべて原文にあたって確かめました。