Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 977c409688 | |||
| 259c8237df | |||
| ba0ef17de6 | |||
| 2a23fc6ce0 | |||
| 2b0ccb58a8 | |||
| 64acf68c5c | |||
| bf17921c90 |
@@ -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