cssreactjsgsapclip-path

How to animate an image reveal with GSAP and clip-path in React


I'm trying to animate the reveal of an image using GSAP and the clip-path property in a Component. The animation works as expected when I use the first clip-path value, but when I switch to the other one, the animation skips.

Here's my code:

import React, { useEffect, useRef } from 'react';
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import Image from 'next/image';

interface ScrollTriggerImageInterface {
  alt: string;
  colStart: string;
  colEnd: string;
  height: string;
  src: string;
}

const ScrollTriggerImage: React.FC<ScrollTriggerImageInterface> = ({
  alt,
  colStart,
  colEnd,
  height,
  src,
}) => {
  const divRef = useRef(null);

  useEffect(() => {
    gsap.registerPlugin(ScrollTrigger);

    gsap.to(divRef.current, {
      clipPath: "polygon(0 0, 100% 0, 100% 100%, 0 100%)",
      scrollTrigger: {
        end: "bottom center",
        markers: true,
        scrub: true,
        start: "top center",
        trigger: divRef.current,
      },
    });
  }, []);

  return (
    <div className={`${height} grid w-full grid-cols-4`}>
      <div
        className={`${colStart} ${colEnd} relative h-full w-full`}
        ref={divRef}
        style={{ clipPath: "polygon(0 0, 0 0, 0 0, 0 0)" }}
        // style={{ clipPath: "polygon(100% 0, 100% 0, 100% 0, 100% 0)" }}
      >
        <Image
          alt={alt}
          className="object-cover object-center"
          fill
          src={src}
        />
      </div>
    </div>
  );
};

The animation works when the clipPath is set to "polygon(0 0, 0 0, 0 0, 0 0)" in the style property, and the GSAP animation clipPath is set to "polygon(0 0, 100% 0, 100% 100%, 0 100%)". However, when I comment out the first clipPath value and uncomment the second one in the style property, the animation doesn't show.

Can anyone help me understand why this is happening and how I can fix it?


Solution

  • I've managed to fix the problem by replacing following lines:

    gsap.to(divRef.current, {
      clipPath: "polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)",
    });
    

    and

    style={{ clipPath: "polygon(100% 0%, 100% 0%, 100% 0%, 100% 0%)" }}
    

    It appears that you need to place a percentage symbol after the zero, and doing so will cause the code to function correctly.