ゼリーみたいなぷるぷるアニメーションボタンを作ろう！

まるでゼリーのようにぷるぷるしたボタンを作る記事です。
![58910b60-f57c-05f3-2039-2d8e856f8b86.gif](https://qiita-image-store.s3.amazonaws.com/0/54478/a6dd6d10-cdcd-e6f3-2036-6144c50bac83.gif)


# 制作手順

1. ボタンのデザインを作る
2. アニメーションの動きのイメージを掴む
3. アニメーションの大まかな動きを作る
4. アニメーションボタンにディティールを追加する
5. コーディング用の画像を作る
6. コーディング
7. 完成


## ボタンのデザインを作る

思わず触れたくなるようなぷるぷるボタンを作ろう！という素敵な意気込みから始まったこの制作。
アニメーション部分が一番の肝だが、それのベースとなる画像を作り込んでおくに越したことは無いので、ウソ・ホントを交えた「ゼリーっぽい」質感のボタンを作った。

そして出来上がったのがこちら。（Photoshopにて作成）
![6dca8b90-6f48-8c9b-2e87-c26cc99668b3.png](https://qiita-image-store.s3.amazonaws.com/0/54478/25933bf1-ae63-8d0b-6904-7131b4ac53a9.png)


ボタンのデザインが出来上がったので次はどう動かすかを考えて行きます。

## アニメーションの動きのイメージを掴む

動画サイトからゼリーのぷるぷるした動きがよく分かる動画を探します。
手動でコマ送りしつつ、ゼリーがどのような動きをしていくのか、ひたすら繰り返し観ます。
そして、ゼリーの動きが目に焼き付いてきたら、
Webサイトのパーツとして配置されたボタンはどう動けば不自然ではないかを考えます。
動画の動きを参考に紙に書き出したりしながら、ひたすらイメージを詰めて行きます。

参考動画：https://www.youtube.com/watch?v=1JEsIzAaaQM

イメージがなんとなく掴めてきたら、アニメーションをざっくり作ってみます。
なんとなくの段階で、とりあえずざっくり作ってみるのが大事です。

## アニメーションの大まかな動きを作る

Animate CC（旧Flash）でアニメーションを作成します。
パスで書いたボタンを1フレームずつ形状変化させて作ります。
約50案を経て↓の動きでOKが出ました。

![6205ee1d-ec57-5c1f-a933-ed7fe2591a91.gif](https://qiita-image-store.s3.amazonaws.com/0/54478/a82c66da-2501-465d-23fa-b60ca0a888e6.gif)


## アニメーションボタンにディティールを追加する

アニメーションボタンにディティールを追加する為に、デザインデータを読み込み整えていきます。

### Animate CCにPSDを読み込む

![47a353b0-7872-7e7f-e630-221951e2231c.png](https://qiita-image-store.s3.amazonaws.com/0/54478/ff278b29-e9d7-a124-d8f9-cbd1030aa0ca.png)


デザインデータを読み込む前に、**Photoshopのレイヤースタイル、シェイプ等々を全てラスタライズ**します。
Animate CC上では再現できないレイヤースタイルや描画モードがあるので最適化していきます。

![efad1e51-75cb-19b6-d494-7744ee17f7ce.png](https://qiita-image-store.s3.amazonaws.com/0/54478/a77e3eef-ae36-1d8e-45ee-a7818fcd7899.png)

続いて、Animate CCのライブラリにPSDを読み込みます。
設定は以下のように行いました。
![5763ec05-dae7-f498-1148-d964c00789d9.png](https://qiita-image-store.s3.amazonaws.com/0/54478/c1e20cdf-ffb9-1fd9-f3d2-1d57c0d02b2d.png)


Animate CCのライブラリに読み込むと、多少荒れますがこの程度なら許容範囲とします。
![17823bfe-f064-4738-7a5c-8e8070b26d6f.png](https://qiita-image-store.s3.amazonaws.com/0/54478/9c54bc25-c83b-4b0b-7d4c-d05ad8136420.png)


### タイムラインにPSDのアセットを展開します

ライブラリから「.psd」と名前のついたアイテムをステージに配置し、右クリック→「分解」をします。
![892bfaa5-9d43-f1cd-d129-888eae1f074e.png](https://qiita-image-store.s3.amazonaws.com/0/54478/524707c1-5402-087d-8993-30e293d1512b.png)

分解されたら、オブジェクト選択状態のまま「レイヤーに配分」
![2b236d13-db40-ad0b-de78-06d6b88c3509.png](https://qiita-image-store.s3.amazonaws.com/0/54478/bc9c284b-8b43-d2aa-6fc5-eaa71b86e068.png)


PSDのレイヤー名がそのままタイムライン上のレイヤー名となって展開される
![0b165433-c056-53d5-6fe3-4be5406471f1.png](https://qiita-image-store.s3.amazonaws.com/0/54478/1cbb2fb4-4e78-00bf-3f83-e2fc16550baa.png)


※ここで描画が変わるとPSD上でのレイヤーのラスタライズ化が上手く出来てないということになるので、
再度PSDに戻ってやり直します。

### アニメーションを作りこんでいく

画像オブジェクトはそのままにしておくと、最終的な画像ファイルの肥大化につながるのと、
今回のように複雑に形状が変化する場合はパスに置き換えないと動きが作れませんでした。
なので、アニメーション作る過程でAnimateの**パスに書き換えて**いきます。

以下が出来上がったアニメーションのタイムラインです。
![55e63fd9-738e-1515-52c7-301f84f3793e.png](https://qiita-image-store.s3.amazonaws.com/0/54478/9fa7c4ad-f844-8ec3-d8a1-4d3f1917183b.png)


ブルーがクラシックトゥイーン（画像）、
グリーンがシェイプトゥイーン（パス/形状変化するアニメーション）です。

制作中は、簡易パブリッシュをし、ブラウザ上で動きを確認します。
![390c0920-fcdf-243e-6aa9-ce3311643a0f.png](https://qiita-image-store.s3.amazonaws.com/0/54478/5503ba5f-dd32-da69-123b-eba30af189b1.png)


アニメーションの動きについては、１フレーム、１オブジェクトずつパスを変形させて作成しました。
根気と集中力が大切です。
![09cf2979-d712-f12f-1b7f-6bac912e3187.png](https://qiita-image-store.s3.amazonaws.com/0/54478/30feb806-4af5-c33e-1ca9-eac8bafbef13.png)


作っていて動きの方向性を見失ったら、最初に調べておいた参考動画を見直して、
再度イメージを掴み直すとまた作り出せて良かったです。

動きが完成するとこんな感じです。
![ef1ae128-84bb-4ac4-13c1-d00b621875eb.gif](https://qiita-image-store.s3.amazonaws.com/0/54478/ae32cd67-8981-f214-bd3e-73a381ec428c.gif)



### データを整理する

制作過程でライブラリにたまった未使用のアセットやトゥイーンを削除し、
使用中のものはレイヤー名と紐付けて命名、整理します。
![036acbbf-15eb-2361-854a-87213b23a88c.png](https://qiita-image-store.s3.amazonaws.com/0/54478/1b2f0bea-2bdc-0a47-f52f-994b25b50158.png)



### 画像を書き出す

**パブリッシュ設定**
png設定の画質を「8bit」にする（画像最適化のため）
![d5c51c8b-47e5-0d0c-f27f-67ab098c92dd.png](https://qiita-image-store.s3.amazonaws.com/0/54478/4ce25ee5-4919-40bf-d3b7-6cbc7439256a.png)


**画像を書き出す**

画像ですが「書き出し」の「ムービーの書き出し」を選択
![1c0835a8-a2a4-e088-2787-f22d8bc57b95.png](https://qiita-image-store.s3.amazonaws.com/0/54478/4a00ca35-86f5-dafa-a928-acf0219cae97.png)


１度に大量の画像が生成されるのでフォルダを用意しておくと良いです。
![7717225c-cc82-544b-edd5-99689354d1b3.png](https://qiita-image-store.s3.amazonaws.com/0/54478/04fd90c0-e07a-f653-bd69-6b1d22b89395.png)


png書き出し設定
![673c0e6c-e556-26db-8c58-ebb8be17208c.png](https://qiita-image-store.s3.amazonaws.com/0/54478/517e0658-1302-315b-917a-e9cf2330af78.png)



- 書き出し時のボタンの幅、高さはここで変更出来ます
    - 幅500pxで作ったけどやっぱり幅200pxで欲しい、というときに便利です
- 解像度は、幅・高さに合わせて数値が変わりますが実際は72ppiで書き出されるので気にしなくてOK
- カラーは、画像最適化の為に最小値の8bit、背景は透過にしたい場合は「不透明」を選びましょう

書き出すとフォルダ内に画像が展開されます。
フレーム数＝画像ファイル数となります。
![d8abc88c-7b38-6732-56ea-b7e663d81fa0.png](https://qiita-image-store.s3.amazonaws.com/0/54478/2fb7b82d-29ba-eff5-48b9-9e6b3ade9e96.png)



## コーディング用の画像を作る

アニメーションgifだとファイル容量が大きい、
かと言ってgifの画質を落とすとクオリティが保てない、
ということでCSSスプライトアニメーションで作ってみることにしました。


### スプライト画像を作る

書き出した画像を[tinypng](https://tinypng.com/)を開き、ドラッグ＆ドロップで圧縮をします。

続いて、[CSS Sprite Generator](http://www.ja.spritegen.website-performance.org/)を利用してスプライト画像を作ります。

デフォルトの設定を「Clear」します
![15060e33-ccb2-f753-2103-47a436954028.png](https://qiita-image-store.s3.amazonaws.com/0/54478/69ff6fe8-58ac-b01c-d6c9-6ab948f91e65.png)


設定をClearすると「Settings」が表示されるので、キャプチャのような設定をし「Save」します。
![4eb80483-3be7-e513-0e7b-6ccfe99da313.png](https://qiita-image-store.s3.amazonaws.com/0/54478/ccf0f9d9-8c45-ba55-3736-68aeaa5daf6f.png)


先ほど書き出した画像を全て選択し、CSS Sprite Generator内にドラッグ＆ドロップします。
画像が多い場合はスクロールして全ての画像がスプライト画像になっているか確認します。
![8582b4d2-ec3d-8bc0-cad3-6967d94d0954.png](https://qiita-image-store.s3.amazonaws.com/0/54478/f7a2077a-ebe6-ba2f-b188-ea7b143d5468.png)


「Download」をクリックし、「PNG」と「CSS」のタブから内容を確認し、
問題なければ「Spritesheet」と「Stylesheet」をDLします。
![52f7b891-524e-135c-add8-fa698b51c994.png](https://qiita-image-store.s3.amazonaws.com/0/54478/411ccb69-cdde-026f-66c3-34c57cbd22c5.png)


### 画像圧縮をする

スプライト画像はDLしたままだとファイル容量がとても大きいので圧縮をします。
![9d566681-4bd7-f339-3f25-3aff37f7a891.png](https://qiita-image-store.s3.amazonaws.com/0/54478/bf60a1a2-9c66-2720-0fb7-ecd40a41dafb.png)

[tinypng](https://tinypng.com/)などの画像圧縮サービスを利用して圧縮します。
![efd3ac7d-28e2-f432-9866-ef8b445257b6.png](https://qiita-image-store.s3.amazonaws.com/0/54478/e9f95e56-250b-491f-dda0-160d73f7db4b.png)

まだファイル容量が大きいので、圧縮0%になるまで何度も圧縮をかけます。
※ある程度行くと底打ちになるので、あまりにもファイル容量が大きい場合はファイルサイズ（横ｘ縦）を変更するのも一手です
※その場合は、Animate CCでのムービー書き出しからやり直しになります

最終的に落ち着いた形がこちら。
![448ceddf-8b5d-4ecf-c4a5-c4acd97ff231.png](https://qiita-image-store.s3.amazonaws.com/0/54478/fa8e495d-00ed-e47a-fa07-b0621a8767b1.png)


## コーディング

### サンプルコード

```lang:HTML
<a href="" class="st-Button_Official">ぷるぷるボタン</a></div>
```


```lang:SCSS
.st-Button_Official {
  display: block;
  overflow: hidden;
  width: 360px;
  height: 115px;
  background: url("/assets/img/btn_jelly_green.png") 0 0 no-repeat;
  animation: sprite_sp 1.5s steps(58, start) infinite;
}

// ==============================================
// == Animation

@keyframes sprite_sp {
  0% {
    background-position: 0 0;
  }
  100% {
    background-position: 0 -6670px;
  }
}

```

### SCSS/CSSの詳細

**keyframes**
スプライト画像が移動する数値を設定します。
CSS Sprite Generatorで生成したcssを開き、一番最後のclassのbackground-positionの数値をコピーします。

![faac55a9-ca24-73b9-9efa-2379d9bbfbd2.png](https://qiita-image-store.s3.amazonaws.com/0/54478/8baa84fb-0447-2a15-68c9-43816c3ab899.png)
この数値を、@keyframesの100%のbackground-positionにペーストします。

```lang:SCSS
@keyframes sprite_sp {
  0% {
    background-position: 0 0;
  }
  100% {
    background-position: 0 -6670px;
  }
}
```


**steps()**
スプライト画像を移動させる回数を設定します。
![220aeb54-ab01-7d03-3b64-da986fa924cb.png](https://qiita-image-store.s3.amazonaws.com/0/54478/6eac8b49-3c16-3d9a-93e4-4283e300a27b.png)
全部で59コマ（書き出し画像なら59枚）あるので、最初の１枚目を引いて58回画像は移動します。
よってstepsは58となります。

```lang:SCSS
.st-Button_Official {
  animation: sprite_sp 1.5s steps(58, start) infinite;
}
```

## 完成

実際の動きをブラウザで確認しつつ、微調整をしたら完成です！！！
![58910b60-f57c-05f3-2039-2d8e856f8b86.gif](https://qiita-image-store.s3.amazonaws.com/0/54478/fdc67ac7-a552-84a4-a0ce-c42d107376d6.gif)


最後までご覧いただき、ありがとうございました。