LIFF(LINE Front-end Framework)+firebase+PIXI.jsで簡単画像作成「いいちGOジェネレーター」作ってみた

# はじめに
先日LINEが新たなるプラットフォームを発表しました。
https://developers.line.me/ja/docs/liff/overview/

これけっこう便利じゃ無いでしょうか！！？
今までであればBOT上で解決できない問題は全部webに飛ばすことで対応していた部分があったと思います。
LIFFを利用することで画面を遷移することなく、データのやりとりが可能になります。

そんなこんなで、
前から作ろうと思っていたいい風景といい言葉を重ねて画像を出力してLineにそのまま投稿する。
ということをやってみたいと思います。

今回のポイントはfirebaseのBaas機能を使うことで、
**サーバー開発一切行わず画像のURL取得と送信を可能にした**ということです。

#できあがり紹介
<img width="375" alt="Screen Shot 2018-06-18 at 18.47.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/247080/bbbbc2fb-fd86-c6d8-dbea-e61082364c63.png">

下のサムネイルをポチポチすると、画像の切り替えができます。
またそれぞれの言葉はPIXIjsの機能によりタッチ操作で移動が可能です。

画像は「ぱくたそ」の風景のフリー素材を利用しております。いい写真だな〜。

実際の動きを確認してみたい方はこちらから友達登録してくださいませ。
https://line.me/R/ti/p/%40lvg6648n
![CnHLtlYN2M-1_thumb.png](https://qiita-image-store.s3.amazonaws.com/0/247080/f748dee6-81dd-4e18-8b87-f7c7c7258466.png)
遊びで作成しているためレイアウトの崩れや送信ができないなどがございます。
ご注意ください。

#利用しているサービスの紹介
##Firebase
https://qiita.com/w-iijima/items/6382b8dab1d48c15ba95
こちらにも紹介しましたが、GoogleのmBaasサービスです。
今の所プロジェクト数などの制限にはかかっていません。
・Firebase Hosting(html/js/cssなどでwebを表示)
・Firebase Storage(LIFFでアップロードされた写真のURL発行)
今回は主にこの２つの機能を利用しています

##PIXI.js
http://www.pixijs.com/
2D描画用のjavascriptライブラリーです。
今回良いライブラリ教えて〜とデザイナーに頼んで、初めて触りました。
・画像とテキストの表示/切り替え
・テキストの移動
・canvas上のデータをbase64に変換（その後firebaseにアップロードを行います）

##LIFF(LINE Front-end Framework)
今回のメイン機能となります。
・ユーザー情報の取得(IDのハッシュ値を保存した画像のファイル名につけています)
・画像をトークルームに送信(sendMessagesという機能です)
・送信後画面を閉じる

#下準備（アカウントの開設/LIFFアプリの登録など）
##LIFFの準備
https://engineering.linecorp.com/ja/blog/detail/299
公式のブログにもありますようにMessaging APIが有効になったLine@のチャンネルが必要になります。
アクセストークンが発行されましたらチャネルにLIFFアプリを登録して完了です。

##Firebaseのプロジェクト作成
https://qiita.com/gupuru/items/25a6722f6f802d3a5250
こちらにしたがってで問題なく準備できると思います。

ここからさらにWEBでStorageへのアップロードなどを行うために、
firebaseのライブラリーをいれます。
作ったプロジェクトがfirebaseの管理画面上にでていると思いますので、
Project Overview→ウェブアプリにFirebaseを追加を選択すると
scriptタグが発行されていますのでコピーして自身の作成したhtmlにペーストしてください。

#重要&つまづきポイントご紹介
##Firebase storageのread/writeはデフォルトではFirebase Authentication で認証したユーザーのみになっている
このままの設定ですと、認証していないユーザーが画像をアップしたりLineでの参照ができなくなります。
これは良い設定ではありますが今回は用途が異なるため修正します。
firebaseの管理画面からStorage→ルール

```
    match /xxxxx/{allPaths=**}{
    	allow read, write;
    }
```
こんな感じで、xxxxxというフォルダ配下のファイル(今回の場合は画像)のread/writeを許可します。


##PIXIでbase64を出力時に使用する関数を間違えると上下反転したデータが取得される
```Javascript
app = new PIXI.Application(xx);
app.renderer = PIXI.autoDetectRenderer(xx);
```
まずこうすることで出力が可能になりました。（rendererを指定しないと真っ黒）
ここからbase64を取得する場合に、

```Javascript
var base64 = app.renderer.view.toDataURL("image/png");
```
こうすることで取得できました。
ただし端末によって上下反転します。
macのchromeでは反転はしませんでしたが、iPhoneでは反転しました。
これを解決する場合にはこうです。

```Javascript
var base64 = app.renderer.extract.base64();
```
##firebase storageにアップされた画像のURLを取得する
続いて上記で取得したbase64値をアップしてみましょう。

```Javascript
var storage = firebase.storage();
var ref = storage.ref();
ref.child("images/xxxxxx.png").putString(base64,"data_url").then(function(snapshot){
  //ここではsnapshotというオブジェクトが取得できますが、画像のURLは取れません。
  snapshot.ref.getDownloadURL().then(function(downloadURL){
   //ここで画像のダウンロードURLが取得できます。
  })
})
```
base64のデータをそのまま送信することはできません。
なにかしら画像をアップロードして参照できるURLが必要になります。
本来この内容をやるためには、サーバーサイドのプログラムが必要になりますが、
上記のfirebase storageの機能を利用することでクライアント側のjsのみを実装することで送信を可能にしております。
(画像の保存やURLの管理はfirebaseにお任せしているということですね)
ここまでできて無料。おそるべしです。

詳しくはこのページを参考にしてください。
https://firebase.google.com/docs/storage/web/upload-files?hl=ja

##PIXIで背景画像を差し替える
Textureというものを利用します。

```Javascript
var texture = PIXI.Texture.fromImage("./xxx.jpg");
landScape = new PIXI.Sprite(texture);
landScape.x = 0;
landScape.y = 0;
app.stage.addChild(landScape);
```
そして別の画像に差し替える時はこんな感じです。

```Javascript
var texture = PIXI.Texture.fromImage("./xxx2.jpg");
landScape.texture = texture;
```


##firebase hostingのキャッシュを調整
firebase.jsonを修正します。
前後省略しています。

```
"headers":[{
"source":"xxx.xx",
"headers":[{
 "key":"Cache-Control",
 "value":"max-age=0"
}]
}]
```
こんな感じでキャッシュされていない最新の状態のファイルを取得できます。

#今後対応すること
・タブレットなど画面広いデバイスに対応する（背景が黒くなってしまう）
・画像送信時にローディングのアニメーション入れたい
・全員の投稿一覧をチェックできるようにしたい
・UIを整えたい

#余談
・LIFFはURLを共有できればどのトークルームでも呼び出せるという素晴らしい仕様ではあるのですが、これを他の人に説明するのが難しい。。。
・Qiitaの書き方には今後慣れていきます。見づらい場合はご容赦ください。