ReactNativeはReactやReduxの知識さえあればだいたいのアプリは作ることができます。 理由は、Reactで使った知識をそのまま流用できる点が多いためです。 しかし、アニメーションは少し勝手が違って、Reactで使ったアニメーションをそのまま流用することは難しいです。 今回は、ReactNativeで動きのあるアプリを実装するための方法を紹介します。 具体的には、Animatedを使って描画時にぴょんぴょん跳ねるViewを作ります。
react-native
のプロジェクト立ち上げ済Typescript
で実装していますAnimated
はreact-native
のモジュールです。
そのためライブラリのインストールが必要なく、バニラの状態でも使えます。
簡単に解説すると、Animated.Value
で指定したフレームに対応した値を出力し、その値を使ってコンポーネントのstyle
を変更していく、というものです。
例えば、0から500フレームの間で1回転させる(=rotateを操作する)
などです。
この説明だけだと分かりにくいと思うので、実装に動作するサンプルを掲載します。
下記は描画が終わったタイミングで2回だけその場でぴょんぴょん跳ねるView
の実装例です。
import React from 'react';
import { View, Text, StyleSheet, Animated } from 'react-native';
interface State {
// Animated.Value(ここにアニメーションの値が格納されている)
animatedValue : Animated.Value,
}
/**
* Animation設定
* 0〜300フレームの間で増減する値を宣言する
* CSSでいうところの@keyframeのようなイメージ
*/
const interpolationConfig : Animated.InterpolationConfigType = {
// 入力される値(フレーム)
inputRange: [0, 75, 150, 225, 300],
// 出力される値
outputRange: [0, -15, 0, -15, 0],
}
export default class Test extends React.Component<{}, State> {
/**
* constructor
* @param props
*/
constructor(props: {}){
super(props);
this.state = {
// animatedValueを0で初期化
animatedValue : new Animated.Value(0),
}
}
/**
* onLayout時処理
*/
handleOnLayout = () => {
// animatedValueを300まで1.5sかけて変化させる
Animated.timing(this.state.animatedValue, {
toValue: 300,
duration: 1500,
useNativeDriver : false,
}).start();
}
render = () : JSX.Element => {
const { animatedValue } = this.state;
const translateY = animatedValue.interpolate(interpolationConfig);
return(
<View style={styles.container}>
<Animated.View style={[styles.jumpingView, { transform : [{translateY : translateY}] }]} onLayout={this.handleOnLayout} />
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex : 1,
alignItems : 'center',
justifyContent : 'center'
},
jumpingView : {
height : 100,
width : 100,
backgroundColor : '#94e4fe',
}
});
続いてポイントを解説していきます。
コンストラクタ内でstate
を初期化していますが、その際にAnimated.Value
を使っています。
これは、<Animated.View>
を動かす際に使用する値で、初期値を0
としています。
new Animated.Value(0)
まず、上下している水色のViewは<Animated.View>
を使っています。
Animated.Value
で動かしたいコンポーネントは<Animated.View>
を使うようにしましょう。
自作のコンポーネントを丸ごとAnimated.View
化したい場合はcreateAnimatedComponent
を使うことで対応できます。
const AnimatedOriginalComponent = Animated.createAnimatedComponent(OriginalComponent);
Animated.InterpolationConfigType
型のインスタンスを作成し、目的のアニメーション動作に合致したフレームと出力値を設定します。
下記の例では、最終的にView
を上下に動かしたい(=translateY
を操作したい)ので、outputRange
にはtranslateY
の値が入っています。
これにより、フレームが0
から300
に変化した際にtranslateY
が0
から-15
の変化し、また0
に戻るという動作を2回繰り返します。
const interpolationConfig : Animated.InterpolationConfigType = {
// 入力される値(フレーム)
inputRange: [0, 75, 150, 225, 300],
// 出力される値
outputRange: [0, -15, 0, -15, 0],
}
Animated.timing
でAnimated.Value
を指定した時間をかけて変化させます。
サンプル中では1.5
秒かけてAnimated.Value
の値を300
に変化させています。
Animated.timing(this.state.animatedValue, {
toValue: 300,
duration: 1500,
useNativeDriver : false,
}).start();
Animated.interpolate
で現在のAnimated.Value
から対応する値を取得します。
先ほどInterpolationConfigType
の項で設定したインスタンスを元に値を取得します。
例.Animated.Value
が25
なら-5
を取得する。
const translateY = animatedValue.interpolate(interpolationConfig);
ここで取得した値を<Animated.View>
のスタイル(ここではtranslateY
)に指定しているので、フレーム値の変化に伴ってtranslateY
が変化し、上下しているように動きます。
<Animated.View style={[styles.jumpingView, { transform : [{translateY : translateY}] }]} onLayout={this.handleOnLayout} />
今回はAnimted
を使って、描画時に上下するView
の作成サンプルを紹介しました。
React
や他のフレームワークから入った方には少し取っつきづらく感じるかもしれませんが、このサンプルを応用することで多種多様な動きをコンポーネントに持たせることができます。
アプリに動きが加わると一気にクオリティが上がるので、早いうちにマスターしておくといいかもしれません。