Jump to content
Search Community

Animated Button Component in React

Joshith test
Moderator Tag

Recommended Posts

I was trying to create a button component which has fluid animation like these buttons :-button-animation.png.2a5c9bbd05a4c2ef94ab46c16e61511a.pngMy solution was as below :-
 

import { useRef, useEffect } from "react";
import { useGSAP } from "@gsap/react";
import { gsap } from "gsap";

const RoundButton = () => {
  const xTo = useRef<any>();
  const yTo = useRef<any>();
  const buttonRef = useRef(null);
  const divRef = useRef(null);

  const { contextSafe } = useGSAP (()=>{
    xTo.current = gsap.quickTo(divRef.current, "x", {duration:0.8, ease: "power3"});
    yTo.current = gsap.quickTo(divRef.current, "y", {duration:0.8, ease: "power3"});
    

    gsap.to(divRef.current, {
      scale: 0,
      xPercent: -50,
      yPercent: -50,
      zIndex: -10,
    })
  },{scope: buttonRef});


  const handleMouseEnter = contextSafe(() => {
    gsap.to(divRef.current, {
      scale:1,
      duration:0.3,
    });

  });
  const handleMouseLeave = contextSafe(() => {
    gsap.to(divRef.current, {
      scale:0,
      duration:0.3,
    })
  });
  const handleMouseMove = contextSafe((e: React.MouseEvent) => {
      const rect = buttonRef.current.getBoundingClientRect();
      const { top, left } = rect;
      xTo.current(e.clientX - left);
      yTo.current(e.clientY - top);
    
  });
  return (
    <button
      ref={buttonRef}
      className="relative border-2 border-solid border-white px-5 py-2 rounded-3xl text-white overflow-hidden hover:text-black hover:border-black z-0"
      onMouseEnter={handleMouseEnter}
      onMouseLeave={handleMouseLeave}
      onMouseMove={(e)=>{handleMouseMove(e)}}
    >
      <div ref={divRef} className="absolute w-[200px] h-[150px] bg-white left-0 top-0 wrapperElement -z-10 pointer-events-none rounded-[50%]"></div>
      <span className="z-10">Click Me!</span>
    </button>
  );
};

export default RoundButton;

I'm using tailwindcss for styling. I wrote this code using various examples on this forums, Like this one and also using the official react support doc.

In official docs, there is an example related to this same effect in the last section of the above shared link. It uses position: fixed styling for the div.

In the above code, I specifically wanted to recreate with position: absolute So that i can actually maintain it as a component.

 

Here is the stackblitz link if needed.


I don't know if this is the correct way. Can someone let me know if there is any better way to do it in react?

Also don't mind the typescript errors if any :)

Link to comment
Share on other sites

Hi,

 

Everything looks OK to me, the only thing you might want to check is the type definition you're using for contexSafe in this case:

const handleMouseMove = contextSafe((e: React.MouseEvent) => {
  const rect = buttonRef.current.getBoundingClientRect();
  const { top, left } = rect;
  xTo.current(e.clientX - left);
  yTo.current(e.clientY - top);
});

This thread and the link in it can help you if you run into any issues when typescript is compiling:

 

Happy Tweening!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...