javascriptreactjsjsxgsap

Animation Doesn't Work Unless I Save The File


The buttons are supposed to be a bubble animation when hovered over. But they stay in place unless I save the .jsx file in VS Code. Then they work fine until I refresh the page and the buttons have no animation.

Here are my console errors and the jsx code. And the code is being rendered through another jsx file

import './App.css';
import CoffeeSteamingBG from './CoffeeSteamingBG.jpg'
import Cart from './cart.svg'
import { gsap } from 'gsap';
//const CoffeeSteamingBG = require('./CoffeeSteamingBG.jpg');

function App() {
  return (
    <>
      <FirstHeader />
      <IndexHome />
      <CoolBtns />
    </>
  )
}

function FirstHeader() {
  return (
    <header>
      <nav className='FirstNav'>
        <div className='OuterDivCJLogo'>
          <span className='FirstCJLogo'>Cuppa Java</span>
        </div>
      </nav>
    </header>
  )
}

function IndexHome() {
  return (
    <>
      <div className='slogan'>
        <h1><em>The Art of Coffee Elevated</em></h1>
      </div>
    </>
  )
}

function CoolBtns() {
  return (
    <div className='FunNew'>
      <ul className='Funul'>
        <li className='Funli'>
          <button className='FunBtn F1'><a>Menu</a></button>
        </li>
        <li className='Funli'>
          <button className='FunBtn F2'><a>Bistro</a></button>
        </li>
        <li className='Funli'>
          <button className='FunBtn F3'><a>Cart</a></button>
        </li>
      </ul>
    </div>
  )
}

export default App

class HoverButton {
  constructor(el) {
    this.el = el;
    this.hover = false;
    this.calculatePosition();
    this.attachEventsListener();
  }
        
  attachEventsListener() {
    window.addEventListener('mousemove', e => this.onMouseMove(e));
    window.addEventListener('resize', e => this.calculatePosition(e));
  }
        
  calculatePosition() {
     gsap.set(this.el, {
        x: 0,
        y: 0,
        scale: 1 });
      if(this.el) {
        const box = this.el.getBoundingClientRect();
        this.x = box.left + box.width * 0.5;
        this.y = box.top + box.height * 0.5;
        this.width = box.width;
        this.height = box.height;
      }
  }
        
  onMouseMove(e) {
    let hover = false;
    let hoverArea = this.hover ? 0.7 : 0.5;
    let x = e.clientX - this.x;
    let y = e.clientY - this.y;
    let distance = Math.sqrt(x * x + y * y);
    if (distance < this.width * hoverArea) {
      hover = true;
      if (!this.hover) {
        this.hover = true;
      }
      this.onHover(e.clientX, e.clientY);
    }
        
    if (!hover && this.hover) {
      this.onLeave();
      this.hover = false;
    }
  }
        
  onHover(x, y) {
    gsap.to(this.el, {
      x: (x - this.x) * 0.4,
      y: (y - this.y) * 0.4,
      scale: 1.15,
      ease: 'power2.out',
      duration: 0.4 });
        
    this.el.style.zIndex = 10;
  }
  onLeave() {
    gsap.to(this.el, {
      x: 0,
      y: 0,
      scale: 1,
      ease: 'elastic.out(1.2, 0.4)',
      duration: 0.7 });
        
    this.el.style.zIndex = 1;
  }}
        
const btn1 = document.querySelector('li:nth-child(1) button');
new HoverButton(btn1);
const btn2 = document.querySelector('li:nth-child(2) button');
new HoverButton(btn2);
const btn3 = document.querySelector('li:nth-child(3) button');
new HoverButton(btn3);

I've tried reinstalling gsap because I heard that can cause problems if its not updated


Solution

  • Try this approach, import useEffect, and set this to CoolBtns.

    import React, { useEffect } from 'react';
    // ... (other staff)
    
    function CoolBtns() {
      useEffect(() => {
        const btn1 = document.querySelector('li:nth-child(1) button');
        new HoverButton(btn1);
        const btn2 = document.querySelector('li:nth-child(2) button');
        new HoverButton(btn2);
        const btn3 = document.querySelector('li:nth-child(3) button');
        new HoverButton(btn3);
      }, []); // put dependency array 
    
      return (
        <div className='FunNew'>
          <ul className='Funul'>
            <li className='Funli'>
              <button className='FunBtn F1'><a>Menu</a></button>
            </li>
            <li className='Funli'>
              <button className='FunBtn F2'><a>Bistro</a></button>
            </li>
            <li className='Funli'>
              <button className='FunBtn F3'><a>Cart</a></button>
            </li>
          </ul>
        </div>
      );
    }