React Springでオープニングアニメーションを作成する

ReactSpringやってみる:オープニングアニメーション

ども!今回は、サイト初入場の際にアニメーションで迎え入れるための開発をやってみました。React SpringでSVGをうまく扱うことができるみたいなので、SVGイラストがあればいろいろな表現ができそうです。王道のフェードインとフェードアウト、あとは開幕アニメーションを作成しました。

ご挨拶

ども!業務での学びとプライベートで実装したものをいい塩梅で混ぜて投稿している龍ちゃんです。最近はブログを書くための仕組みが定着してきたので、苦なくかけるようになってきました。ほぼブログの担当者とかしているのが気になるところです…

さて!今回は、【React-Spring】のお話になります。ちょこっと調べれば、フロントエンドの画面に少しだけ彩を足すことができるライブラリがたくさんあります。多用しすぎると大変ですが、動いてみるものを見ると感動を覚えるということで、実装しています。

オープニングアニメーションという言葉が、実際にあるか定かではないのです。サイトに最初に訪れた時に流れるアニメーションのことを指しています。今回実装した結果としては、こちらの動画になります。

順番に文字が表示されて、それが上下に消えてから幕が開くイメージしています。

今回の実装に必要となるスキルや知識は以下になります。

  • Figma
  • 【Tailwind】基礎的な知識
  • 【react-spring】:useSpring, useSprings, useChainの知識

それでは解説を始めていきます。

設計

初めての作業になるので、しっかり前提を埋めておきたいと思います。基本的にほかの文字でも適応できるように流れを解説していきます。

アニメーションの流れ

アニメーションとしては、3つのパートで構成されています。

アニメーション設計

それぞれを順番に起動していくことで、完成します。

SVG素材を用意する

画像でも問題ないのですが、いろんな端末から呼び出されることも考慮してSVGで素材を用意していきます。せっかくなので、Figmaで作成していきます。

まずは適当な文字列を打ち込みましょう(フォントはお好みで決定してください)。文字を打ち込んだら、選択して、右クリックからの「線のアウトライン化」を選択します。

選のアウトライン化

「線のアウトライン化」が済んだコンポーネントをSVG形式でダウンロードしてください。ファイルを開いた際に、以下のように一文字ずつ分割されておけば準備完了です。

<svg width="357" height="85" viewBox="0 0 357 85" fill="none" xmlns="<http://www.w3.org/2000/svg>">
<path d="M288.018 14.2402C291.762 14.4322 294.258 14.4322 296.562 14.4322C301.65 14.4322 343.41 14.4322 348.114 14.4322C350.13 14.4322 353.586 14.4322 356.562 14.3362C356.37 16.6402 356.37 19.3282 356.37 21.7282C356.37 26.2402 356.37 65.4082 356.37 69.0562C356.37 72.1282 356.466 79.6162 356.562 80.6722H348.21C348.306 79.6162 348.402 74.1442 348.402 70.1122C348.402 66.5602 348.402 22.0162 348.402 22.0162H295.986C295.986 22.0162 295.986 66.1762 295.986 70.1122C295.986 73.2802 296.082 79.4242 296.082 80.6722H287.922C287.922 79.4242 288.114 72.4162 288.114 69.0562C288.114 65.1202 288.114 25.4722 288.114 21.7282C288.114 19.5202 288.114 16.6402 288.018 14.2402ZM351.57 67.7122V75.2002H292.146V67.7122H351.57Z" fill="black"/>
<path d="M255.277 11.0718C255.277 14.6238 258.061 17.4078 261.613 17.4078C265.069 17.4078 267.949 14.6238 267.949 11.0718C267.949 7.61583 265.069 4.73582 261.613 4.73582C258.061 4.73582 255.277 7.61583 255.277 11.0718ZM250.861 11.0718C250.861 5.11983 255.661 0.319824 261.613 0.319824C267.565 0.319824 272.365 5.11983 272.365 11.0718C272.365 17.0238 267.565 21.8238 261.613 21.8238C255.661 21.8238 250.861 17.0238 250.861 11.0718ZM259.213 17.5038C258.541 18.8478 258.157 20.4798 257.773 22.3038C255.661 32.3838 251.053 47.9358 243.373 57.7278C234.637 69.0558 223.213 77.8878 205.645 83.4558L199.117 76.2558C217.741 71.5518 228.493 63.3918 236.557 53.1198C243.373 44.4798 247.789 31.0398 249.133 21.8238C243.565 21.8238 205.549 21.8238 199.981 21.8238C196.141 21.8238 192.877 22.0158 190.477 22.2078V13.6638C193.069 13.9518 196.909 14.3358 200.077 14.3358C205.549 14.3358 243.853 14.3358 248.173 14.3358C249.709 14.3358 251.533 14.2398 253.357 13.7598L259.213 17.5038Z" fill="black"/>
<path d="M121.836 36.032C134.124 43.232 149.868 54.272 159.372 61.952L153.708 68.672C144.876 60.608 128.46 48.8 116.556 41.408L121.836 36.032ZM165.708 18.56C164.94 19.904 163.98 22.112 163.5 23.648C160.62 33.44 154.572 46.208 146.124 56.576C137.388 67.328 124.908 77.6 106.668 84.32L99.8521 78.272C117.708 72.896 130.764 62.72 139.404 52.448C146.796 43.616 152.844 31.424 155.052 22.496H119.532L122.604 15.584H153.132C155.724 15.584 157.836 15.296 159.372 14.72L165.708 18.56ZM133.356 4.63996C131.724 7.13595 129.996 10.4 129.036 12.224C123.372 22.784 112.524 37.28 97.1641 47.84L90.8281 42.944C107.244 32.672 117.132 18.272 121.548 9.43996C122.508 7.80795 124.044 4.35195 124.62 1.85596L133.356 4.63996Z" fill="black"/>
<path d="M13.5526 7.32812C26.0326 8.96013 51.7606 14.3361 63.8566 18.5601L60.7846 25.9521C49.1686 21.6321 24.0166 16.1601 10.7686 14.4321L13.5526 7.32812ZM9.13656 32.6721C22.2886 34.9761 45.6166 39.8721 57.5206 44.1921L54.5446 51.5841C43.4086 47.2641 19.8886 41.9841 6.25656 39.8721L9.13656 32.6721ZM3.95256 60.6081C19.9846 63.2001 47.9206 69.7281 61.0726 75.0081L57.7126 82.4001C45.0406 76.8321 16.4326 70.4001 0.976562 68.0001L3.95256 60.6081Z" fill="black"/>
</svg>

