2018 05 18

電光掲示板を作るの1

先日、高幡不動参道の駄目電光掲示板を見てたら自分でも作ってみたくなったので、それっぽいものを作ってみる。

まずは仕様の検討。

どんなものを作るか。
入力した文字列を電光掲示板風の文字に変換して動かす。
電光掲示板風とは?
本物の電光掲示板は、方眼に並んだ電球やLEDなどの自発光デバイスが画素となって文字を構成している。 それを模擬して、方眼に並んだ小さな円で文字を構成する。
どうやって変換する?
HTML5で導入されたcanvasならピクセル毎に色の情報が取れたはず。 これを使う。 まず文字をcanvasに書き、その結果を方眼状にサンプリングしてやればいいだろう。
どうやって動かす?
サンプリング結果を適用する位置をずらす。 駅の電光掲示板のように動きを一方向に限定するなら、画素を敷き詰めた領域そのものを画素サイズ単位で移動してもいいだろう。

細かいことは作りながら考えるとして、まずはcanvasに文字を書いてみよう。

上のテキストボックスに何か入力して適用ボタンをクリックすると、下のキャンバスに文字を描画する。

ソースは以下の通り。

<input type="text" id="t1" size="30" maxlength="30" value="高幡不動" /> <input type="button" value="適用" onclick="apply1()"/> <canvas id="c1" width="400" height="100" style="border:1px solid black;"></canvas> <script> function apply1() { const ct1 = document.getElementById("c1").getContext("2d"); ct1.clearRect( 0, 0, 400, 100 ); ct1.font = "80px sans-serif"; ct1.fillStyle = "red"; ct1.fillText( document.getElementById("t1").value, 0, 80 ); } </script>

描画領域を一旦クリアし、フォントと色を設定してから文字を描いている。

で、実際に描画した結果を見ると、文字がうっすら縁取りされていた。 そうならないように strokeText ではなく fillText を使っているのだが。 環境に依存するのかと、Mac と Windows の両方でいろんなブラウザで表示してみたが、どれも同じ結果だった。 なぜ?

縁取られている部分をもっとよく見てみようと拡大してみたら、なんかアンチエイリアスっぽい。 でもここで使っているのは地の白と文字の赤だけ。 中間をどう取っても黒にはならないよな。

納得いかないので、実際の縁取り部分にどんな色が設定されているのか調べてみることにした。 といっても縁取り部分の正確な座票は解らないので、上の描画処理の中に、上から50ピクセルの位置で左端から横に50ピクセルほど各ピクセルの情報を表示する処理を埋め込んでみた。

for ( let y = 0; y < 50; y++ ) { console.log( ct1.getImageData( 50, y, 1, 1 ).data ); }

getImageData が返すオブジェクト内の属性 data は配列になっていて、先頭から(R,G,B,a,...)と値が入っている。

出力の結果、地の部分は全て (0,0,0,0) だった。 これが地から文字に入るところでは (0,0,0,0) → (220,0,0,140) → (255,0,0,255) と、逆に文字から地に出るところでは (255,0,0,255) → (201,0,0,95) → (0,0,0,0) と変化していた。

一見白の地の部分は、実は透明な黒だった。 黒なんてどこにも無いじゃないかと思っていたが、無いのは白の方だった。 キャンバスの背後の白がそのまま透けて見えているだけ。 黒い縁取りは、キャンバスの地の黒と文字との中間階調を作ろうとした結果なんだろう。

ここまで来てようやく 「あれ? そういえば何年か前にフラクタルの描画にキャンバスを使った時にも同じことを調べたような…」 と思い出した。 なんかどっと疲れたので、続きはまた明日。

+

西城秀樹が死んだ。 享年63歳。 晩年は脳梗塞との戦いだったらしい。