Next.jsでDOMをアニメーションさせようと思った際、いつもはトゥイーンを自作していたのですが、いい感じのライブラリがあれば使いたいなと常々思っていました。
そこで、今回はReact + GSAPでDOMのアニメーションを試みてみようと思います。
ソースコード(抜粋)
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のセレクタを文字列で渡しています。
しかし、
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内でステートを変化させることでレンダリングさせています。