実装

それでは、実装に入っていきます。最後に完成系のコードを張り付けておくので、一度手元で動かしてみるのが良いかもしれません。動画の場合は、わかりやすいように色を付けていますが、解説するファイルでは白を付けています。

SVGファイルを分割する

一番最初の作業としては、動かしたい部分のSVGをreact-springの対応している形式に変更していく必要があります。先ほど作成したSVGファイルをエディターで開いて、一文字ずつ切り出していきます。

// ミ
const AnimatedPath1 = () => {
  return (
    <animated.path
      d="M64.9181 94.9283C65.0888 95.355 65.1314 95.6963 65.0461 95.9523C64.9608 96.123 64.8328 96.2937 64.6621 96.4643C64.3208 96.8057 64.1501 97.147 64.1501 97.4883C59.7128 97.5737 54.9768 97.1043 49.9421 96.0803C44.9074 94.971 39.5314 93.6483 33.8141 92.1123C29.5474 90.9177 25.2808 89.723 21.0141 88.5283C16.8328 87.2483 13.5048 85.9257 11.0301 84.5603C10.0061 83.963 8.81144 83.0243 7.44611 81.7443C6.16611 80.4643 4.92877 79.099 3.7341 77.6483C2.53944 76.1123 1.64344 74.6617 1.0461 73.2963C0.448771 71.931 0.363438 70.907 0.790104 70.2243C2.49677 70.2243 4.03277 70.7363 5.39811 71.7603C6.84877 72.699 8.42744 73.5097 10.1341 74.1923C11.8408 74.875 13.6754 75.4723 15.6381 75.9843C17.6861 76.411 19.6914 76.9657 21.6541 77.6483C25.4088 78.843 29.3341 80.123 33.4301 81.4883C37.6114 82.7683 41.6648 83.451 45.5901 83.5363C45.9314 83.5363 46.2301 83.4937 46.4861 83.4083C46.8274 83.323 47.0834 83.2803 47.2541 83.2803C47.5954 83.195 47.8941 83.1097 48.1501 83.0243C48.4061 82.939 48.7048 82.939 49.0461 83.0243C50.0701 83.195 51.3928 83.7923 53.0141 84.8163C54.6354 85.755 56.1714 86.779 57.6221 87.8883C59.1581 88.9123 60.2248 89.723 60.8221 90.3203C61.6754 91.003 62.4008 91.771 62.9981 92.6243C63.5954 93.4777 64.2354 94.2457 64.9181 94.9283ZM64.9181 26.8323C64.3208 27.9417 63.4248 28.7097 62.2301 29.1363C61.1208 29.563 59.8834 29.7763 58.5181 29.7763C57.2381 29.7763 55.9154 29.6483 54.5501 29.3923C53.1848 29.1363 51.8621 28.8803 50.5821 28.6243C49.1314 28.283 47.7661 28.027 46.4861 27.8563C45.2061 27.6857 44.1821 27.6857 43.4141 27.8563V27.3443C40.9394 26.6617 38.1234 26.0643 34.9661 25.5523C31.8088 24.955 28.5661 24.2723 25.2381 23.5043C21.9954 22.7363 18.9234 21.755 16.0221 20.5603C12.8648 19.1097 10.1341 17.3177 7.8301 15.1843C5.52611 12.9657 4.11811 10.1497 3.60611 6.73633C7.61677 8.78433 12.5661 10.5763 18.4541 12.1123C24.3421 13.563 30.1021 14.715 35.7341 15.5683C35.8194 15.5683 35.9474 15.5683 36.1181 15.5683C38.3368 15.9097 40.5554 16.1657 42.7741 16.3363C45.0781 16.507 46.9128 16.2083 48.2781 15.4403C51.6061 16.8057 54.7208 18.3843 57.6221 20.1763C60.6088 21.883 63.0408 24.1017 64.9181 26.8323ZM61.7181 60.6243C61.5474 62.075 60.9074 62.8003 59.7981 62.8003C55.8728 61.7763 51.2648 60.8803 45.9741 60.1123C40.7688 59.259 35.5208 58.235 30.2301 57.0403C25.0248 55.8457 20.3314 54.1817 16.1501 52.0483C13.3341 50.5977 10.9021 48.8057 8.85411 46.6723C6.89144 44.4537 5.56877 41.8937 4.8861 38.9923C7.4461 39.8457 10.1768 40.8697 13.0781 42.0643C16.0648 43.1737 19.1368 44.1123 22.2941 44.8803C25.3661 45.563 28.5661 46.2883 31.8941 47.0563C35.2221 47.8243 38.3794 48.2937 41.3661 48.4643C41.6221 48.4643 41.8781 48.4643 42.1341 48.4643C42.4754 48.4643 42.7741 48.4217 43.0301 48.3363C43.4568 48.3363 43.8408 48.3363 44.1821 48.3363C44.5234 48.251 44.8648 48.251 45.2061 48.3363C47.3394 48.6777 49.4301 49.5737 51.4781 51.0243C53.6114 52.3897 55.5741 53.9683 57.3661 55.7603C59.1581 57.467 60.6088 59.0883 61.7181 60.6243Z"
      fill="black"
    />
  );
};

一度全文をコピーしてきて、出力しながらやるほうが楽で良いです。以下のような状態に持っていきます。

const TEST = () => {
  return (
    <>
      <svg viewBox="0 0 462 100" fill="none" xmlns="<http://www.w3.org/2000/svg>">
        <AnimatedPath1 />
        <AnimatedPath2 />
        <AnimatedPath3 />
        <AnimatedPath4 />
      </svg>
    </>
  );
};

アニメーション実装

それでは、各アニメーションの解説を進めていきます。前提知識としてreact-springは、変更前と変更後のCSSを記述することで、その間をいい感じに埋めてプロパティの値を変更してくれます。イメージとしては以下です。

React Springの変更前と変更後の遷移

文字のフェードイン

//   文字が順番に出てくる
const [springs] = useSprings(items.length, (springIndex: number) => ({
  from: { fill: '#FFF' },
  to: { fill: '#000' },
  delay: 250 * springIndex,
  config: { duration: 2000 },
}));

