12
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

LIGAdvent Calendar 2018

Day 2

SVG を transform で楽しくアニメーションするための最適化 〜僕らは幸せになるために生まれてきた〜

Last updated at Posted at 2018-12-01

SVG を transform でアニメーションさせる場合、SVG 内の各要素を指定すると、原点が SVG 全体の左上なってしまいます。translate などは問題ないですが、scalerotate などは思うようにアニメーションさせることができないです。

動かしたい要素をそれぞれ別の SVG に分けて、重ねて、原点を調整することで、対応することはできます。

しかし、それをひとつひとつ設定していくのは骨が折れる作業になります。とてもやってられないですね。だからといって、SVG ではない要素でつくってひとつひとつ配置していくのは涙が出るほど辛いでしょう。こんなことはエンジニアがやることでないです。僕たちは幸せになるために生まれてきたのだから。まだまだ理想にはほど遠いですが、とりあえず少しは楽になる方法を考えてみました。

作業手順

大きな作業手順としては以下の3ステップです。

  1. svg を Adobe Illustrator で編集
  2. SVG のサイズと位置情報を出力
  3. スクリプト(Node)で最適化した要素を出力

では細かい手順をみていきましょう。

1. svg を Adobe Illustrator で編集

1-1. 最上位レイヤー直下でグループ化する

まずは、svg を Adobe Illustrator で開きます。
最上位レイヤーはひとつだけにして、動かしたい要素ごとに分けます。
グループ化されていないとデータを取得できないので、単体のパスであってもグループ化します。

レイヤー 1
  ├ <直線>
  ├ <長方形>
  └ <パス>

↓ グループ化

レイヤー 1
  ├ <グループ>
  ├ <グループ>
  └ <グループ>

※最上位レイヤー名はなんでもよいので初期値のままで レイヤー 1 としています。

1-2. グループ名をつける

この名称が class 名や中心位置の設定などに反映されます。

class 名に関する命名ルール

名称は 英数字 と **-(ハイフン)**で、同じ名称は使えないです。
同じ名称ににしたい場合は **_(アンダースコア)**つなぎで番号を追加します。

例)同じクラス名称のグループがひとつの場合
レイヤー 1
  ├ line
  ├ rect
  └ circle
例)同じクラス名称のグループが複数の例
レイヤー 1
  ├ line_1
  ├ line_2
  └ line_3

原点に関する命名ルール

上記の Class 名のあとに接尾詞として追加します。追加しない場合はグループの中心が原点になります。
***(アスタリスク)**つなぎで原点を設定していきます。
グループからみた位置を % で X 軸 Y 軸の順番に **,(カンマ)つなぎで指定します。
また、
^ (キャレット)**からはじまる場合は SVG 要素の位置からみた指定になります。

例)
レイヤー 1
  ├ line
  ├ rect*20,80
  └ circle*^50*50

line : グループの中心(X 軸 Y 軸 ともに 50%)
rect*20,80 : グループの X 軸は 20% で Y 軸は 80%
circle^50*50* : SVG 要素の中心(X 軸 Y 軸 ともに 50%)

1-3. オプションを選択して保存する

保存時のオプションで 詳細オプション > CSS プロパティ > スタイル属性 を選択して保存します。
※これは SVG 要素を分割するため、スタイル属性をつかったほうが都合がよいからです。

2. グループのサイズと位置情報を txt で出力

Adobe Illustrator のプラグインである Adobe-Export-Scripts をつかいます。

2-0. プラグインをつかう準備(初回のみ)

GitHub からダウンロードして、Adobe-Export-Scripts-master > Illustrator > Export Layout.jsx を以下の環境に応じたフォルダに設置する。

Mac: ~/Applications/Adobe Illustrator CC 2019/Presets/ja_JP/Scripts/
Windows: C:\Program Files\Adobe\Adobe Illustrator CC 2019\Presets\ja_JP\Scripts
※環境によって変わります。主にバージョンと言語の箇所。

スクリプトを使えるようにするために、一度 Adobe Illustrator を再起動する必要があります。

2-1. スクリプトで txt を出力

ファイル > スクリプト > Export Layout からスクリプトを実行し txt を出力します。
※このときに png も出力されますが今回はつかいません。

3. SVG をアニメーションしやすく最適化

編集した svg と、出力した txt をつかって、アニメーションしやすく最適化した状態の要素をつくります。
これには僕が制作したスクリプトの optimize-svg-transform をついかいます。

3-0. ダウンロードする(初回のみ)

GitHub からダウンロードして、任意の場所におきます。

3-1. ファイルの追加

src ディレクトリ直下に svg と txt を追加

3-2. スクリプトの実行

ターミナルで optimize-svg-transfrom をおいた場所に移動して、以下のコマンドを実行します。

$ node optimize-svg-transfrom.js -- [SVG の拡張子を除いたファイル名]

実行に成功すると、dist ディレクトリ直下に html が出力されます。
最適化されたざっくりな内容は以下です。

  • グループごとの svg に分割
  • グループごとに設定した transform-origin を設定
  • 個々の svgdiv でラップ
  • 全体を div でラップ
  • レスポンシブ対応
例)
$ node optimize-svg-transfrom.js -- sample
┬ dist ─ sample.html
└ src ┬ sample.svg
      └ sample.txt

サンプル

まあ、何をいっているか分かりづらいと思いますので、サンプルを用意しました。

Illustrator で開いてグループ名を変更した SVG のキャプチャ

かるく説明します。
  • 四角は設定していないので自身を中心に動きます
  • 円は全体を中心に動きます
  • 三角は自身のひとつの頂点を中心に動きます(六芒星をかたどっているので、それぞれ別の頂点にしました)

CSS スタイルをスタイル属性で保存した SVG

See the Pen SVG Sample before Optimize by Syuji Higa (@syuji-higa) on CodePen.

まあ、まんまですね。 Illustrator で保存したので、不要な要素や属性とかもありますが、スクリプトを通すと消えるので編集は不要です。

スクリプトで最適化した SVG を適当にアニメーション

See the Pen Optimize SVG Sample by Syuji Higa (@syuji-higa) on CodePen.

CSS の animation でサクッとアニメーションさせました。
まあ、こんな感じですよ。

まとめ

どれだけの人がこの手法で幸せになるかは分からないですが、デザイナーがつくってフロントエンドエンジニアが動かすみたいな手順の場合は結構つかえるかと思います。
例えばインフォグラフィックスとかのアニメーションは大変だと思うんですけど、この手法なら少しは楽になりそうな気がしませんか?

まあ、はじめから After Effects とかでつくっちゃうのが一番はやそうですけどね。Lottie とかよいらしいので、次の案件でつかってみてボクはボクで勝手に幸せになろうかと思います。

12
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?