- import React, { useEffect, useRef, useState } from "react";
- import useIsMobile from "../../constants/useIsMobile";
- const easeInOutSine = (t) => -(Math.cos(Math.PI * t) - 1) / 2;
- const FloatingSVG = ({
- svg,
- position,
- speed = 0.5,
- amplitude = 20,
- rotationRange = 10,
- resetTrigger, // Prop to trigger reset
- }) => {
- const svgRef = useRef(null);
- const animationRef = useRef(null);
- const startTimeRef = useRef(null);
- const [isExploding, setIsExploding] = useState(true);
- const isMobile = useIsMobile();
-
- useEffect(() => {
- if (!resetTrigger) {
-
- const svgElement = svgRef.current;
- const centerX = window.innerWidth / 2 - (isMobile ? 7.5 : 15);
- const centerY = window.innerHeight / 2 - (isMobile ? 7.5 : 15);
- svgElement.style.transition =
- "left 1s ease-out, top 1s ease-out, opacity 1s ease-out";
- svgElement.style.left = `${centerX}px`;
- svgElement.style.top = `${centerY}px`;
- svgElement.style.opacity = "0";
- setIsExploding(true);
- } else {
-
- setIsExploding(true);
- }
- }, [resetTrigger, isMobile]);
-
- useEffect(() => {
- const svgElement = svgRef.current;
- if (isExploding && resetTrigger) {
-
- const centerX = window.innerWidth / 2 - (isMobile ? 7.5 : 15);
- const centerY = window.innerHeight / 2 - (isMobile ? 7.5 : 15);
- svgElement.style.left = `${centerX}px`;
- svgElement.style.top = `${centerY}px`;
-
- svgElement.style.transition =
- "left 1s ease-out, top 1s ease-out, opacity 1s ease-out";
- svgElement.style.opacity = "0";
- setTimeout(() => {
- svgElement.style.left = position.x;
- svgElement.style.top = position.y;
- svgElement.style.opacity = "1";
- setIsExploding(false);
- }, Math.random() * 500);
- }
-
- const animate = (timestamp) => {
- if (!startTimeRef.current) startTimeRef.current = timestamp;
- const elapsed = (timestamp - startTimeRef.current) / 1000;
-
- const offsetY =
- Math.sin(elapsed * speed * 1.8) * amplitude * 0.6 +
- Math.sin(elapsed * speed * 1.2) * amplitude * 0.4;
- const offsetX =
- Math.cos(elapsed * speed * 1.3) * amplitude * 0.3 +
- Math.sin(elapsed * speed * 0.8) * amplitude * 0.2;
-
- const t = (Math.sin(elapsed * speed) + 1) / 2;
- const easedOffsetY = easeInOutSine(t) * amplitude * 2 - amplitude;
-
- const rotation = Math.sin(elapsed * speed * 0.6) * rotationRange;
-
- svgElement.style.transform = `translate(${offsetX}px, ${easedOffsetY}px) rotate(${rotation}deg)`;
- animationRef.current = requestAnimationFrame(animate);
- };
-
- if (!isExploding && resetTrigger) {
- animationRef.current = requestAnimationFrame(animate);
- }
- return () => cancelAnimationFrame(animationRef.current);
- }, [
- position,
- speed,
- amplitude,
- rotationRange,
- isExploding,
- resetTrigger,
- isMobile,
- ]);
-
- const size = isMobile ? "20px" : "30px";
- return (
- <div
- ref={svgRef}
- style={{
- position: "absolute",
- width: size,
- height: size,
- zIndex: 0,
- }}
- >
- <img
- src={svg}
- alt="floating-svg"
- style={{ width: "100%", height: "100%" }}
- />
- </div>
- );
- };
- export default FloatingSVG;