背景色が白の場合で、塗りつぶしの色が白だと表示的には見えません。その状態から黒に塗りつぶし色を変化させることでフェードインを表現しています。CSSプロパティであるopacityを使うと背景色関係なしにフェードインとアウトを実装できるので、特別な事情がない限りはそちらが良いかもしれません。

useSpringsでは、特定の数のアニメーションを作成します。今回は、itemsの配列の数分のフェードインを少しづつずらしています。

文字を上下に動かしながらフェードアウト

  //   文字が一斉に動いて消える
  const [fadeSprings] = useSprings(items.length, (springIndex: number) => ({
    from: { opacity: 1, translateY: 0 },
    to: { opacity: 0, translateY: springIndex % 2 === 0 ? 100 : -100 },
    config: { duration: 250 },
  }));

こちらでは、文字を動かしながら透明度をゼロにすることでフェードアウトを実現しています。フェードアウトアニメーションでは、一文字ごとに上下別の方向に行ってほしいので、偶数奇数で方向を決定しています。

開幕!!

//   開幕!
const fadeParentRef = useSpring({
  from: { top: 0 },
  to: { top: -window.innerHeight },
  config: { duration: 1000 },
});

こちらでは、fixedで肯定しているページを上部に移動させることによって開幕感を演出しています。こちらのシステムでは、適応対象がfixedもしくはabsolute前提となっています。上方向に表示Window分ずらすことで画面外に押し出すテクニックです。

それぞれのアニメーションを順次実行させる

それぞれ、独立したアニメーションとなっているので順番を設定してあげる必要があります。そこで便利なのが、useChainです。使用方法としては、それぞれのアニメーションにSpringRefを紐づけて順序を設定します。

//   文字が順番に出てくる
const springsRef = useSpringRef();
const [springs] = useSprings(items.length, (springIndex: number) => ({
  ref: springsRef,
  from: { fill: '#FFFFFF' },
  to: { fill: '#000' },
  delay: 250 * springIndex,
  config: { duration: 250 },
}));

//   文字が一斉に動いて消える
const fadeoutRef = useSpringRef();
const [fadeSprings] = useSprings(items.length, (springIndex: number) => ({
  ref: fadeoutRef,
  from: { opacity: 1, translateY: 0 },
  to: { opacity: 0, translateY: springIndex % 2 === 0 ? 100 : -100 },
  config: { duration: 250 },
}));

//   開幕!
const parentRef = useSpringRef();
const fadeParentRef = useSpring({
  ref: parentRef,
  from: { top: 0 },
  to: { top: -window.innerHeight },
  config: { duration: 1000 },
});

useChain([springsRef, fadeoutRef, parentRef]);

これで、設計段階に描いた内容を実装することができました。あとは、適応していきます。

完成系

ここはさっくりと行きましょう。SVGを切り出したコンポーネントにPropsを付け加えます。これは、定義したアニメーション情報を受け渡すために使用します。

react-springでは、タグ名がHTMLとほぼ同等のものが用意されているので、適応したい要素にanimatedもしくはa を付けることで変換することができます。

今回の場合だと、animated.pathanimated.divが該当します。

import {
  SpringValue,
  animated,
  useChain,
  useSpring,
  useSpringRef,
  useSprings,
} from '@react-spring/web';

type AnimationPathProps = {
  fill: SpringValue<string>;
  opacity: SpringValue<number>;
  translateY: SpringValue<number>;
};

// ミ
const AnimatedPath1 = (props: AnimationPathProps) => {
  const { fill, opacity, translateY } = props;
  return (
    <animated.path
      style={{ fill, opacity, translateY }}
      d="M64.9181 94.9283C65.0888 95.355 65.1314 95.6963 65.0461 95.9523C64.9608 96.123 64.8328 96.2937 64.6621 96.4643C64.3208 96.8057 64.1501 97.147 64.1501 97.4883C59.7128 97.5737 54.9768 97.1043 49.9421 96.0803C44.9074 94.971 39.5314 93.6483 33.8141 92.1123C29.5474 90.9177 25.2808 89.723 21.0141 88.5283C16.8328 87.2483 13.5048 85.9257 11.0301 84.5603C10.0061 83.963 8.81144 83.0243 7.44611 81.7443C6.16611 80.4643 4.92877 79.099 3.7341 77.6483C2.53944 76.1123 1.64344 74.6617 1.0461 73.2963C0.448771 71.931 0.363438 70.907 0.790104 70.2243C2.49677 70.2243 4.03277 70.7363 5.39811 71.7603C6.84877 72.699 8.42744 73.5097 10.1341 74.1923C11.8408 74.875 13.6754 75.4723 15.6381 75.9843C17.6861 76.411 19.6914 76.9657 21.6541 77.6483C25.4088 78.843 29.3341 80.123 33.4301 81.4883C37.6114 82.7683 41.6648 83.451 45.5901 83.5363C45.9314 83.5363 46.2301 83.4937 46.4861 83.4083C46.8274 83.323 47.0834 83.2803 47.2541 83.2803C47.5954 83.195 47.8941 83.1097 48.1501 83.0243C48.4061 82.939 48.7048 82.939 49.0461 83.0243C50.0701 83.195 51.3928 83.7923 53.0141 84.8163C54.6354 85.755 56.1714 86.779 57.6221 87.8883C59.1581 88.9123 60.2248 89.723 60.8221 90.3203C61.6754 91.003 62.4008 91.771 62.9981 92.6243C63.5954 93.4777 64.2354 94.2457 64.9181 94.9283ZM64.9181 26.8323C64.3208 27.9417 63.4248 28.7097 62.2301 29.1363C61.1208 29.563 59.8834 29.7763 58.5181 29.7763C57.2381 29.7763 55.9154 29.6483 54.5501 29.3923C53.1848 29.1363 51.8621 28.8803 50.5821 28.6243C49.1314 28.283 47.7661 28.027 46.4861 27.8563C45.2061 27.6857 44.1821 27.6857 43.4141 27.8563V27.3443C40.9394 26.6617 38.1234 26.0643 34.9661 25.5523C31.8088 24.955 28.5661 24.2723 25.2381 23.5043C21.9954 22.7363 18.9234 21.755 16.0221 20.5603C12.8648 19.1097 10.1341 17.3177 7.8301 15.1843C5.52611 12.9657 4.11811 10.1497 3.60611 6.73633C7.61677 8.78433 12.5661 10.5763 18.4541 12.1123C24.3421 13.563 30.1021 14.715 35.7341 15.5683C35.8194 15.5683 35.9474 15.5683 36.1181 15.5683C38.3368 15.9097 40.5554 16.1657 42.7741 16.3363C45.0781 16.507 46.9128 16.2083 48.2781 15.4403C51.6061 16.8057 54.7208 18.3843 57.6221 20.1763C60.6088 21.883 63.0408 24.1017 64.9181 26.8323ZM61.7181 60.6243C61.5474 62.075 60.9074 62.8003 59.7981 62.8003C55.8728 61.7763 51.2648 60.8803 45.9741 60.1123C40.7688 59.259 35.5208 58.235 30.2301 57.0403C25.0248 55.8457 20.3314 54.1817 16.1501 52.0483C13.3341 50.5977 10.9021 48.8057 8.85411 46.6723C6.89144 44.4537 5.56877 41.8937 4.8861 38.9923C7.4461 39.8457 10.1768 40.8697 13.0781 42.0643C16.0648 43.1737 19.1368 44.1123 22.2941 44.8803C25.3661 45.563 28.5661 46.2883 31.8941 47.0563C35.2221 47.8243 38.3794 48.2937 41.3661 48.4643C41.6221 48.4643 41.8781 48.4643 42.1341 48.4643C42.4754 48.4643 42.7741 48.4217 43.0301 48.3363C43.4568 48.3363 43.8408 48.3363 44.1821 48.3363C44.5234 48.251 44.8648 48.251 45.2061 48.3363C47.3394 48.6777 49.4301 49.5737 51.4781 51.0243C53.6114 52.3897 55.5741 53.9683 57.3661 55.7603C59.1581 57.467 60.6088 59.0883 61.7181 60.6243Z"
      fill="black"
    />
  );
};

