単一コンポーネントに連続アニメーション追加:React Spring

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
VSCode Dev Containersで楽々開発環境構築祭り〜Python/Reactなどなど〜
Visual Studio Codeの拡張機能であるDev Containersを使ってReactとかPythonとかSpring Bootとかの開発環境をラクチンで構築する方法を紹介するイベントです。
https://tech-lab.connpass.com/event/311864/

ども!l今回はReact Springを用いて単一コンポーネントに連続でアニメーションを適応する方法について解説しています。まるでスプラのリザルト画面的なアニメーションを実装する方法を目指してみました。若干動きがぎこちないですが、ひとまずという感じで執筆しています。小さいところからアニメーションを用いたUX改善を始めましょう。

はじめます

ども!お家から30分圏内で行ける温泉を探し回っている龍ちゃんです。意外といける温泉が多くてニヤニヤしています。温泉でコーディングできる施設なんてないかな~と思っていますが、これはもう旅館に行くしかないですね。

さて今回もReact Springを使った内容を深ぼっていきたいと思います。今回取り扱うシナリオは、「同一のコンポーネントに複数のアニメーションを連続で適応する」になります。

それではさくっと始めていきましょう。セットアップに関しては、前回の記事で解説入れています。

本題

今回のシナリオをどこで使ったかについては、以下の動画を見てもらえればかなと思います。こちらは、OSC福岡で作成したサイトになります。

「スプラ〇ゥーン」のリザルト画面をイメージして作成しました。もっと滑らかになるつもりだったのですが、ひとまずここが限界かなと思います。

環境とセットアップ

それでは、セットアップと使用方法についてまとめていきます。インストール自体は、安心コマンド一発になります。

yarn add @react-spring/web

あとは、要素の部分を以下に変更することで動作します。

import { animated } from '@react-spring/web'

export default function MyComponent() {
  return (
    <animated.div
      style={
				<-- アニメーションの定義をここで書くとええ感じの動作する -->
			}
    />
  )
}

これだけでアニメーションを定義することができるので、非常に楽で便利です。環境は「Tailwind CSS」を利用しています。

連続アニメーション適応

単一コンポーネントに複数のアニメーションを適応する方法は、一つのアニメーションの後にAPIで適応する方法などもありそうです。今回は、事前に複数の定義を付けておく方法で対応していきます。toの部分で順次定義を記載しておくことでアニメーションが連続で実行されます。

const ratioAnimationPropsA = useSpring({
  from: { width: '0%' },
  to: async (next) => {
    await next({ tension: 200, friction: 20, config: { duration: 200 } });
    for (let i = 0; i < 5; i++) {
      await next({
        width: `${Math.random() * 5 + 10}%`,
        config: { tension: 200, friction: 20, duration: 500 },
      });
    }
    await next({
      width: `${ratioA}%`,
      config: { duration: 100 },
    });
  },
});

スプ〇トゥーン的なアニメーション

サンプル動画で作成したプログラムが以下になります。引数として2つの値を渡すことで、値を計算してプログラムがスプラ〇ゥーン的なアニメーションを作成してくれます。

import { animated, useSpring } from '@react-spring/web';

interface TripleGraphProps {
  valueA: number;
  valueB: number;
}

const calculatePercentages = (A: number, B: number): { ratioA: number; ratioB: number } => {
  const total = A + B;
  if (total <= 0) return { ratioA: 0, ratioB: 0 };
  const ratioMushrooms = (A / total) * 100;
  const ratioBamboo = (B / total) * 100;
  return { ratioA: ratioMushrooms, ratioB: ratioBamboo };
};

export const BarHorizontal = (props: TripleGraphProps) => {
  const { valueA, valueB } = props;

  const { ratioA, ratioB } = calculatePercentages(valueA, valueB);

  const ratioAnimationPropsA = useSpring({
    from: { width: '0%' },
    to: async (next) => {
      await next({ tension: 200, friction: 20, config: { duration: 200 } });
      for (let i = 0; i < 5; i++) {
        await next({
          width: `${Math.random() * 5 + 10}%`,
          config: { tension: 200, friction: 20, duration: 500 },
        });
      }
      await next({
        width: `${ratioA}%`,
        config: { duration: 100 },
      });
    },
  });
  const ratioAnimationPropsB = useSpring({
    from: { width: '0%' },
    to: async (next) => {
      await next({ tension: 200, friction: 20, config: { duration: 200 } });
      for (let i = 0; i < 5; i++) {
        await next({
          width: `${Math.random() * 5 + 10}%`,
          config: { tension: 200, friction: 20, duration: 500 },
        });
      }
      await next({
        width: `${ratioB}%`,
        config: { duration: 100 },
      });
    },
  });

  return (
    <div className="flex w-full flex-row items-center gap-2 py-4 shadow">
      <div className="relative flex h-44 w-full flex-row justify-between rounded-md shadow">
        <animated.div className={'bg-[#F59E0B]'} style={ratioAnimationPropsA} />
        <animated.div className={' bg-[#22C55E]'} style={ratioAnimationPropsB} />
        <span className="absolute left-1/2 top-0 h-full w-2 -translate-x-1/2 bg-main" />
      </div>
    </div>
  );
};

ひとまず適当にコピペしてもらえれば動くと思うので参考にしてみてください。

おわります

今回のプログラムは、同僚が事前調査をしてくれていたのでカスタマイズするだけで実装できました。すごくありがたいですね。ブログのネタを共有してくれる同僚とChatGPTには感謝しかありません。ちょっとしたUX改善ができるのが、アニメーションのいいところですがデザイン性は気を使わないといけないですね。あんまり頭の中にストックがないのがつらいところなので、サンプルを探すところから始まりそうです。

すんばらしいことにReact Spring Exampleが質の良いサンプルが転がっています。ここを見て学習をしていきましょう。

最近ChatGPTで、単線描画を出力させるのにはまっています。かわいいですよね。

ChatGPTで遊ぼう

React Springの記事はこちらになります。

 

 

 

アバター画像
About 龍:Ryu 106 Articles
2022年入社で主にフロントエンドの業務でTailwindと遊ぶ日々。お酒とうまいご飯が好きで、運動がちょっと嫌いなエンジニアです。しゃべれるエンジニアを目指しておしゃべりとブログ執筆に注力中(業務もね)//
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる