skip to Main Content

I have tried literally everything I can search for and think of but nothing is letting me implement this feature. I want the background to have completely faded to black by the time the "who" class is in the middle of the screen with reference.

Here is my home.jsx and background related css:

import React, { useEffect, useRef } from 'react';
import { Container, Row, Col } from "react-bootstrap";
import Marquee from 'react-fast-marquee';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { icon } from '@fortawesome/fontawesome-svg-core/import.macro';
import myImg from "../../Assets/avatar.svg";
import Tilt from "react-parallax-tilt";
import { AiFillGithub, AiOutlineTwitter, AiFillInstagram } from "react-icons/ai";
import { FaLinkedinIn } from "react-icons/fa";
import Footer from "../Footer";
import '../../style.css';
import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

function Home() {
  const backgroundRef = useRef(null);
  const headingRef = useRef(null);
  const marqueeContainerRef = useRef(null);
  const aboutRef = useRef(null); // Reference for the about section
  const whoRef = useRef(null); // Reference for the "who" element


  useEffect(() => {
    const observer = new IntersectionObserver((entries) => {
      entries.forEach((entry) => {
        const opacity = 1 - entry.intersectionRatio; // Calculate opacity based on intersection
        document.body.style.backgroundColor = `rgba(0, 0, 0, ${opacity})`; // Set background color
      });
    });
  
    // Observe the desired element (e.g., a section with content)
    observer.observe(aboutRef.current);
  
    return () => observer.disconnect();
  }, [aboutRef]);


  useEffect(() => {
    const spans = headingRef.current.querySelectorAll(".heading-name span");
    spans.forEach((span) => {
      span.addEventListener("mouseenter", handleMouseEnter);
      span.addEventListener("animationend", handleAnimationEnd);
    });

    return () => {
      spans.forEach((span) => {
        span.removeEventListener("mouseenter", handleMouseEnter);
        span.removeEventListener("animationend", handleAnimationEnd);
      });
    };
  }, []);

  const handleMouseEnter = (event) => {
    const span = event.target;
    span.classList.add("hovered");
  };

  const handleAnimationEnd = (event) => {
    const span = event.target;
    span.classList.remove("hovered");
  };

  return (
    <div>
      <div ref={backgroundRef} className="background-container">
        <div className="content-container">
          <Container fluid className="home-section" id="home">
            <Container className="home-content">
              <Row>
                <Col md={7} className="home-header">
                  <h1 style={{ paddingBottom: 15 }} className="heading">
                    <span>H</span>
                    <span>i</span>
                    <span style={{ marginRight: '55px' }}></span>
                    <span>T</span>
                    <span>h</span>
                    <span>e</span>
                    <span>r</span>
                    <span>e</span>
                  </h1>
                  <h1 ref={headingRef} className="heading-name">
                    <span>I</span>
                    <span>'</span>
                    <span style={{ marginRight: '55px' }}>m</span>
                    <span>O</span>
                    <span>l</span>
                    <span>l</span>
                    <span>i</span>
                    <span>e</span>
                  </h1>
                </Col>
                <Col md={5} style={{ paddingBottom: 30 }}>
                </Col>
              </Row>
            </Container>
            <div className="marquee-container w-full" ref={marqueeContainerRef}>
              <Marquee autoFill={true} speed={10}>
                {[
                  'ASPIRING ENGINEER',
                  'PROGRAMMER',
                  'ENTREPRENEUR',
                  'DEVELOPER',
                  'UI / UX DESIGNER',
                  'SPORTS LOVER',
                  'DESIGNER',
                  'STUDENT',
                ].map((item, index) => (
                  <div className="flex items-center" key={index}>
                    <h1 className='marqueeText font-vog text-md'>{item}</h1>
                    <FontAwesomeIcon className='spin' icon={icon({ name: 'fan' })} style={{ color: 'white' }} />
                  </div>
                ))}
              </Marquee>
            </div>
          </Container>
          <br></br>
          <Container fluid className="home-about-section" id="about" ref={aboutRef}>  {/* Added ref for about section */}
            <Container style={{ backgroundColor: `rgba(0, 0, 0, 0)`, transition: 'background-color 0.5s ease-in-out' }}> {/* Set initial background color and transition */}
              <Row>
                <Col md={8} className="home-about-description">
                  <h1 className='who' style={{ fontSize: "2.6em" }}>
                    WHO <span className="purple"> AM </span> I?
                  </h1>
                  <p className="home-about-body">
                    I'm a bla bla year old programmer from bla bla, bla bla,
                    and through my family I found an interest in coding!
                    <br />
                    <br />I am learning languages like
                    <i>
                      <b className="purple"> Python and Javascript. </b>
                    </i>
                    <br />
                    <br />
                    I love building things like &nbsp;
                    <i>
                      <b className="purple">Websites and Stores </b> and
                      also in areas related to{" "}
                      <b className="purple"> Creativity.</b>
                    </i>
                    <br />
                    <br />
                    Whenever possible, I also apply my passion for developing products
                    with <b className="purple">Node.js</b> and
                    <i>
                      <b className="purple"> other frameworks</b>
                    </i>
                    &nbsp; like
                    <i>
                      <b className="purple"> React.js and Next.js</b>
                    </i>
                  </p>
                </Col>
                <Col md={4} className="myAvtar">
                  <Tilt>
                    <img src={myImg} className="img-fluid" alt="avatar" />
                  </Tilt>
                </Col>
              </Row>
              <Row>
                <Col md={12} className="home-about-social">
                  <h1>FIND ME ON</h1>
                  <p>
                    Feel free to <span className="purple">connect </span>with me
                  </p>
                  <ul className="home-about-social-links">
                    <li className="social-icons">
                      <a
                        href="https://github.com/"
                        target="_blank"
                        rel="noreferrer"
                        className="icon-colour  home-social-icons"
                      >
                        <AiFillGithub />
                      </a>
                    </li>
                    <li className="social-icons">
                      <a
                        href="https://twitter.com/"
                        target="_blank"
                        rel="noreferrer"
                        className="icon-colour  home-social-icons"
                      >
                        <AiOutlineTwitter />
                      </a>
                    </li>
                    <li className="social-icons">
                      <a
                        href="https://www.linkedin.com/in//"
                        target="_blank"
                        rel="noreferrer"
                        className="icon-colour  home-social-icons"
                      >
                        <FaLinkedinIn />
                      </a>
                    </li>
                    <li className="social-icons">
                      <a
                        href="https://www.instagram.com/"
                        target="_blank"
                        rel="noreferrer"
                        className="icon-colour home-social-icons"
                      >
                        <AiFillInstagram />
                      </a>
                    </li>
                  </ul>
                </Col>
              </Row>
            </Container>
          </Container>
          <Footer />
        </div>
      </div>
    </div>
  );
}

