Zenn

【GSAP】GSAP Practice【#26 GSAP Nextjs TimeLine2】

2025/02/25に公開

【#26 GSAP Nextjs TimeLine2】

YouTube: https://youtu.be/IECA30A2dDk
https://youtu.be/IECA30A2dDk

今回はアニメーションの対象となる要素を
再利用可能なコンポーネントとして作成する方法について解説します。

app/page.tsx
'use client'

import { useRef, useState } from 'react'
import gsap from 'gsap'
import { useGSAP } from '@gsap/react'

gsap.registerPlugin(useGSAP)

interface BoxProps {
  tl: gsap.core.Timeline | undefined
  index: number
  children: React.ReactNode
}

const Box = ({ tl, index, children }: BoxProps) => {
  const boxRef = useRef<HTMLDivElement>(null)

  useGSAP(() => {
    tl &&
      tl.to(
        boxRef.current,
        {
          x: 500,
        },
        index * 0.1
      )
  }, [tl, index])

  return (
    <div
      ref={boxRef}
      className="w-40 h-40 bg-red-700 flex flex-col items-center justify-center text-white font-bold cursor-pointer"
    >
      {children}
    </div>
  )
}

export default function Home() {
  const containerRef = useRef<HTMLDivElement>(null)
  const [tl, setTl] = useState<gsap.core.Timeline>()

  const { contextSafe } = useGSAP(
    () => {
      const tl = gsap.timeline()
      setTl(tl)
    },
    { scope: containerRef }
  )

  // const toggleTimeLine = contextSafe(() => {
  //   tl1.current?.reversed(!tl1.current.reversed())
  // })

  return (
    <main className="w-screen h-screen">
      <div
        ref={containerRef}
        className="size-full flex flex-col gap-32 items-center justify-center bg-slate-300"
      >
        <Box tl={tl} index={0}>
          <p>box1</p>
        </Box>
        <Box tl={tl} index={1}>
          <p>box2</p>
        </Box>
        <Box tl={tl} index={2}>
          <p>box3</p>
        </Box>
      </div>
      <div className="size-full flex items-center justify-center bg-rose-300">
        <div className="box w-40 h-40 bg-red-700 flex flex-col items-center justify-center text-white font-bold cursor-pointer">
          <p>box1</p>
        </div>
      </div>
      <div className="size-full flex items-center justify-center bg-sky-300">
        <h2 className="text-3xl font-bold">Section3</h2>
      </div>
    </main>
  )
}

Discussion

ログインするとコメントできます