2 Commits

View File

@@ -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}