// タ
const AnimatedPath2 = (props: AnimationPathProps) => {
  const { fill, opacity, translateY } = props;
  return (
    <animated.path
      style={{ fill, opacity, translateY }}
      d="M200.219 25.8074C199.622 26.1487 199.067 26.5327 198.555 26.9594C198.043 27.3861 197.659 27.9834 197.403 28.7514C195.611 28.2394 194.161 28.3674 193.051 29.1354C192.027 29.8181 191.089 30.6714 190.235 31.6954C189.723 32.2074 189.211 32.7194 188.699 33.2314C188.187 33.7434 187.59 34.1701 186.907 34.5114C186.907 34.6821 186.95 34.9381 187.035 35.2794C187.121 35.5354 187.163 35.8341 187.163 36.1754C187.249 36.4314 187.249 36.7727 187.163 37.1994C186.907 37.1994 186.566 37.2847 186.139 37.4554C185.798 37.6261 185.499 37.6687 185.243 37.5834C184.561 39.8021 183.75 41.8927 182.811 43.8554C181.873 45.8181 181.062 47.9514 180.379 50.2554L178.715 50.1274C179.142 51.2367 179.185 52.1754 178.843 52.9434C178.587 53.6261 178.246 54.3514 177.819 55.1194C177.393 55.7167 177.009 56.3567 176.667 57.0394C176.326 57.6367 176.07 58.4047 175.899 59.3434C175.473 59.4287 175.089 59.5567 174.747 59.7274C174.406 59.8127 174.022 59.9407 173.595 60.1114C173.595 60.4527 173.766 60.4954 174.107 60.2394C174.193 60.1541 174.321 60.0687 174.491 59.9834C174.747 59.8981 175.003 59.9407 175.259 60.1114C175.259 60.7087 175.046 61.0501 174.619 61.1354C174.278 61.2207 173.851 61.2634 173.339 61.2634C172.657 61.2634 172.187 61.3487 171.931 61.5194C172.102 61.9461 172.529 62.0741 173.211 61.9034C173.809 61.7327 174.15 61.7754 174.235 62.0314C173.638 63.1407 173.041 64.2074 172.443 65.2314C171.846 66.2554 171.206 67.3221 170.523 68.4314C170.267 68.1754 169.883 68.0474 169.371 68.0474C169.115 68.3887 169.243 68.6874 169.755 68.9434C170.097 69.1994 170.182 69.4554 170.011 69.7114C169.67 69.9674 169.329 70.0527 168.987 69.9674C168.731 69.9674 168.518 69.9674 168.347 69.9674C168.518 70.7354 168.347 71.6314 167.835 72.6554C167.409 73.6794 166.854 74.5754 166.171 75.3434C165.489 76.0261 164.849 76.3674 164.251 76.3674C164.166 76.7087 164.337 76.9647 164.763 77.1354C165.19 77.2207 165.403 77.2634 165.403 77.2634C165.062 77.3487 164.806 77.5621 164.635 77.9034C164.465 78.1594 164.294 78.4154 164.123 78.6714C164.038 78.6714 163.953 78.5861 163.867 78.4154C163.697 78.0741 163.526 78.0314 163.355 78.2874C163.355 78.8847 163.185 79.5674 162.843 80.3354C162.587 81.1034 161.947 81.5727 160.923 81.7434V80.5914C160.582 80.7621 160.326 80.9754 160.155 81.2314C159.985 81.4021 159.814 81.6581 159.643 81.9994C159.387 82.3407 159.089 82.6821 158.747 83.0234C158.406 83.3647 157.894 83.4928 157.211 83.4074C157.126 83.8341 157.339 84.0047 157.851 83.9194C158.193 83.9194 158.406 83.9621 158.491 84.0474C158.918 83.7914 159.174 83.4927 159.259 83.1514C159.345 82.7247 159.601 82.3834 160.027 82.1274C160.198 82.2981 160.411 82.4261 160.667 82.5114C160.923 82.5114 161.094 82.6394 161.179 82.8954C160.753 83.8341 160.198 84.4314 159.515 84.6874C158.833 84.9434 158.193 85.0714 157.595 85.0714C157.169 85.1568 156.785 85.2421 156.443 85.3274C156.187 85.3274 155.931 85.4554 155.675 85.7114C155.931 85.9674 155.974 86.2661 155.803 86.6074C155.718 86.9487 155.249 87.0341 154.395 86.8634C154.31 87.2047 154.481 87.3754 154.907 87.3754C155.334 87.3754 155.547 87.3754 155.547 87.3754C154.779 87.5461 154.225 87.9301 153.883 88.5274C153.542 89.1247 153.158 89.6794 152.731 90.1914C152.305 90.7034 151.622 90.9594 150.683 90.9594C150.683 91.1301 150.769 91.3007 150.939 91.4714C151.281 91.7274 151.409 91.9834 151.323 92.2394C150.47 92.3248 149.873 92.6661 149.531 93.2634C149.19 93.8608 148.721 94.3727 148.123 94.7994C147.867 94.7141 147.739 94.5007 147.739 94.1594C147.825 93.7327 147.867 93.5194 147.867 93.5194C147.526 94.5434 146.715 95.4394 145.435 96.2074C144.241 96.9754 143.131 97.8288 142.107 98.7674C141.595 98.5968 141.425 98.3407 141.595 97.9994C141.851 97.7434 142.107 97.5301 142.363 97.3594C142.449 97.2741 142.491 97.2314 142.491 97.2314C142.235 96.9754 141.851 97.0181 141.339 97.3594C141.083 97.5301 140.827 97.6581 140.571 97.7434C140.315 97.8287 140.059 97.6154 139.803 97.1034C139.462 97.1034 139.377 97.2314 139.547 97.4874C139.803 97.9141 139.846 98.2981 139.675 98.6394C138.907 98.5541 138.139 98.5541 137.371 98.6394C136.689 98.8101 136.006 98.9807 135.323 99.1514C134.129 99.4074 132.891 99.5781 131.611 99.6634C130.417 99.7487 129.094 99.3647 127.643 98.5114C130.715 96.8047 133.617 94.8847 136.347 92.7514C139.078 90.6181 141.467 88.1007 143.515 85.1994C143.515 85.1994 143.473 85.3701 143.387 85.7114C143.387 85.9674 143.43 86.1808 143.515 86.3514C145.222 84.3888 146.545 82.7247 147.483 81.3594C148.422 79.9941 149.958 78.4154 152.091 76.6234C152.091 76.3674 151.963 76.2394 151.707 76.2394C151.537 76.2394 151.323 76.1967 151.067 76.1114C152.006 74.6607 153.073 73.2101 154.267 71.7594C155.547 70.2234 156.571 68.5167 157.339 66.6394C157.595 66.6394 157.766 66.8527 157.851 67.2794C157.937 67.7914 158.15 68.0047 158.491 67.9194C158.321 67.3221 158.406 66.4687 158.747 65.3594C159.089 64.1647 159.601 63.2261 160.283 62.5434C160.454 62.1167 160.113 61.8181 159.259 61.6474C159.174 61.6474 159.089 61.6474 159.003 61.6474C157.809 59.7701 156.273 58.1914 154.395 56.9114C152.603 55.5461 150.897 54.1381 149.275 52.6874C148.934 50.9807 148.251 49.5727 147.227 48.4634C146.289 47.3541 145.265 46.2874 144.155 45.2634C143.046 44.1541 142.193 42.8741 141.595 41.4234C140.23 42.6181 139.206 43.9407 138.523 45.3914C137.926 46.8421 136.774 47.7381 135.067 48.0794C135.067 48.3354 135.153 48.5061 135.323 48.5914C135.494 48.5914 135.579 48.5914 135.579 48.5914C134.47 49.1034 133.489 49.9141 132.635 51.0234C131.782 52.1327 130.801 53.0287 129.691 53.7114C128.838 54.2234 127.899 54.5221 126.875 54.6074C125.937 54.6927 124.913 54.6927 123.803 54.6074C123.035 54.6074 122.267 54.6074 121.499 54.6074C120.731 54.6074 119.963 54.6501 119.195 54.7354C120.39 53.5407 121.542 52.2181 122.651 50.7674C123.761 49.2314 124.955 48.2074 126.235 47.6954C125.894 46.9274 126.065 46.0741 126.747 45.1354C127.515 44.1114 128.283 43.1727 129.051 42.3194C129.307 42.0634 129.521 41.8074 129.691 41.5514C129.947 41.2954 130.161 41.0394 130.331 40.7834C130.417 40.6981 130.459 40.4847 130.459 40.1434C130.374 39.8021 130.374 39.5461 130.459 39.3754C131.739 37.3274 133.233 35.1087 134.939 32.7194C136.646 30.3301 138.267 27.9407 139.803 25.5514C141.339 23.0767 142.449 20.6874 143.131 18.3834C142.363 16.9327 141.339 15.6954 140.059 14.6714C138.865 13.6474 137.67 12.5807 136.475 11.4714C137.414 10.6181 138.779 10.1914 140.571 10.1914C142.363 10.1914 144.155 10.4047 145.947 10.8314C147.825 11.2581 149.233 11.6847 150.171 12.1114C151.707 12.7941 153.03 13.8181 154.139 15.1834C155.334 16.5487 156.87 17.4447 158.747 17.8714C159.515 18.0421 160.411 18.1274 161.435 18.1274C162.545 18.0421 163.697 17.9567 164.891 17.8714C166.001 17.7861 167.11 17.7434 168.219 17.7434C169.329 17.6581 170.353 17.6581 171.291 17.7434C172.059 17.8287 172.913 17.8287 173.851 17.7434C174.875 17.6581 176.113 17.5301 177.563 17.3594H177.691C178.033 17.2741 178.161 17.0181 178.075 16.5914C177.99 16.1647 178.246 15.9087 178.843 15.8234C181.403 16.1647 184.049 16.7194 186.779 17.4874C189.51 18.2554 192.07 19.3221 194.459 20.6874C196.849 21.9674 198.769 23.6741 200.219 25.8074ZM175.515 26.1914C174.235 25.7647 172.827 25.5514 171.291 25.5514C169.841 25.5514 168.347 25.6367 166.811 25.8074C164.849 25.8927 162.843 25.9354 160.795 25.9354C158.833 25.8501 156.913 25.3807 155.035 24.5274C154.438 24.6981 153.883 24.9541 153.371 25.2954C152.859 25.6367 152.305 25.9354 151.707 26.1914C151.537 27.3861 151.067 28.4527 150.299 29.3914C149.617 30.2447 148.891 31.0127 148.123 31.6954C147.27 32.5487 146.545 33.4021 145.947 34.2554C145.435 35.0234 145.393 35.9194 145.819 36.9434C145.137 36.9434 144.667 37.1567 144.411 37.5834C144.155 38.0101 143.942 38.4794 143.771 38.9914C143.601 39.2474 143.43 39.5461 143.259 39.8874C143.174 40.2287 143.046 40.4847 142.875 40.6554C144.411 40.8261 146.246 41.2954 148.379 42.0634C150.513 42.7461 152.646 43.6847 154.779 44.8794C156.913 45.9887 158.79 47.2687 160.411 48.7194C162.033 50.1701 163.142 51.7061 163.739 53.3274C166.299 49.4021 168.646 45.3061 170.779 41.0394C172.998 36.7727 174.577 31.8234 175.515 26.1914Z"
      fill="black"
    />
  );
};

