ひらがな練習プリントを作れるサービスを公開したよ

Pocket

好きな言葉でひらがなの練習ができるプリントが作れるサービス「ひらがなプリントメーカー(仮)」を公開した。今後カタカナにも対応したり、文字練習以外の教材の生成ができるようにすることもぼんやり考えているので、名前は変わるかもしれない。

(2019年01月11日追記) 0〜9の数字にも対応したので「かきかたプリントメーカー」に改名した。さらにカタカナもサポートした。

紙の向きや縦書き横書き、文字サイズが切り替えられるようになっている。書き順もつけることができるので、数字をおぼえた子ならひとりでもできる。

PDFファイルを生成するので、そのまま自宅やコンビニのプリンタできれいに印刷できる。スマホでぽちぽち作って帰り道にコンビニで印刷してお土産に持って帰るなんてこともできる。

もともとうちの3歳の娘のために作ったのだが、これはけっこう需要があるだろうということで真面目に作り込んで公開した。

市販の子供用ドリルは、画数の少ない文字や字形のシンプルな文字から少しずつ練習できるようにできている。それはそれでよいのだが、子供は、そういう順番をすっ飛ばして何かのきっかけで「難しい」とされる文字から興味を示したりするものだ。好きな言葉や自分の名前は早く書きたいだろう。「『しか』や『とり』はどうでもいいから新幹線の名前を書かせろぉぉぉぉ!!!」っていう子だっているはず。うちの娘も、プリキュアで「えみるちゃんの『え』」を覚えたし、銭湯や温泉が大好きなので「ゆ」の字も気に入っているらしい。

ひとりひとりのレベルや興味に合った教材で、退屈したりつまづいたりすることなく楽しく文字をおぼえてもらえると嬉しい。

開発

ここからは開発の話。色々工夫した点や技術的なメモなど。

フォントの選定

たとえば「さ」という文字は本来3画なのだが、世の中の日本語フォントの多くは2画目と3画目がつながっている。大人はどんなフォントでも読めるし、多少の崩し字も読み書きできるが、子供はできるだけ「学校で習うような書き方」でスタートしたほうがいいだろう。たとえば教科書体などは非常にそれに近いのだが、ちょっと細っこいのが難点。子供はどうしても線がブレるし、ちょっと枠から線がはみ出してしまっただけでも「失敗した」と思ってしょんぼりしまうこともあるので、ほどほどに幅のある枠を用意してのびのびと練習できるようにしたい。

そんなわけで今回選定したのがIPA Pゴシックである。ほどほどに幅があり、字形も初学者向きで、しかも改変・再配布もOKなライセンスになっている。

字形を調整

それでもごく一部「学校で習うような書き方」と若干異なる文字もあるので、そこは手作業で改変してある。たとえば、手で文字を書くときに濁点は本来文字の右上にちょぼちょぼと打つが、多くのフォントの「で」の字は「て」の右の弧の中に濁点がおさまっている。そういうところは手で調整した。

矢印と書き順は手作業

矢印や数字はPhotoshopで手作業で書き込んでいる。手作業というと大変そうだが、全文字で1時間くらいでできた。レイヤー構成は同じにしておいて、後から矢印・書き順レイヤーのオン/オフを切り替えたりサイズを縮小したりしながらバッチ処理で画像を一気に吐き出す。

最初は印刷用CSSで

最初は、家庭内でとりあえず使うため、印刷用のCSSを用意し、HTMLをそのままブラウザの機能で「印刷」すれば欲しいものが出てくるというきわめて単純なものを作った。しかし、一般向けに公開するとなるとどうしても一部ブラウザで崩れたりする。できればPCやプリンタがない環境でも綺麗に印刷できるようにしたい。よーしママPDF生成しちゃうぞー。

ブラウザ上で生成

PDF生成もなるべくクライアントサイドで完結させたい。サーバ側を用意するのは少々めんどくさい。「自分や家族の名前を書く練習をする」という用途も多いだろうから、そういう大切な情報の送受信は最低限にしたほうがお互い嬉しい。

これは、(PDFKit + blob-stream) * Browserify という構成で実現することができた。

PDFKitはNode.jsで使うケースが多いと思うけれど、Node.jsのモジュールを (できる範囲で) ブラウザ向けにする Browserify をかますとなんとブラウザ上でも動いてくれる。
こちらがブラウザ上でPDFを生成するデモ。

PDFKit Browser Demo

PDFKitで生成したPDFのデータはblob-streamにパイプしてblob化するとブラウザに渡し、PDFファイルとして開かせることができる。

ブラウザ上でPDFKitを使って画像を貼るコツ

PDFKitで画像を貼り込むには、ちょいとコツがいる。Node.jsで動かす場合は

doc.image('hoge.png', 15, 15, width: 300);

という感じでファイルシステム上からとってきてさくっと貼っちゃったりできるが、ブラウザ上の場合は少し工夫がいる。

let canvas = document.getElementById("canvas"); // canvas tag
let ctx = canvas.getContext("2d");
let img = document.getElementById("image"); // image tag
doc.image(canvas.toDataURL('image/png'), x, y, { width:w, height:h });

こんな具合に

  • imgタグに画像をロード
  • その画像をcanvasにdrawImageでぺたっと描く
  • canvasからtoDataURLでデータURLに変換
  • PDFKitに渡す

というのが実装の一例。

今回のケースでは、プレビュー画面内のimgタグにすでに画像がロードされた状態でPDFを吐くことを想定しているが、まだロードされていない画像を新たに取ってきて貼り付けたい場合などはonloadのタイミングで実行するなど必要がある。

ちなみにクロスドメインで呼び出した画像貼ったcanvasでtoDataURL すると

Uncaught DOMException: Failed to execute ‘toDataURL’ on ‘HTMLCanvasElement’: Tainted canvases may not be exported.

という具合に怒られる。これはローカルのファイルをブラウザでそのまんま開いた場合にも発生する。開発時はさくっと手元でHTTPサーバを立ててテストするのが吉。

Pocket

1件のコメント

ただいまコメントは受け付けていません。