みかづきブログ・カスタム

基本的にはちょちょいのほいです。

GSAPをつかってuseRefの値をアニメーションさせる 🎥

Next.jsでDOMをアニメーションさせようと思った際、いつもはトゥイーンを自作していたのですが、いい感じのライブラリがあれば使いたいなと常々思っていました。
そこで、今回はReact + GSAPでDOMのアニメーションを試みてみようと思います。

greensock.com

ソースコード(抜粋)

import { gsap } from 'gsap';
import { useEffect, useRef, useState } from 'react';

export function IndecPage() {
  const sizeRef = useRef(100);
  const timerRef = useRef(-1);
  const [ size, setSize ] = useState(sizeRef.current);

  useEffect(() => {
    window.clearInterval(timerRef.current);
    timerRef.current = window.setInterval(changeSize, 1000);
  }, []);

  function changeSize() {
    gsap.to(sizeRef, {
      current: 100 + 200 * Math.random(),
      duration: 1,
      onUpdate: () => {
        setSize(sizeRef.current);
      }
    });
  }

  return (
    <section>
      <div
        style={{
          width: `${ size }px`,
          height: `${ size }px`
        }}
      />
    </section>
  );
}


解説

ドキュメントgsap.to を見ると、 サンプルでは第一引数にアニメーションさせたいDOMのセレクタを文字列で渡しています。

greensock.com

しかし、

targets - the object(s) whose properties you want to animate. This can be selector text like ".class", "#id", etc. (GSAP uses document.querySelectorAll() internally) or it can be direct references to elements, generic objects, or even an array of objects.

https://greensock.com/docs/v3/GSAP/gsap.to() より引用

とあるように、第一引数にはオブジェクトを渡すことができる為、RefObjectを渡しています。
ただ、RefObjectのcurrentを変化させるだけでは、再レンダリングは起こらないため、onUpdate内でステートを変化させることでレンダリングさせています。