// プ
const AnimatedPath3 = (props: AnimationPathProps) => {
  const { fill, opacity, translateY } = props;
  return (
    <animated.path
      style={{ fill, opacity, translateY }}
      d="M332.442 30.8008C331.077 31.3981 329.882 32.2514 328.858 33.3608C327.834 34.4701 326.64 35.4088 325.274 36.1768C323.994 38.2248 322.842 40.4008 321.818 42.7048C320.88 44.9234 319.429 46.7581 317.466 48.2088C317.722 49.0621 317.594 49.6594 317.082 50.0008C316.656 50.3421 316.101 50.5981 315.418 50.7688C315.418 51.5368 315.248 52.1768 314.906 52.6888C314.565 53.2008 314.138 53.6701 313.626 54.0968C313.2 54.5234 312.816 54.9928 312.474 55.5048C312.133 55.9314 311.92 56.4861 311.834 57.1688C311.322 57.4248 311.152 57.2114 311.322 56.5288C310.81 56.4434 310.469 56.6994 310.298 57.2968C310.128 57.8088 310.213 58.2781 310.554 58.7048C310.042 59.5581 309.573 60.2834 309.146 60.8808C308.72 61.4781 307.952 61.8621 306.842 62.0328C306.928 62.7154 306.672 63.3981 306.074 64.0808C305.562 64.6781 304.965 65.3181 304.282 66.0008C303.6 66.5981 303.002 67.2381 302.49 67.9208C301.978 68.5181 301.808 69.0728 301.978 69.5848C302.064 69.9261 301.978 70.2248 301.722 70.4808C301.466 70.7368 301.168 70.5661 300.826 69.9688C300.826 69.9688 300.784 70.0114 300.698 70.0968C300.528 70.3528 300.357 70.6514 300.186 70.9928C300.016 71.3341 300.016 71.7608 300.186 72.2728C299.76 72.9554 299.333 72.9554 298.906 72.2728C296.688 74.4914 294.725 76.7528 293.018 79.0568C292.592 79.3981 292.208 79.5261 291.866 79.4408C291.525 79.3554 291.226 79.6114 290.97 80.2088C290.714 80.2088 290.544 80.1234 290.458 79.9528C290.373 79.6968 290.202 79.5261 289.946 79.4408C289.946 79.6968 289.776 79.9954 289.434 80.3368C288.922 80.7634 288.709 81.1901 288.794 81.6168C288.624 81.7021 288.325 81.8728 287.898 82.1288C287.557 82.2994 287.216 82.5128 286.874 82.7688C286.533 83.0248 286.405 83.4088 286.49 83.9208C285.893 83.9208 285.338 84.1341 284.826 84.5608C284.4 84.9874 284.016 85.4568 283.674 85.9688C283.248 86.4808 282.778 86.9501 282.266 87.3768C281.84 87.8034 281.285 87.9314 280.602 87.7608C280.261 88.0168 280.048 88.4008 279.962 88.9128C279.962 89.4248 279.749 89.7661 279.322 89.9368C278.469 89.5101 277.616 89.7661 276.762 90.7048C275.994 91.6434 275.482 92.5394 275.226 93.3928C273.861 94.2461 272.538 94.6728 271.258 94.6728C270.064 94.5874 268.997 95.1421 268.058 96.3368C267.802 96.1661 267.461 96.1234 267.034 96.2088C266.522 96.2941 266.138 96.1234 265.882 95.6968C265.2 96.2088 264.602 96.4648 264.09 96.4648C263.578 96.3794 263.024 96.2514 262.426 96.0808C262.17 95.9101 261.872 95.8248 261.53 95.8248C261.189 95.7394 260.848 95.6968 260.506 95.6968C260.506 95.6968 260.72 95.4834 261.146 95.0568C261.658 94.6301 261.573 94.2888 260.89 94.0328C260.976 93.6061 261.274 93.4781 261.786 93.6488C262.384 93.7341 262.725 93.8621 262.81 94.0328C263.152 94.0328 263.28 93.7768 263.194 93.2648C263.194 92.5821 263.45 92.3688 263.962 92.6248C264.218 92.7101 264.56 92.5821 264.986 92.2408C265.157 92.0701 265.328 91.8994 265.498 91.7288C265.754 91.5581 266.01 91.4728 266.266 91.4728C266.266 91.0461 266.053 90.9608 265.626 91.2168C265.285 91.3874 265.029 91.6008 264.858 91.8568C264.688 91.6008 264.816 91.2594 265.242 90.8328C265.754 90.4061 266.266 89.9794 266.778 89.5528C267.034 89.3821 267.205 89.2541 267.29 89.1688C267.632 89.7661 268.229 89.6381 269.082 88.7848C270.021 87.9314 270.832 86.9501 271.514 85.8408C272.538 84.8168 273.648 83.9208 274.842 83.1528C276.122 82.2994 276.762 81.3181 276.762 80.2088C277.786 79.6968 278.81 78.7581 279.834 77.3928C280.944 76.0274 282.053 74.5768 283.162 73.0408C284.272 71.5048 285.424 70.0968 286.618 68.8168C287.813 67.5368 289.05 66.6834 290.33 66.2568C290.416 65.7448 290.16 65.4888 289.562 65.4888C292.037 62.2461 294.469 59.0888 296.858 56.0168C299.333 52.8594 301.68 49.6168 303.898 46.2888C303.898 46.2888 303.941 46.0754 304.026 45.6488C304.112 45.2221 303.813 44.9661 303.13 44.8808C304.24 42.6621 305.477 40.5714 306.842 38.6088C308.293 36.6461 309.445 34.4701 310.298 32.0808C304.752 31.9954 298.693 32.2088 292.122 32.7208C285.552 33.2328 278.938 33.9154 272.282 34.7688C265.712 35.6221 259.568 36.6034 253.85 37.7128C253.082 37.0301 252.016 35.9208 250.65 34.3848C249.37 32.8488 248.09 31.0994 246.81 29.1368C245.616 27.1741 244.677 25.2114 243.994 23.2488C243.738 22.5661 243.994 22.0968 244.762 21.8408C246.469 22.5234 248.304 23.3768 250.266 24.4008C252.229 25.3394 253.552 25.9794 254.234 26.3208C258.757 26.2354 263.28 25.9368 267.802 25.4248C272.41 24.8274 277.018 24.3581 281.626 24.0168C283.162 23.8461 284.656 23.7608 286.106 23.7608C287.642 23.7608 289.136 23.7608 290.586 23.7608C291.866 23.7608 293.146 23.7608 294.426 23.7608C295.706 23.7608 296.986 23.7181 298.266 23.6328C299.461 23.5474 301.168 23.4194 303.386 23.2488C305.605 22.9928 307.738 22.6514 309.786 22.2248C311.834 21.7981 313.114 21.2861 313.626 20.6888C314.224 20.6034 314.778 20.6034 315.29 20.6888C315.802 20.7741 316.314 20.9021 316.826 21.0728C317.338 21.2434 317.893 21.4141 318.49 21.5848C319.173 21.6701 319.941 21.6274 320.794 21.4568C321.733 22.5661 323.056 23.4621 324.762 24.1448C326.469 24.7421 328.09 25.5101 329.626 26.4488C331.162 27.3021 332.101 28.7528 332.442 30.8008ZM345.242 16.5928C344.645 17.1901 343.92 17.7448 343.066 18.2568C342.298 18.6834 341.786 19.4088 341.53 20.4328C340.336 20.4328 339.354 20.6034 338.586 20.9448C337.818 21.2008 336.922 21.6274 335.898 22.2248C334.96 21.5421 333.808 21.1154 332.442 20.9448C331.162 20.7741 329.925 20.4754 328.73 20.0488C327.194 18.0861 326.128 15.9954 325.53 13.7768C325.018 11.5581 325.061 9.5101 325.658 7.63276C326.256 5.58476 327.493 3.92076 329.37 2.64076C331.333 1.27543 333.978 0.678092 337.306 0.848756C340.549 1.70209 342.853 3.57943 344.218 6.48076C345.669 9.38209 346.01 12.7528 345.242 16.5928ZM338.586 9.04076C337.136 8.01676 335.77 7.63276 334.49 7.88876C333.637 8.14476 332.912 8.69943 332.314 9.55276C331.802 10.3208 331.546 11.0888 331.546 11.8568C331.546 13.0514 332.101 14.0754 333.21 14.9288C334.405 15.6968 336.069 15.4834 338.202 14.2888C338.714 13.5208 339.013 12.6674 339.098 11.7288C339.269 10.7901 339.098 9.89409 338.586 9.04076Z"
      fill="black"
    />
  );
};

