chot Inc.

ちょっと株式会社 社員ブログ
Blog
  • ホーム
  • ブログ
  • react-springでシンプルなテキストアニメーションをつくる

react-springでシンプルなテキストアニメーションをつくる

ナレッジ・ノウハウ
react-springでシンプルなテキストアニメーションをつくる

SHARE

こんにちは、ちょっと株式会社フロントエンドエンジニアのnoeです。

今回はシンプルな記述でリッチなUIを作るための、react-springというライブラリをご紹介します。完成系は、以下のように連続したテキストが時間差でIN/OUTされるアニメーションです。



Next.jsプロジェクトへの組み込みを想定して、順に説明していきます。

react-springとは

react-springは他のアニメーションライブラリであるanimatedreact-motionに触発されたUIアニメーションライブラリです。webやネイティブアプリなどあらゆるプラットフォームに対応しており、2022年3月現在もコミュニティによって活発に開発が進められています。

インストール

react-springはユースケース別にモジュールがエクスポートされています。そのため、プロジェクト要件によってはモジュール全体をインストールする必要がなく、容量を抑えることができます。

// 以下のターゲットに対応
@react-spring/konva
@react-spring/native
@react-spring/three
@react-spring/web
@react-spring/zdog


今回は@react-spring/web の範囲内を取り扱うため、以下のように追加します。

yarn add @react-spring/web


アニメーションの実装

時間差で動くアニメーションのために、useTrailフックを利用します。第一引数にはアニメーション対象、第二引数にアニメーションの設定を渡します。

import { useTrail, animated as a } from "@react-spring/web"

// アニメーション対象と設定の初期化
const items = Array(10).fill("chot Inc.")
const config = { mass: 4, tension: 2000, friction: 200 };

const Page: NextPage = () => {
// useTrailフックを呼び出し、アニメーション対象と設定を渡す
const trail = useTrail(items.length, {
config,
opacity: toggle ? 1 : 0,
x: toggle ? 0 : 20,
height: toggle ? 80 : 0,
from: { opacity: 0, x: 20, height: 0 }
})
}


viewへの割り当て

trailオブジェクトはアニメーションの挙動を含む配列ですので、.map()を使用して展開します。
.to()メソッドのところは同様の機能で.interpolations()メソッドが存在しますが、現在非推奨[1]となっておりますので注意しましょう。

return (
<div className={styles["trails-main"]} onClick={() => set(state => !state)}>
<div>
{trail.map(({ x, height, ...rest }, index) => {
return (
<a.div
key={items[index]}
className={styles["trails-text"]}
style=
{{
...rest,
transform: x.to(x => `translate3d(0,${x}px,0)`)
}}

>

<a.div style=
{{ height }}>{items[index]}</a.div>
</a.div>
);
})}
</div>
</div>
)


最終的なコード

cssで調整し、これまでのコードを組み合わせると最終的に次のような形になります。

import React, { useState } from "react";
import { useTrail, animated as a } from "@react-spring/web";
import styles from '../styles/pages/index.module.scss'
import { NextPage } from "next";

const items = Array(10).fill("chot Inc.")
const config = { mass: 4, tension: 2000, friction: 200 };

const Page: NextPage = () => {
const [toggle, set] = useState(true);
const trail = useTrail(items.length, {
config,
opacity: toggle ? 1 : 0,
x: toggle ? 0 : 20,
height: toggle ? 80 : 0,
from: { opacity: 0, x: 20, height: 0 }
});

return (
<div className={styles["trails-main"]} onClick={() => set(state => !state)}>
<div>
{trail.map(({ x, height, ...rest }, index) => {
return (
<a.div
key={items[index]}
className={styles["trails-text"]}
style={{
...rest,
transform: x.to(x =>
`translate3d(0,${x}px,0)`)
}}
>
<a.div style={{ height }}>{items[index]}</a.div>
</a.div>
);
})}
</div>
</div>

)
}

export default Page


まとめ

公式ドキュメントを参照すると、useTrail以外にも様々な表現が可能となるAPIがサンプル付きで豊富に載っています。ぜひ手を動かして試してみてください。

noe

フロントエンドエンジニア

関連記事

Copyright © 2022, chot inc.