From 259c8237dfc7bd9014361e456735db54ed3bbc75 Mon Sep 17 00:00:00 2001 From: kudindmitriy Date: Tue, 24 Feb 2026 10:09:49 +0000 Subject: [PATCH] Bob AI: Add an 'explode on click' animation effect to buttons in the --- .../sections/hero/HeroBillboard.tsx | 74 ++++++++++++++++++- 1 file changed, 72 insertions(+), 2 deletions(-) diff --git a/src/components/sections/hero/HeroBillboard.tsx b/src/components/sections/hero/HeroBillboard.tsx index 1bb6f8b..7d9e44b 100644 --- a/src/components/sections/hero/HeroBillboard.tsx +++ b/src/components/sections/hero/HeroBillboard.tsx @@ -100,7 +100,7 @@ const HeroBillboard = ({ buttonClassName = "", buttonTextClassName = "", mediaWrapperClassName = "", - imageClassName = "", +imageClassName = "", marqueeClassName = "", marqueeItemClassName = "", marqueeCardClassName = "", @@ -110,6 +110,76 @@ const HeroBillboard = ({ }: HeroBillboardProps) => { const { containerRef: mediaContainerRef } = useButtonAnimation({ animationType: mediaAnimation }); + const handleButtonClick = (e: React.MouseEvent, 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) => { + handleButtonClick(e, button.onClick as (() => void) | undefined); + }, + })); + return (