// ロ
const AnimatedPath4 = (props: AnimationPathProps) => {
  const { fill, opacity, translateY } = props;
  return (
    <animated.path
      style={{ fill, opacity, translateY }}
      d="M460.949 37.7111C458.048 38.3084 455.914 39.8017 454.549 42.1911C453.269 44.4951 452.33 47.2257 451.733 50.3831C451.136 53.2844 450.666 56.3564 450.325 59.5991C450.069 62.8417 449.472 65.7857 448.533 68.4311C448.192 68.2604 448.021 67.7484 448.021 66.8951C448.106 65.9564 448.149 65.4871 448.149 65.4871C447.466 66.8524 447.082 68.3031 446.997 69.8391C446.997 71.2897 446.912 72.6977 446.741 74.0631C446.656 75.4284 446.144 76.6657 445.205 77.7751C445.888 78.3724 446.656 79.1404 447.509 80.0791C448.362 80.9324 448.832 81.8284 448.917 82.7671C448.405 83.1937 447.808 83.4497 447.125 83.5351C446.442 83.5351 445.76 83.5351 445.077 83.5351C444.309 83.5351 443.584 83.5777 442.901 83.6631C442.218 83.7484 441.621 84.0471 441.109 84.5591C436.245 83.3644 430.869 82.8524 424.981 83.0231C419.178 83.1937 413.546 83.4497 408.085 83.7911C406.89 83.8764 405.696 83.9617 404.501 84.0471C403.306 84.0471 402.154 84.0897 401.045 84.1751C398.741 84.2604 396.736 84.5591 395.029 85.0711C393.322 85.4977 391.744 86.4791 390.293 88.0151C388.501 87.0764 387.05 85.7964 385.941 84.1751C384.832 82.5537 383.722 80.8897 382.613 79.1831C382.442 78.7564 382.528 78.3724 382.869 78.0311C383.125 77.6897 383.253 77.3484 383.253 77.0071C382.314 70.6071 381.674 64.0791 381.333 57.4231C381.077 50.7671 380.352 44.3244 379.157 38.0951C378.901 37.6684 378.56 37.2417 378.133 36.8151C377.792 36.3031 377.408 35.8337 376.981 35.4071C376.042 34.3831 375.189 33.3164 374.421 32.2071C373.738 31.0977 373.653 29.9031 374.165 28.6231C375.104 28.7084 375.786 28.9217 376.213 29.2631C376.64 29.6044 377.194 29.7751 377.877 29.7751C378.645 29.7751 379.157 29.5617 379.413 29.1351C379.669 28.7084 380.138 28.4524 380.821 28.3671C384.149 28.1964 387.648 28.0257 391.317 27.8551C395.072 27.5991 398.314 27.4711 401.045 27.4711C402.666 27.4711 404.33 27.3431 406.037 27.0871C407.829 26.8311 409.664 26.6604 411.541 26.5751C413.504 26.4044 415.509 26.3191 417.557 26.3191C419.69 26.3191 421.738 26.3617 423.701 26.4471C427.114 26.4471 430.4 26.4044 433.557 26.3191C436.8 26.2337 439.658 25.8071 442.133 25.0391C445.29 25.4657 448.533 26.2764 451.861 27.4711C455.189 28.5804 458.133 30.3297 460.693 32.7191C461.034 33.2311 461.205 33.7004 461.205 34.1271C461.205 34.5537 461.162 35.0231 461.077 35.5351C460.992 35.7911 460.906 36.1324 460.821 36.5591C460.821 36.9004 460.864 37.2844 460.949 37.7111ZM439.189 33.1031C434.325 33.0177 429.418 33.0604 424.469 33.2311C419.52 33.4017 414.4 33.7004 409.109 34.1271C405.952 34.3831 402.709 34.5537 399.381 34.6391C396.053 34.7244 392.896 35.4071 389.909 36.6871C389.653 37.0284 389.61 37.3271 389.781 37.5831C389.952 37.8391 390.165 38.0524 390.421 38.2231C390.677 38.4791 390.89 38.7351 391.061 38.9911C391.232 39.1617 391.317 39.4177 391.317 39.7591C390.976 45.8177 391.018 51.6204 391.445 57.1671C391.872 62.7137 392.384 68.2604 392.981 73.8071C392.981 74.3191 392.981 74.8311 392.981 75.3431C393.066 75.7697 393.152 76.1964 393.237 76.6231C396.906 76.2817 400.661 76.0257 404.501 75.8551C408.341 75.5991 412.096 75.3857 415.765 75.2151C416.618 75.2151 417.514 75.2151 418.453 75.2151C419.477 75.2151 420.501 75.2577 421.525 75.3431C423.829 75.5137 426.218 75.5991 428.693 75.5991C431.168 75.5137 433.6 75.0444 435.989 74.1911C436.074 72.9111 436.202 71.6737 436.373 70.4791C436.629 69.2844 436.842 68.0897 437.013 66.8951C437.354 64.9324 437.653 62.9271 437.909 60.8791C438.165 58.8311 438.25 56.6977 438.165 54.4791C439.104 51.2364 439.744 47.6951 440.085 43.8551C440.426 39.9297 440.128 36.3457 439.189 33.1031ZM448.149 69.3271C448.661 69.4124 448.746 70.1804 448.405 71.6311C448.149 73.0817 447.808 74.2764 447.381 75.2151C447.381 75.2151 447.381 74.8311 447.381 74.0631C447.466 73.2097 447.552 72.3137 447.637 71.3751C447.808 70.3511 447.978 69.6684 448.149 69.3271Z"
      fill="black"
    />
  );
};

