Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f8c44db0da | |||
| 977c409688 | |||
| 259c8237df |
@@ -28,27 +28,27 @@ export default function LandingPage() {
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarStyleFullscreen
|
||||
navItems={[
|
||||
{ name: "Home", id: "hero" },
|
||||
{ name: "About", id: "about" },
|
||||
{ name: "Products", id: "products" },
|
||||
{ name: "Contact", id: "contact" },
|
||||
{ name: "Order", id: "order" }
|
||||
{ name: "Головна", id: "hero" },
|
||||
{ name: "Про нас", id: "about" },
|
||||
{ name: "Продукти", id: "products" },
|
||||
{ name: "Контакти", id: "contact" },
|
||||
{ name: "Замовити", id: "order" }
|
||||
]}
|
||||
brandName="Пекарня"
|
||||
bottomLeftText="Authentic Ukrainian Bakery"
|
||||
bottomLeftText="Автентична українська пекарня"
|
||||
bottomRightText="hello@ukrainianbakery.local"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="hero" data-section="hero">
|
||||
<HeroBillboard
|
||||
title="Freshly Baked Ukrainian Traditions"
|
||||
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."
|
||||
title="Свіжовипечені українські традиції"
|
||||
description="Відкрийте для себе автентичний український хліб та випічку, виготовлені щодня за традиційними рецептами, переданими з покоління в покоління. Кожна булка розповідає історію спадщини та майстерності."
|
||||
background={{ variant: "plain" }}
|
||||
tag="Est. 2005"
|
||||
tag="Заснована 2005"
|
||||
tagIcon={Sparkles}
|
||||
buttons={[
|
||||
{ text: "Order Now", href: "#order" },
|
||||
{ text: "Замовити зараз", href: "#order" },
|
||||
{ text: "Learn More", href: "#about" }
|
||||
]}
|
||||
imageSrc="https://img.b2bpic.net/free-photo/various-type-rustic-breads-box_23-2147975199.jpg"
|
||||
|
||||
@@ -100,7 +100,7 @@ const HeroBillboard = ({
|
||||
buttonClassName = "",
|
||||
buttonTextClassName = "",
|
||||
mediaWrapperClassName = "",
|
||||
imageClassName = "",
|
||||
imageClassName = "",
|
||||
marqueeClassName = "",
|
||||
marqueeItemClassName = "",
|
||||
marqueeCardClassName = "",
|
||||
@@ -110,6 +110,78 @@ const HeroBillboard = ({
|
||||
}: HeroBillboardProps) => {
|
||||
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 (
|
||||
<section
|
||||
aria-label={ariaLabel}
|
||||
@@ -123,7 +195,7 @@ const HeroBillboard = ({
|
||||
tag={tag}
|
||||
tagIcon={tagIcon}
|
||||
tagAnimation={tagAnimation}
|
||||
buttons={buttons}
|
||||
buttons={enhancedButtons}
|
||||
buttonAnimation={buttonAnimation}
|
||||
avatars={avatars}
|
||||
avatarText={avatarText}
|
||||
|
||||
Reference in New Issue
Block a user