見出し画像

SVGでプログラマブルな書体を作る話

こんにちは。

Googleのロゴが変わっていくらか経ちますが、このロゴはSVGを使うと少ないデータ量で表現できるというニュースが話題になりました。

グーグルの旧ロゴは14,000バイトもあったのに、新ロゴはたった305バイトなのはどうして?

http://www.gizmodo.jp/2015/09/14000305.html

この記事を見た際に、厳密には視覚調整が入るはずなので、正確に幾何的図形とは一致しないだろうという感想も抱きました。しかし、SVGで文字を生成するということには非常に興味を持ちました。今までにも、文字のアウトラインを使ったアニメーションや表現はありましたが、文字自体を生成するというものは見たことがなく、そしてSVGはJavaScriptで操作することができるため、書体の印象が動的なフォントを作ることができると考えたからです。

どういうことかというと、例えば

であるとか、

といったことができるかもしれない、と考えたということです。

というわけで、作ってみた

1週間ほど使って、SVGとJavaScriptを使い、実際に「縦の画と横の画の太さ、ディセンダやアセンダ、カーニングを自在に操作できるフォント」を作ってみました。
ぜひご覧になって、操作して遊んでみてください。

縦の画と横の画の太さ、アセンダやディセンダ、カーニングを自在に操作できるフォント

こちらからご覧になれます(※Github pagesに遷移します)

今回はSVGとJavaScriptを使って制作しているので、例えば、以下の様なことも出来ます。

ポインタの位置で変化するフォント(PC用)

こちらからご覧になれます(※Github pagesに遷移します)

加速度センサーで変化する書体(加速度センサ搭載のスマートフォン用)

こちらからご覧になれます(※Github pagesに遷移します)

さて、いかがでしょうか?少しでも、文字を生成する面白さを感じていただけたでしょうか?

今回は、作り方も簡単に紹介します。

SVGの概略

僕はほとんどSVGを書いたりしたことがなかったので、そのような方々のために、SVGの書き方を簡単に記しておきます。

SVGとは

SVGとは、Scalable Vector Graphicの略で、その名の通り、「拡大縮小ができる」「ベクター形式の」画像です。そのため、様々な解像度のデバイスで綺麗に表示することができるので、レスポンシブデザインにも有効とされています。
また、xmlで書かれているため、CSSでスタイルを当てることができたり、JavaScriptで操作することができるため、インタラクションにもよく関わっています。

SVGの基本的な書き方

まず、最初に<svg>タグで次のように領域を指定します。そして、その中に図形の情報を書いていきます。
1 <svg width="400" height="300">
2 <!-- ここに図形の情報を書いていく -->
3 </svg>

SVGでは、長方形、線、多角形、ベジエ曲線、円など、様々な種類の図形を書くことが出来ます。
今回ここでは、フォント作成に用いた長方形、多角形の書き方のみを簡単に紹介します。

長方形を描く

長方形は<rect>タグで記述します。
例えば、幅300px、高さ200pxの四角形がある、という状態を書くのであれば、次のように書きます。

<svg width="400" height="200">
 <rect width="300" height="200"/>
</svg>

塗りの色はfill属性、枠線の色はstroke属性、枠線の幅はstroke-width属性で指定します。

塗りを赤、線の色を青、枠線の幅を10pxとする時には、以下のように書きます。

<svg width="400" height="200">
 <rect width="300" height="200" fill="red" stroke="blue" stroke-width="10"/>
</svg>

また、描画の開始地点もx属性、y属性で指定できます。原点は左上で、右がxの正の方向、下がyの正の方向です。

先ほどの四角形の開始地点を右に30px、下に10pxずらすには、以下のように書きます。

<svg width="400" height="200">
<rect x="30" y="10" width="300" height="200" fill="red" stroke="blue" stroke-width="10"/>
</svg>

多角形を描く

多角形は<polygon>タグで記述します。

頂点の指定はpoints属性で行います。指定の仕方ですが、例として、(0,0), (10, 0), (100, 30), (100, 40)という座標をとる平行四辺形はsvgでは次のように書きます。

<svg width="400" height="200">
<polygon points="0,0 10,0 100,30, 100,40"/>
</svg>

この例から分かる通り、points属性は、x方向の座標、y方向の座標のセットをスペースで区切っていき、座標を指定していきます。fill, stroke, stroke-width属性も長方形と同じように指定できます。

今回はこの2つを使ってフォントを作りました。