export const TopAnimation = () => {
  const items = [AnimatedPath1, AnimatedPath2, AnimatedPath3, AnimatedPath4];

  //   文字が順番に出てくる
  const springsRef = useSpringRef();
  const [springs] = useSprings(items.length, (springIndex: number) => ({
    ref: springsRef,
    from: { fill: '#FFFFFF' },
    to: { fill: '#000' },
    delay: 250 * springIndex,
    config: { duration: 250 },
  }));

  //   文字が一斉に動いて消える
  const fadeoutRef = useSpringRef();
  const [fadeSprings] = useSprings(items.length, (springIndex: number) => ({
    ref: fadeoutRef,
    from: { opacity: 1, translateY: 0 },
    to: { opacity: 0, translateY: springIndex % 2 === 0 ? 100 : -100 },
    config: { duration: 250 },
  }));

  //   開幕!
  const parentRef = useSpringRef();
  const fadeParentRef = useSpring({
    ref: parentRef,
    from: { top: 0 },
    to: { top: -window.innerHeight },
    config: { duration: 1000 },
  });

  useChain([springsRef, fadeoutRef, parentRef]);

  return (
    <animated.div
      className={
        'fixed left-0 top-0 z-50 flex h-screen w-full items-center justify-center bg-white'
      }
      style={fadeParentRef}
    >
      <svg
        viewBox="0 0 462 100"
        fill="none"
        className="h-1/2 w-1/2"
        xmlns="<http://www.w3.org/2000/svg>"
      >
        {items.map((Item, index) => (
          <Item
            key={index}
            fill={springs[index].fill}
            opacity={fadeSprings[index].opacity}
            translateY={fadeSprings[index].translateY}
          />
        ))}
      </svg>
    </animated.div>
  );
};

