Slide 1

Slide 1 text

OGP画像を⽣成するNode.jsの
 ライブラリを作ってみた Kentaro Matsushita Kanazawa.js meetup #1 2020/01/19

Slide 2

Slide 2 text

⾃⼰紹介 ⾦沢市内のゲーム会社で働くフロントエンドエンジニア ゲームプラットフォームのリプレイス開発に従事 Kentaro Matsushita kentaro-m _kentaro_m

Slide 3

Slide 3 text

Node.jsでOGP画像の動的⽣成に チャレンジした話をします 今⽇のトピック

Slide 4

Slide 4 text

⽬次 • OGP画像とは • Node.jsでOGP画像⽣成 • 作成したライブラリ紹介 • 画像⽣成の仕組み • 実装ハマりポイント • さいごに

Slide 5

Slide 5 text

OGP画像とは • Open Graph Protocol (OGP) • SNSにWebサイトをシェアしたときにタイトルや概要、サムネイルな どのWebサイト情報を正しく伝えるための標準規格 • OGP画像 • SNSでWebサイトをシェアしたときにタイムラインに表⽰される画像 • フォロワーの⽬を引いて、Webサイトを⾒てもらうのが⽬的で設定

Slide 6

Slide 6 text

これがOGP画像です

Slide 7

Slide 7 text

OGP画像のもやもや • 画像が設定されてない場合、寂しい⾒た⽬になる • 画像を毎回作成するのは⾯倒

Slide 8

Slide 8 text

OGP画像の動的⽣成が増えている • 記事タイトルや作者名から動的に画像を⽣成する事例が増加 • Qiitaやはてなブログ、dev.toなどがサポートしている • 画像配信CDNの画像へのテキスト追加機能やサーバーサイドの 画像処理の仕組みで実現 • 記事の作成者はOGP画像作成の考慮する必要がない • SNSにシェアしたときに統⼀感のある⾒た⽬になる

Slide 9

Slide 9 text

Node.jsで動的に画像⽣成する
 ライブラリを作った ⾃分の課題解決のために

Slide 10

Slide 10 text

作例

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

できること • 記事タイトルと作者名を含んだ画像⽣成 • 各種カスタマイズ機能 • テキスト周囲のパディング指定 • 出⼒画像サイズの指定 • 背景⾊や背景画像の指定、作者のアイコン指定 • 任意のフォントの使⽤、フォントサイズやフォントカラーの指定 • タイムアウト設定

Slide 14

Slide 14 text

画像⽣成の仕組み

Slide 15

Slide 15 text

Node.jsで動的に画像⽣成する • ブラウザで処理するならCanvas APIで実現できそう • JavaScriptとHTMLのCanvas要素を使⽤し、ブラウザ上で図を描画を ⾏うHTML5の機能 • GatsbyJSのビルド時に画像⽣成したいので、サーバーサイドで動かし たい • node-canvasというNode.jsモジュールがある • Canvas APIの機能がサーバーサイドでも利⽤できる

Slide 16

Slide 16 text

node-canvasを簡単に触ってみる

Slide 17

Slide 17 text

正⽅形を描画するコード例 • 描画したい位置の座標と図形の⼤きさを指定する

Slide 18

Slide 18 text

テキストを描画するコード例 • 描画したい位置の座標とテキストを指定する

Slide 19

Slide 19 text

⻑⽅形とテキストの描画を 組み合わせて画像を⽣成を実現

Slide 20

Slide 20 text

実装ハマりポイント

Slide 21

Slide 21 text

テキスト描画は座標計算との戦い

Slide 22

Slide 22 text

テキスト描画は座標計算との戦い • キャンバスサイズに収まるようにテキスト配置が必要 • ⾏間やフォントサイズの調整やテキストの折返しなどを
 ⾏う場合は描画位置の座標計算が必要 • CSSのありがたみをすごく感じる • レイアウトの柔軟性は乏しい • テキストや画像の配置を柔軟に変えることは難しい

Slide 23

Slide 23 text

テキスト描画は座標計算との戦い • こんにちは。こんばんは。を描画した例 • キャンバスが400px、フォントサイズが48pxの
 場合、幅は8⽂字しか⼊らない • テキストを”こんにちは。こん”と”ばんは。”に
 わけて、2⾏に分割して描画する必要がある • measureText(text)を使⽤することで、引数に渡したテキストを描画す る際の幅や⾼さが分かる • 使⽤したフォントやフォントサイズによって、異なる計算結果が出る

Slide 24

Slide 24 text

停⽌しないタイムアウト処理

Slide 25

Slide 25 text

タイムアウト処理を追加 • 記事タイトルやフォントサイズはユーザー指定で⼊⼒する • テキストの⻑さやフォントサイズの値が⼤きい場合は計算に時間がか かることもある • ⼀定時間内に処理が終了しない場合にタイムアウトエラーを throwするようにした • タイムアウト制御をPromise.race()で⾏うようにした • タイムアウトの時間はユーザー指定可能

Slide 26

Slide 26 text

停⽌しないタイムアウト処理 • Promise.race() は複数のPromise関数を実⾏して、最初に成功 か失敗したPromise関数の結果を得る • 画像⽣成関数の成功かタイムアウト関数の失敗のいずれかの結果を得 て、処理を終了したい

Slide 27

Slide 27 text

停⽌しないタイムアウト処理

Slide 28

Slide 28 text

停⽌しないタイムアウト処理 • ⾃分の書いたコードは画像⽣成関数もタイムアウト関数も双⽅ とも最後まで処理された • 本来であれば、⼀⽅の関数の結果が返却されたら、もう⼀⽅は停⽌し てほしい • Promise.race()は最初に成功か失敗したPromise関数の結果を 得たあとに、他のPromise関数の停⽌は保証されない • つまり⾃分でもう⼀⽅の関数の処理を⽌める必要がある

Slide 29

Slide 29 text

正常なタイムアウト処理

Slide 30

Slide 30 text

今後の展望 • ライブラリをnpmに公開する • ライブラリを使って、GatsbyJSのプラグインを作りたい • Kanazawa.jsのコミュニティページで動作させる

Slide 31

Slide 31 text

さいごに • OGP画像の動的⽣成について紹介しました • 画像⽣成が⾃動化されて、楽をすることできた • OGP画像を⼿っ取り早く作成するにはCDN利⽤が良いと思う • カスタマイズ性を求めるならサーバーサイドでやるのもあり • ソースコードはGitHubに公開しているので、興味がある⽅はご 覧ください • kentaro-m/generate-og-image