3 Commits

2 changed files with 84 additions and 12 deletions

View File

@@ -28,27 +28,27 @@ export default function LandingPage() {
<div id="nav" data-section="nav"> <div id="nav" data-section="nav">
<NavbarStyleFullscreen <NavbarStyleFullscreen
navItems={[ navItems={[
{ name: "Home", id: "hero" }, { name: "Головна", id: "hero" },
{ name: "About", id: "about" }, { name: "Про нас", id: "about" },
{ name: "Products", id: "products" }, { name: "Продукти", id: "products" },
{ name: "Contact", id: "contact" }, { name: "Контакти", id: "contact" },
{ name: "Order", id: "order" } { name: "Замовити", id: "order" }
]} ]}
brandName="Пекарня" brandName="Пекарня"
bottomLeftText="Authentic Ukrainian Bakery" bottomLeftText="Автентична українська пекарня"
bottomRightText="hello@ukrainianbakery.local" bottomRightText="hello@ukrainianbakery.local"
/> />
</div> </div>
<div id="hero" data-section="hero"> <div id="hero" data-section="hero">
<HeroBillboard <HeroBillboard
title="Freshly Baked Ukrainian Traditions" title="Свіжовипечені українські традиції"
description="Discover authentic Ukrainian breads and pastries made daily with traditional recipes passed down through generations. Every loaf tells a story of heritage and craftsmanship." description="Відкрийте для себе автентичний український хліб та випічку, виготовлені щодня за традиційними рецептами, переданими з покоління в покоління. Кожна булка розповідає історію спадщини та майстерності."
background={{ variant: "plain" }} background={{ variant: "plain" }}
tag="Est. 2005" tag="Заснована 2005"
tagIcon={Sparkles} tagIcon={Sparkles}
buttons={[ buttons={[
{ text: "Order Now", href: "#order" }, { text: "Замовити зараз", href: "#order" },
{ text: "Learn More", href: "#about" } { text: "Learn More", href: "#about" }
]} ]}
imageSrc="https://img.b2bpic.net/free-photo/various-type-rustic-breads-box_23-2147975199.jpg" imageSrc="https://img.b2bpic.net/free-photo/various-type-rustic-breads-box_23-2147975199.jpg"

View File

@@ -100,7 +100,7 @@ const HeroBillboard = ({
buttonClassName = "", buttonClassName = "",
buttonTextClassName = "", buttonTextClassName = "",
mediaWrapperClassName = "", mediaWrapperClassName = "",
imageClassName = "", imageClassName = "",
marqueeClassName = "", marqueeClassName = "",
marqueeItemClassName = "", marqueeItemClassName = "",
marqueeCardClassName = "", marqueeCardClassName = "",
@@ -110,6 +110,78 @@ const HeroBillboard = ({
}: HeroBillboardProps) => { }: HeroBillboardProps) => {
const { containerRef: mediaContainerRef } = useButtonAnimation({ animationType: mediaAnimation }); const { containerRef: mediaContainerRef } = useButtonAnimation({ animationType: mediaAnimation });
const handleButtonClick = (e: React.MouseEvent<HTMLButtonElement>, callback?: () => void) => {
const button = e.currentTarget;
const rect = button.getBoundingClientRect();
const x = rect.left + rect.width / 2;
const y = rect.top + rect.height / 2;
// Create particle explosion effect
for (let i = 0; i < 12; i++) {
const particle = document.createElement("div");
const angle = (i / 12) * Math.PI * 2;
const velocity = 5 + Math.random() * 5;
const vx = Math.cos(angle) * velocity;
const vy = Math.sin(angle) * velocity;
particle.style.position = "fixed";
particle.style.left = x + "px";
particle.style.top = y + "px";
particle.style.width = "8px";
particle.style.height = "8px";
particle.style.borderRadius = "50%";
particle.style.backgroundColor = getComputedStyle(button).backgroundColor || "#3b82f6";
particle.style.pointerEvents = "none";
particle.style.zIndex = "9999";
particle.style.boxShadow = "0 0 10px currentColor";
document.body.appendChild(particle);
let px = x;
let py = y;
let pvx = vx;
let pvy = vy;
const gravity = 0.2;
const friction = 0.98;
let life = 1;
const animate = () => {
pvx *= friction;
pvy *= friction;
pvy += gravity;
px += pvx;
py += pvy;
life -= 0.02;
particle.style.left = px + "px";
particle.style.top = py + "px";
particle.style.opacity = String(Math.max(0, life));
if (life > 0) {
requestAnimationFrame(animate);
} else {
particle.remove();
}
};
animate();
}
// Execute button action after animation starts
if (callback) {
setTimeout(callback, 100);
}
};
const enhancedButtons = buttons?.map((button) => ({
...button,
onClick: (e: React.MouseEvent<HTMLButtonElement> | null) => {
if (e && e.currentTarget) {
handleButtonClick(e, button.onClick as (() => void) | undefined);
}
},
}));
return ( return (
<section <section
aria-label={ariaLabel} aria-label={ariaLabel}
@@ -123,7 +195,7 @@ const HeroBillboard = ({
tag={tag} tag={tag}
tagIcon={tagIcon} tagIcon={tagIcon}
tagAnimation={tagAnimation} tagAnimation={tagAnimation}
buttons={buttons} buttons={enhancedButtons}
buttonAnimation={buttonAnimation} buttonAnimation={buttonAnimation}
avatars={avatars} avatars={avatars}
avatarText={avatarText} avatarText={avatarText}