Skip to content

Commit

Permalink
upgraded the project a little bit
Browse files Browse the repository at this point in the history
  • Loading branch information
StarKnightt committed Nov 2, 2024
1 parent 45c3405 commit 4fddece
Show file tree
Hide file tree
Showing 3 changed files with 240 additions and 102 deletions.
111 changes: 79 additions & 32 deletions src/components/Hero.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState, useEffect, useCallback } from 'react';
import { motion } from 'framer-motion';
import PropTypes from 'prop-types';

const IMAGES = [
'/images/hero-background.webp',
Expand All @@ -10,8 +11,22 @@ const IMAGES = [

const INTERVAL = 5000;

// Preload images for smoother transitions
const preloadImages = () => {
IMAGES.forEach((src) => {
const img = new Image();
img.src = src;
});
};

function Hero() {
const [currentImage, setCurrentImage] = useState(0);
const [imagesLoaded, setImagesLoaded] = useState(false);

useEffect(() => {
preloadImages();
setImagesLoaded(true);
}, []);

const nextImage = useCallback(() => {
setCurrentImage((prevImage) => (prevImage + 1) % IMAGES.length);
Expand All @@ -22,49 +37,70 @@ function Hero() {
return () => clearInterval(timer);
}, [nextImage]);

const heroContent = (
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-center px-4 max-w-xs sm:max-w-sm md:max-w-md lg:max-w-lg xl:max-w-xl">
<HeroTitle />
<HeroSubtitle />
<HeroCTA />
</div>
</div>
);

if (!imagesLoaded) {
return <div className="h-screen w-full bg-gray-900 animate-pulse" />;
}

return (
<section className="relative h-screen w-full overflow-hidden">
<section className="relative h-screen w-full overflow-hidden" role="banner">
{IMAGES.map((src, index) => (
<motion.div
<BackgroundImage
key={src}
className="absolute inset-0 bg-cover bg-center"
initial={{ opacity: 0 }}
animate={{ opacity: index === currentImage ? 1 : 0 }}
transition={{ duration: 1 }}
style={{ backgroundImage: `url(${src})` }}
aria-hidden="true"
src={src}
isActive={index === currentImage}
/>
))}

<div className="absolute inset-0 bg-black bg-opacity-60" />

<div className="absolute inset-0 flex items-center justify-center">
<div className="text-center px-4 max-w-xs sm:max-w-sm md:max-w-md lg:max-w-lg xl:max-w-xl">
<motion.h1
initial={{ y: -50, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, delay: 0.2 }}
className="hero-title text-2xl sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl font-bold mb-2 sm:mb-3 md:mb-4 text-orange-400 drop-shadow-lg leading-tight"
>
Experience Coffee Evolution
</motion.h1>
<motion.p
initial={{ y: 50, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, delay: 0.4 }}
className="hero-subtitle text-base sm:text-lg md:text-xl lg:text-2xl mb-4 sm:mb-5 md:mb-6 text-orange-200 drop-shadow-md"
>
Where science meets flavor
</motion.p>
<HeroCTA />
</div>
</div>

{heroContent}
<NavigationDots currentImage={currentImage} setCurrentImage={setCurrentImage} />
</section>
);
}

const BackgroundImage = React.memo(({ src, isActive }) => (
<motion.div
className="absolute inset-0 bg-cover bg-center"
initial={{ opacity: 0 }}
animate={{ opacity: isActive ? 1 : 0 }}
transition={{ duration: 1 }}
style={{ backgroundImage: `url(${src})` }}
aria-hidden="true"
/>
));

const HeroTitle = React.memo(() => (
<motion.h1
initial={{ y: -50, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, delay: 0.2 }}
className="hero-title text-2xl sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl font-bold mb-2 sm:mb-3 md:mb-4 text-orange-400 drop-shadow-lg leading-tight"
>
Experience Coffee Evolution
</motion.h1>
));

const HeroSubtitle = React.memo(() => (
<motion.p
initial={{ y: 50, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.5, delay: 0.4 }}
className="hero-subtitle text-base sm:text-lg md:text-xl lg:text-2xl mb-4 sm:mb-5 md:mb-6 text-orange-200 drop-shadow-md"
>
Where science meets flavor
</motion.p>
));

const HeroCTA = React.memo(() => (
<motion.a
href="#menu"
Expand Down Expand Up @@ -96,4 +132,15 @@ const NavigationDots = React.memo(({ currentImage, setCurrentImage }) => (
</div>
));

export default Hero;
// Add PropTypes
BackgroundImage.propTypes = {
src: PropTypes.string.isRequired,
isActive: PropTypes.bool.isRequired,
};

NavigationDots.propTypes = {
currentImage: PropTypes.number.isRequired,
setCurrentImage: PropTypes.func.isRequired,
};

export default React.memo(Hero);
Loading

0 comments on commit 4fddece

Please sign in to comment.