FlareをFlutterだけじゃなくてJSでもFlareった話

Diverse Advent Calendar 2018 19日目の記事です。

昨日は、 @clownfish さんの [Reproを使いやらかしてしまった話](https://qiita.com/clownfish/items/b043e84498e47efd026e) でした。

Diverseでは、失敗を糧に多くトライでさらに成長できる **Fail Fast** というバリューを掲げており、今年の反省をぜひ来年に活かしていきたいですね！:blush:

（※今回の記事は執筆時の12/12時点での内容になります。）


# 序章 ~Flareとの出会い~

さて今回のお話ですが、先日 12/4 に行われた [Flutter Live](https://developers.google.com/events/flutter-live/) で、Flutterの大きなアップデートの発表がありましたが、その中のツール紹介で、 2dimentions社の [Flare](https://medium.com/2dimensions/flare-launch-d524067d34d8) がありました。

Flareは、ブラウザ上でポチポチするだけで簡単にアニメーションが作成できる素晴らしいGUIツールです。
作成したアニメーションはflr形式のバイナリファイルをexportでき、そのファイルをflutter appに取り込み、[package](https://pub.dartlang.org/packages/flare_flutter)を介して表示することができます。

そこでexportする際に、アニメーションを動かすプラットフォームを選択できる `Engine` の項目で `Web` という選択肢を確認しました。

<img width="384" alt="スクリーンショット 2018-12-12 18.59.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/139890/f3527387-1c61-627d-6aea-6bd2d9cb49f1.png">

:thinking: 


**「もしやWebフロントエンドでも使えるのでは？:open_mouth:」** 

そんな小さな好奇心から始まった、ブラウザでflrファイルを表示できるまでの奮闘記についてお話します。

# 第1章 ~SDKへの期待と挫折~

まず、私は[公式ページ](https://www.2dimensions.com/runtimes)を確認したところ、

<img width="893" alt="スクリーンショット 2018-12-12 19.11.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/139890/543e957f-94ab-5dd7-cc73-f52604f85d0d.png">

なんだーあるんじゃーん♪
期待に胸を踊らせリンク先の[リポジトリ](https://github.com/2d-inc/Flare-JS)へ。

早速READMEを読んでみると、

> Usage
Take a look at example/example.html and example/example.js for how to initialize and use a Flare animation. 

要約すると、

`example/example.html` と `example/example.js` をみて参考にしてね！


とのことで、早速 example.html をブラウザで確認！

![スクリーンショット 2018-12-12 19.27.49.png](https://qiita-image-store.s3.amazonaws.com/0/139890/98cd8856-d223-4df7-3507-83ebcb1c49fb.png)


:innocent:


`gl-matrix.js` は、package.json にあったのでコピーすればよさそう。
`Flare.min.js` は、webpack.config.js があるので、ビルドすれば生成できそう。

```bash

npm install
npx webpack
cp ./node_modules/gl-matrix/dist/gl-matrix.js ./build
```

これで再度トライ！

<img width="596" alt="スクリーンショット 2018-12-13 13.15.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/139890/4cb31d9c-c4fe-bb44-0c85-1beb3c812929.png">

:innocent: :innocent:

`ball.flj` なるアニメーションファイルらしきものが、[こちら](https://github.com/2d-inc/Flare-JS/commit/a3a8bc0f5887cb46fb16f1b496eecabba99fdc60#diff-1)で削除されてて、masterでは確認できませんでした。

もう一度READMEをみてみると、

> CanvasKit vs Canvas
 There are currently two branches: master with Canvas 2d context as the renderer and CanvasKit with SKIA via WebAssembly. Going forward the CanvasKit branch will become the active one as it supports more advanced rendering operations which Flare will soon require.


要約すると、

`master` ブランチは Canvas 2d context、`CanvasKit` ブランチはCanvasKitでレンダリングしてるけど、今後は`CanvasKit`が活発になるよ！

なるほど :thinking: 


ということで、 `canvaskit` ブランチにチェックアウトして、ブラウザで再チャレンジ！

<img width="674" alt="スクリーンショット 2018-12-13 14.36.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/139890/a13ad369-58b2-25cd-5608-4451b8dc55db.png">


:innocent: :innocent: :innocent:


この `canvaskit.js` は、webpackにも記述がなく、参照されているbuild ディレクトリは .gitignore されてるため、別途生成する必要がでてきました。 


# 第2章 ~CanvasKitのビルド~

CanvasKitとは、先のREADMEにもあったとおり、Googleが開発してる2Dグラフィックライブラリ [SKIA](https://skia.org/) の一つです。[^1]

目的のCanvasKitは、[リポジトリ](https://github.com/google/skia)の`experimental` ディレクトリにあります。

以下、OSX(10.14.1)でのビルド手順です。

## 1. GNコマンドのインストール[^2]


GNコマンドについては、[こちら](
https://chromium.googlesource.com/chromium/src/tools/gn/+/48062805e19b4697c5fbd926dc649c78b6aaa138/README.md)ご覧ください。

```bash
python tools/git-sync-deps
```

## 2. Emscriptenのインストール[^3]

Emscriptenは、C/C++言語から生成されるLLVMビットコードを入力に、JavaScriptに変換するコンパイラです。[^4]

※ビルドに30分ほどかかります。

```bash

# CMakeのインストール
brew install cmake

# Emscriptenのビルド
git clone https://github.com/juj/emsdk.git
cd emsdk
./emsdk install --build=Release sdk-incoming-64bit binaryen-master-64bit
# 30分...
./emsdk activate --global --build=Release sdk-incoming-64bit binaryen-master-64bit

# emsdkにパスを通す
export EMSDK=/path/to/emsdk
```

## 3. CanvasKitのビルド

```bash
cd experimental/canvaskit
make
```

以上が成功すると、以下のディレクトリに２ファイルが生成されているのが確認できました。

```
skia
└── out
    └── canvaskit_wasm
        ├── canvaskit.js
        └── canvaskit.wasm
```


# 最終章 ~リベンジ~

第2章で作成したcanvaskitをFlare-JSのbuildディレクトリ配下に配置して、再度ブラウザ起動！

<img width="600" alt="スクリーンショット 2018-12-13 15.15.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/139890/801662c2-9a0e-c9b5-89af-4a5a1f8086cb.png">

:innocent: :innocent: :innocent: :innocent:

この`setMatrix`関数ですが、タイミングが悪く執筆時の数日前にちょうどCanvasKit側で[変更](https://github.com/google/skia/commit/92d8ea6f993043a3d1513ee62bfd70a774edf52d)があり、`setMatrix`関数が使えなくなっていました...

なので、`setMatrix`を`concat`に書き換えて再度チャレンジ！（本家に[PR](https://github.com/2d-inc/Flare-JS/pull/5)出しました :muscle: ）

![spaceman.gif](https://qiita-image-store.s3.amazonaws.com/0/139890/e0a23c9d-b911-541a-cebc-40ade30d07f9.gif)

:raised_hands: :raised_hands: :raised_hands: :raised_hands: :raised_hands:


# 完 ~まとめ~

Flare-JSでブラウザでも表示できることが確認できました。Flareの公式で1.0.0のリンクがだされていましたが、CanvasKitも絶賛開発中でFlare-JSもそれに追従している？感じが見受けられ、現状まだ安定版ではないのかなと思いました。しかし、近い将来安定版出た際には、アニメーション実装の選択肢として検討してみてもいいかなと思いました！:blush:


明日は、 @giiiita さんの[Poiboyで使用しているFirebaseの機能紹介と事例ついでにおまけ](https://qiita.com/giiiita/items/ee3423c39456093dc5ea)です！お楽しみに！ノシ



[^1]: https://skia.org/user/modules/canvaskit
[^2]: https://skia.org/user/build
[^3]: https://developer.mozilla.org/ja/docs/WebAssembly/C_to_wasm
[^4]: http://kripken.github.io/emscripten-site/index.html