Kanazawa.js meetup #1 LT発表
OGP画像を⽣成するNode.jsの ライブラリを作ってみたKentaro MatsushitaKanazawa.js meetup #12020/01/19
View Slide
⾃⼰紹介⾦沢市内のゲーム会社で働くフロントエンドエンジニアゲームプラットフォームのリプレイス開発に従事Kentaro Matsushitakentaro-m _kentaro_m
Node.jsでOGP画像の動的⽣成にチャレンジした話をします今⽇のトピック
⽬次• OGP画像とは• Node.jsでOGP画像⽣成• 作成したライブラリ紹介• 画像⽣成の仕組み• 実装ハマりポイント• さいごに
OGP画像とは• Open Graph Protocol (OGP)• SNSにWebサイトをシェアしたときにタイトルや概要、サムネイルなどのWebサイト情報を正しく伝えるための標準規格• OGP画像• SNSでWebサイトをシェアしたときにタイムラインに表⽰される画像• フォロワーの⽬を引いて、Webサイトを⾒てもらうのが⽬的で設定
これがOGP画像です
OGP画像のもやもや• 画像が設定されてない場合、寂しい⾒た⽬になる• 画像を毎回作成するのは⾯倒
OGP画像の動的⽣成が増えている• 記事タイトルや作者名から動的に画像を⽣成する事例が増加• Qiitaやはてなブログ、dev.toなどがサポートしている• 画像配信CDNの画像へのテキスト追加機能やサーバーサイドの画像処理の仕組みで実現• 記事の作成者はOGP画像作成の考慮する必要がない• SNSにシェアしたときに統⼀感のある⾒た⽬になる
Node.jsで動的に画像⽣成する ライブラリを作った⾃分の課題解決のために
作例
できること• 記事タイトルと作者名を含んだ画像⽣成• 各種カスタマイズ機能• テキスト周囲のパディング指定• 出⼒画像サイズの指定• 背景⾊や背景画像の指定、作者のアイコン指定• 任意のフォントの使⽤、フォントサイズやフォントカラーの指定• タイムアウト設定
画像⽣成の仕組み
Node.jsで動的に画像⽣成する• ブラウザで処理するならCanvas APIで実現できそう• JavaScriptとHTMLのCanvas要素を使⽤し、ブラウザ上で図を描画を⾏うHTML5の機能• GatsbyJSのビルド時に画像⽣成したいので、サーバーサイドで動かしたい• node-canvasというNode.jsモジュールがある• Canvas APIの機能がサーバーサイドでも利⽤できる
node-canvasを簡単に触ってみる
正⽅形を描画するコード例• 描画したい位置の座標と図形の⼤きさを指定する
テキストを描画するコード例• 描画したい位置の座標とテキストを指定する
⻑⽅形とテキストの描画を組み合わせて画像を⽣成を実現
実装ハマりポイント
テキスト描画は座標計算との戦い
テキスト描画は座標計算との戦い• キャンバスサイズに収まるようにテキスト配置が必要• ⾏間やフォントサイズの調整やテキストの折返しなどを ⾏う場合は描画位置の座標計算が必要• CSSのありがたみをすごく感じる• レイアウトの柔軟性は乏しい• テキストや画像の配置を柔軟に変えることは難しい
テキスト描画は座標計算との戦い• こんにちは。こんばんは。を描画した例• キャンバスが400px、フォントサイズが48pxの 場合、幅は8⽂字しか⼊らない• テキストを”こんにちは。こん”と”ばんは。”に わけて、2⾏に分割して描画する必要がある• measureText(text)を使⽤することで、引数に渡したテキストを描画する際の幅や⾼さが分かる• 使⽤したフォントやフォントサイズによって、異なる計算結果が出る
停⽌しないタイムアウト処理
タイムアウト処理を追加• 記事タイトルやフォントサイズはユーザー指定で⼊⼒する• テキストの⻑さやフォントサイズの値が⼤きい場合は計算に時間がかかることもある• ⼀定時間内に処理が終了しない場合にタイムアウトエラーをthrowするようにした• タイムアウト制御をPromise.race()で⾏うようにした• タイムアウトの時間はユーザー指定可能
停⽌しないタイムアウト処理• Promise.race() は複数のPromise関数を実⾏して、最初に成功か失敗したPromise関数の結果を得る• 画像⽣成関数の成功かタイムアウト関数の失敗のいずれかの結果を得て、処理を終了したい
停⽌しないタイムアウト処理• ⾃分の書いたコードは画像⽣成関数もタイムアウト関数も双⽅とも最後まで処理された• 本来であれば、⼀⽅の関数の結果が返却されたら、もう⼀⽅は停⽌してほしい• Promise.race()は最初に成功か失敗したPromise関数の結果を得たあとに、他のPromise関数の停⽌は保証されない• つまり⾃分でもう⼀⽅の関数の処理を⽌める必要がある
正常なタイムアウト処理
今後の展望• ライブラリをnpmに公開する• ライブラリを使って、GatsbyJSのプラグインを作りたい• Kanazawa.jsのコミュニティページで動作させる
さいごに• OGP画像の動的⽣成について紹介しました• 画像⽣成が⾃動化されて、楽をすることできた• OGP画像を⼿っ取り早く作成するにはCDN利⽤が良いと思う• カスタマイズ性を求めるならサーバーサイドでやるのもあり• ソースコードはGitHubに公開しているので、興味がある⽅はご覧ください• kentaro-m/generate-og-image