コピーしていろいろカスタマイズしてみてください。もし、いい作品できたら共有待ってます。

付録:複数アニメーションを紐づけたらuseChainが機能しない

はい!詰まった部分の共有情報を書いていこうと思います。

今回、フェードインとフェードアウトをそれぞれ異なる方法で実装しました。それにはわけがあります。react-sprinの場合だと、一つの定義内に複数の状態遷移を持たせることが可能です。今回だと、「文字のフェードイン」と「文字を上下に動かしながらフェードアウト」は以下のように書くことができます。配列指定と関数指定があるよ!!公式のページはここね!!

const [springs] = useSprings(items.length, (springIndex: number) => ({
    ref: springsRef,
    from: { opacity: 0, translateY: 0 },
    to: [
      {
        opacity: 1,
        translateY: 0,
        delay: 250 * springIndex,
        config: { duration: 1000 },
      },
      {
        opacity: 0,
        translateY: springIndex % 2 === 0 ? 100 : -100,
        delay: 250 * (items.length - springIndex),
        config: { duration: 250 },
      },
    ],
  }));

実行のタイミングを合わせる部分が、ちょっと頭使いますがこちらの方が自然だと思います。ではなぜやらなかったのか??

おそらくバグです。さまよって検索してたら、Isuueが上がっていました。とりあえず、自分とおんなじ状況の方を見つけることができて安心しています。というわけで、対応として二つ上げておきます。

  • useChainを使わない実装:実行時間と遅延の計算式を書けば…コスト高め
  • 処理を分散する:今回は何とかなりましたが、フェードインとフェードアウトだけでよかった
  • Controllerを使用する:API経由で動的にアニメーションを作成する

この辺りが考えられそうです。

おわります

ちょっとしたバグに苦しめられましたが、やりたい形には実装することができたので良かったです。定期的に新しい技術に入門しておかないと、おいておかれるのがフロントエンドの界隈だと思っています。最近はブロガーになりつつあるので、ちゃんとアクセス解析をして書く内容も上げていかなきゃいけないと思っています。半分ぐらいは好きな記事を書くので、体感はあまり変わらない予定です。

噂ですけど、ブログのデザインリニューアルするかもですよ( *´艸`)

これまで書いたreact-sprin関連のブログ載せておきます!

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

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

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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です