さらに詳しい書き方や使い方は

を参考にしてください。

SVGで描く予定の書体デザインをillustratorで作る

実際にSVGやJavaScriptを書く前に、書体デザインのラフをillustratorで作ります。

フォント作成計画

今回は、SVGの長方形と多角形だけを使って作れるように、以下の様な直線で構成された書体デザインにしました。

その上で、こんな感じにしたいというイメージを以下のように考えていました。

実際のillustrator上でも、縦画と横画のパスはレイヤーを分けて作っていました。

また、今回はより簡単に書けるように、以下の様なグリッドを設定して設計しました。

実装に向けて

文字の元になる情報を作る

先ほど画像にも上げたとおり、今回の書体デザインは、

  • 縦画と横画、斜めの画が存在

  • 7 x 19の格子点に単純化できる

という特徴を持っているため、以下の様なデータ構造でglyphsというオブジェクトを作成しました。

"j": {  // グリフ(文字)名
  h: [  // この中に横画を入れる
    [1.5, 6, 2.5]  // 始点のx, 始点のy, 長さ
  ],
  v: [  // この中に縦画を入れる
    [4, 1.5, 1.5],  // 始点のx, 始点のy, 長さ
    [4, 6, 6]
  ],
  sl: [  // この中に斜めの画を入れる
    [4, 12, 1.5, 18, "j"]  // 始点のx, 始点のy, 終点のx, 終点のy, 接続しているか(していないなら"n", してたら"j")
  ]
}


(上のように、座標は小数も使えます)
また、設定できる情報は

  • 縦画・横画の太さ(細さ)

  • ディセンダ・xハイト・アセンダ

  • カーニング

  • 塗りつぶしの色

とし、configというオブジェクトにまとめました。一応区切りの数、行間(複数行用)も設定しました。

上で作成したグリフの情報(glyphsオブジェクト)から文字を表示してみる

文字は次のようにして描画しました。

  • まずは与えられたテキストを行に分割し、更に各行を一文字ごとに分割し、配列に入れる。

  • 一文字ごとに対し、以下を行う

    • 文字の仮想ボディの始点を取る(l行目、n文字目はどこの座標から始まるのか)

    • 横画の<rect>を生成する(ここで先程のグリフ情報(glyphsオブジェクト)を使う)

    • 縦画を<rect>を生成する(ここで先程のグリフ情報(glyphsオブジェクト)を使う)

    • 斜めの画の<polygon>を生成する(ここで先程のグリフ情報(glyphsオブジェクト)を使う)

    • これらを<svg>に入れる

  • 全文字について以上の工程を終えたら、最後に<svg>をターゲットとなるdomに入れる

横画、縦画の終端は、接続して幅を変えた時のことを考慮して座標を計算します。

また、斜めの画の幅は、今回は縦画の幅に合わせています。高校数学程度の知識で座標を計算できます。普通の斜めの画の場合は単なる平行四辺形を書けばいい(つまり4点を計算すればいい)ですが、縦画と接続する場合は、以下の5点を計算します。これも縦幅や横幅を変えることを考慮して計算する必要があります。

文字のアセンダ・ディセンダや太さを変えてみる

今回は

  • configの値を書き換える

  • svgごと消す(ターゲットとなるdivのinnerHTMLを空にする)

  • 再度描画する

というシンプルな手順で行いました。
他のプロパティも調整することもでき、効果的なアニメーションなども実装できるかと思います。

今回のソースコードは以下で公開しています。
https://github.com/ln-north/svg_font

おわりに・展望

さて、いかがだったでしょうか。実は、今回作ったような動的なフォント生成にはすでに前例があるようでしたので紹介いたします。

SNEAK PEEKS AT ADOBE MAX 2015 ROCKED – Adobe の #projectface
https://blogs.adobe.com/conversations/2015/10/sneaks-peeks-at-adobe-max-2015.html

どれもすごいのですが、僕が動的なフォントを作っている目的は、

  • 「オンデマンドで書体デザインを考えることができること」

  • 「インタラクティブに書体デザインを変えることで新しい表現や体験を発想できるのではないか」

の二点にあります。前例に挙げましたものは、どちらかと言うと前者の考えに寄っているようで、今後の私の考えとしましては、後者のように、動的なフォントで面白い表現ができないか、ということについても考えていけたらと思います。

それではまたお会いしましょう。



この記事が気に入ったらサポートをしてみませんか?