SVGを使って画像ジェネレーター的なものを作ったよという話

この記事はTech KAYAC Advent Calendar 2020 10日目の記事です。

こんにちは。技術部新卒フロントエンドエンジニアの熊谷です。ふだんはNuxt.jsやTypeScriptを書いてWebサービスを開発しています。 今回は、業務内容からちょっと離れたフロントエンドについての内容として、SVGを用いた表現について紹介してみます。

※この記事は「どうやるか」に的を絞ったゆるい感じを想定しています。登場する作ったアプリは全て個人で開発したものです。

SVGとはなにか

Scalable Vector Graphicsの略で、MDNでは以下のように説明されています。

二次元ベースのベクター形式のための XML に基づくマークアップ言語です。そのため、どんな大きさでもきれいにレンダリングできる画像を記述するためのテキストベースのオープンなウェブ標準であり、特に他のウェブ標準、例えば CSS, DOM, JavaScript, SMIL などとうまく機能するように設計されています。 SVG は本質的に、グラフィックに対するもので、テキストに対する HTML のような位置づけです。

developer.mozilla.org

デザインツールから出力されるベクタ画像としての馴染みが深いかもしれません。HTML上に図表を描く手法としてはCSSやcanvasによるものが一般的ですが、今回はSVGを直接扱おう、という趣旨になります。 SVGを用いる最大の利点としては、DOMのように宣言的に扱えることが挙げられます。HTML+CSSと同じような書き味で表現でき、Vue.jsやReactのようなリアクティブで組み合わせ可能なコンポーネントを扱うフレームワークとの相性もよいです。

具体的にSVGで図形を描画する方法については割愛します。「SVG 図形」などで検索して見つかる記事や、SVGの仕様を参照いただければと思います。

triple-underscore.github.io

Vue.jsでSVGを扱う方法についても割愛します(特筆することは無いと思っています)。手前味噌ですが、過去に個人で作成した「黄金比に基づいたクマのアイコンを生成するアプリ」が素朴な実装をしているので、分かりやすいかもしれません。Vue CLIで作成したVue 2のプロジェクトをベースに作成しています。 github.com

f:id:spdbear:20201210100805p:plain
スライダーを動かしてSVGをリアクティブにいじっています

SVGならではの表現にチャレンジ - 袋文字を作る

ここでは、SVGだからこそ実現できるような表現を書いていきます。複数書く予定でしたが時間が押してしまったのもあり、1つです🙇‍♂️ 袋文字とは、輪郭線が適用された文字をいいます。SVGではstroke属性を編集することで輪郭線が描画されるため、これを使うことで実現できます。 さらに、stroke を変化させた要素を複数重ねることで、テロップのような複雑な袋文字を実現できます。

See the Pen Multipie Outline Text by spdbear (@spdbear) on CodePen.

この例では愚直に要素を複数回記述していますが、Vue.jsのようなフレームワークを用いることで、コンポーネント化してpropsから輪郭線の回数や厚みを指定するような設計にすることも可能です。

テロップジェネレーター的なものを作った

ようやくタイトルが回収できました。ここまでの情報を応用して作ったのが、YouTubeで見られるテロップっぽい字幕を誰でも作れるWebアプリです。

f:id:spdbear:20201210102550g:plain
テロップっぽい字幕を作るアプリ
若干オーバーキル気味ですが、今どきっぽくNuxt.js + Composition API + TypeScriptで作っています。 時間があれば詳説しようと思いましたが、いったんリポジトリを貼って終わりとします。 github.com


いかがでしたでしょうか、終盤とても駆け足になってしまいましたが、SVGを使って簡単な画像生成系のWebアプリを作ることもできるよ、という記事でした。

明日の執筆者は1日目にも記事を書かれた @mashiike さんです。引続きTech KAYAC Advent Calendar 2020 をよろしくお願いします!