export default Home;

   .background-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    background: url('./Assets/home-bg.jpg');
    background-size: cover;
    background-attachment: fixed;
    background-repeat: no-repeat;
  }

I was trying to get an effect like my friends portfolio: https://cmcdev.net

2

Answers


  1. The link you shared is managed Using Javascript, for this, you can use third party library like GSAP

    In my opinion it’s way easier to manage it via CSS. This feature is kinda new to the standards so it might not work on older browsers.

    #MyBackgroundImage::after {
      content: "";
      position: fixed;
      inset: 0;
      background: black
      animation: fade-out auto linear;
      animation-timeline: scroll();
    }
    @keyframes fade-out {
      from {
        opacity: 0;
      } to {
        opacity: 0.8;
      }
    }
    

    You can have a "half-page fade" behaviour by adapting this with percentages instead of the from/to

    You can find a great sample of example here

    Login or Signup to reply.
  2. Ah, the classic "I’ve tried literally everything" statement followed by a project dump. Next time, please consider focusing your question more on the specific issue rather than sharing the entire project (which in this case is not helpful and serves no purpose whatsoever), it helps both you and the people answering your question.

    With that in mind, here is how I would approach implementing the fade-to-black feature:

    document.addEventListener('scroll', function() {
      // Calculate how much the user has scrolled down
      const scrolled = window.scrollY;
    
      // Calculate opacity based on scroll position and the size of the window
      const opacity = 1 - (scrolled / ((1000 - window.innerHeight) * 0.5)); //Change the multiplier to adjust the scroll distance
      
      // Apply the opacity to the fade-element
      document.querySelector('.fade-element').style.opacity = opacity;
    });
    body {
      height: 1000px;
      margin: 0;
      background-color: black;
    }
    
    .fade-container {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      overflow: hidden;
      background-color: black;
    }
    
    .fade-element {
      width: 100%;
      height: 100vh;
      opacity: 1;
      transition: opacity 0.25s ease; /* Smooth transition */
    }
    <div class="fade-container">
      <img class="fade-element" src="https://via.placeholder.com/150" alt="Image"/>
    </div>

    The logic is very simple, all we do is modify the opacity of the element, while the main body’s background is set to black.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search