Vue Nativeを使ってアプリにアニメーションを組み込みます。
instagramやFacebookのいいね!を押した時のアニメーションを実装していきます。これだけでもアプリの雰囲気が大きく変わるのでぜひやってみてください。
実は、expoはデフォルトでLottieをサポートしています。なので、Vue Nativeには最初から簡単にアニメーションを使用することができます。
今回は、Instagramのいいねのアニメーションを実装します。クリックしたら色がついて、もう一度クリックしたら解除されます。
Lottieとは?
そもそもLottieとはairbnbが開発した、ネイティブアプリに高品質のアニメーションを簡単に作成することができます。
以前は、Android、iOS、およびReact Nativeアプリ用の複雑なアニメーションを作成する場合、アニメーションの作成は困難で時間のかかるプロセスでした。
After Effectsアニメーションをリアルタイムでレンダリングし、ネイティブアプリが静止画像を使用するのと同じくらい簡単にアニメーションを使用できるようにします。
Lottieは、Bodymovinと呼ばれるオープンソースのAfter Effectsの拡張機能からJSONファイルとしてエクスポートされたアニメーションデータを使用します。
After Effectを使うことで自分でオリジナルのアニメーションを作りアプリに実装することができます。
今回は実装の方です。After Effect でアニメーションを作る方法はググったりyoutubeで検索したら出てくると思います。しかし、lottieで用意されているものでも十分すぎるほどあります。
サンプルには、基本的なラインアート、キャラクターベースのアニメーション、複数のアングルとカットを使用した動的なロゴアニメーションなど、さまざまな種類のアニメーションのソースファイルが存在し、みているだけでも楽しいです。
さぁ、早速作っていきましょう。
Vue Nativeの環境構築はこちらで済ませておいてください。
Lottieアニメーション一覧はこちらにまとまっています。
会員登録をしなければアニメーションをダウンロードすることはできません。まずは会員登録をしましょう。
実際に使用するときは、この中から好きなものを選んでください。今回はいいね機能の実装なので、ハートを使います。検索窓で"heart"と検索すればたくさん出てきます。
これらの中から適当に一つ選んでください。今回は以下のアニメーションを選びます。
するとこのようにひたすらアニメーションが流れるモーダルが出現します。アニメーションをダウンロードするには右上の"Download"を押してください。
下にスクロールすると、このような項目があります。
Background Colorはアニメーションの背景を変更できます。
Edit Layer Colorsを選択すると、色を変更できる画面が新たに開きます。
Edit Layer Colorsはイラストの色を変更することができます。
animationsというディレクトリを作成してください。その中に先ほどダウンロードしたjsonファイルを入れます。ファイル名は今回はlike.jsonにしておきます。
prism For WPでvue.jsのハイライトが効かないので少し見辛いです。すみません。早く対応してくれないかな・・・。
はい、少し脱線しましたが、まずは表示部分
<template>
<view class="container">
<touchable-opacity :onPress="() => playAnimation()">
<lottie
ref="lottieAnimation"
:style="{width: 200,height: 200,}"
:loop="false"
:source="lottie_animation"
/>
</touchable-opacity>
</view>
</template>
次はスクリプト部分
<script>
import React, { Component } from 'react';
import { View,TouchableOpacity } from 'react-native';
import { DangerZone } from "expo";
const { Lottie } = DangerZone;
const animation = require('./animations/like.json');
export default {
components: { Lottie,TouchableOpacity },
data: function() {
return {
animation: null,
lottie_animation: null
};
},
methods: {
playAnimation() {
if (!this.animation) {
this.$refs.lottieAnimation.play();
this.animation = true
} else {
this.$refs.lottieAnimation.reset();
this.animation = false
}
},
},
created(){
this.lottie_animation = animation
}
};
</script>
解説
ほとんどvueなので全体像はわかると思います。
表示部分
TouchbleOpacityはReact Nativeで使われている、ビューをタッチできるようにするコンポーネントです。
<touchable-opacity :onPress="() => playAnimation()">
onPress="() => playAnimation()"、この書き方気になった方もいると思います。
onPress="playAnimation"、こうじゃないのかって。
これは、ReactNativeがJSXのrenderメソッドの中でプログラムに遭遇したら、表示されているプログラムを即実行してしまうからです。しかしonPress="() => playAnimation()"のように関数として定義しておくと、クリックされたタイミングで発火します。ここは説明が難しいです。
難しいことは抜きにすると、クリックしたタイミングで発火させたかったら、onPress="() => playAnimation()"の形にしましょうってことです。うまく説明できなくてすみません。
lottieコンポーネントの変数の設定は色々あります。
今回はループさせたくはないので、:loop="false"にします。
スクリプト部分
const animation = require('./animations/like.json');
先ほどのlottieアニメーションのjsonファイルを読み込みま、aniamtionとして定義します。
methods: {
playAnimation() {
if (!this.animation) {
this.$refs.lottieAnimation.play();
this.animation = true
} else {
this.$refs.lottieAnimation.reset();
this.animation = false
}
},
},
this.$refs.lottieAnimation.play()でアニメーションを開始します。this.$refs.lottieAnimation.reset()でアニメーションを初期化します。クリックされているかどうかの判定をするのでanimationで分岐しています。
また、アニメーションの再生時間も制御することができます。ここは時間を細かく変えながら微調整していくのが良いと思います。
.play(開始時間,終了時間)
this.$refs.lottieAnimation.play(60, 120);
createdのタイミングでlottie_animationに代入します。mountedのタイミングではエラーになります。
created(){
this.lottie_animation = animation
}
DOMが生成されるタイミングで、lottie_animationはnullなのでnull is not an objectのエラーが出てきます。
vue.jsのライフサイクルフックでcreatedはDOMが生成される前、mountedはDOMが生成された後のフックなのでmountedのタイミングではエラーになってしまいます。
完成です!
まとめ
実際にいいね!機能を実装するときはもう少しだけ複雑になりますが、基本はこれで完成です。
Vue Nativeを使えば(expo)簡単にリッチなアニメーションを実装することができました!
とっても簡単:)
webで実装する方法もこちらにまとめておきました!