const {useEffect, useRef} = React; function ArrowFlow({direction = 'rtl', reverseFlow = false}) { const stemPathRef = useRef(null); const circlePathRef = useRef(null); const arrowRef = useRef(null); const circleRefs = useRef([]); circleRefs.current = []; const circleRadii = [4, 14, 7, 16, 9]; const stemPaths = { 'rtl': 'M 250,75 L 125,75 A 50 50 0 0 0 75,125 L 75,132', 'ltr': 'M 0,75 L 125,75 A 50 50 0 0 1 175,125 L 175,132', }; const circlePaths = { 'rtl': 'M 300,75 L 125,75 A 50 50 0 0 0 75,125 L 75,182', 'ltr': 'M -50,75 L 125,75 A 50 50 0 0 1 175,125 L 175,182', }; const stemPathD = stemPaths[direction]; const circlePathD = circlePaths[direction]; const addToCircleRefs = el => { if (el && !circleRefs.current.includes(el)) { circleRefs.current.push(el); } }; useEffect(() => { gsap.registerPlugin(MotionPathPlugin); gsap.set(arrowRef.current, {opacity: 0}); gsap.set(circleRefs.current, {opacity: 0}); const len = stemPathRef.current.getTotalLength(); let pathTween, arrowTween, circlesTl; if (reverseFlow) { gsap.set( stemPathRef.current, {strokeDasharray: len, strokeDashoffset: -len}); pathTween = gsap.to( stemPathRef.current, {strokeDashoffset: 0, duration: 1.6, delay: 0, ease: 'power1.inOut'}); } else { gsap.set( stemPathRef.current, {strokeDasharray: len, strokeDashoffset: len}); pathTween = gsap.to( stemPathRef.current, {strokeDashoffset: 0, duration: 1.6, delay: 0, ease: 'power1.inOut'}); } const motionPathConfig = { path: stemPathRef.current, align: stemPathRef.current, alignOrigin: [0.5, 0.5], autoRotate: true, start: reverseFlow ? 1 : 0, end: reverseFlow ? 0 : 1, }; arrowTween = gsap.to(arrowRef.current, { opacity: 1, duration: 1.6, delay: 0, motionPath: motionPathConfig, ease: 'power1.inOut', }); const circleMotionPathConfig = { path: circlePathRef.current, align: circlePathRef.current, alignOrigin: [0.5, 0.5], start: reverseFlow ? 1 : 0, end: reverseFlow ? 0 : 1, }; circlesTl = gsap.timeline({delay: 0}); circleRefs.current.forEach((circle, index) => { circlesTl.fromTo( circle, {opacity: 0}, {opacity: 1, duration: 0.2}, index * 0.3); // stagger start time circlesTl.to( circle, { motionPath: circleMotionPathConfig, duration: 1.6, ease: 'power1.inOut', }, index * 0.3); // same start time as opacity fade in circlesTl.to( circle, {opacity: 0, duration: 0.2}, index * 0.3 + 1.4); // fade out before end }); circlesTl.to(arrowRef.current, {opacity: 0, duration: 0.2}, 2.8); circlesTl.to(stemPathRef.current, {opacity: 0, duration: 0.2}, 2.8); return () => { pathTween.kill(); arrowTween.kill(); circlesTl.kill(); } }, [direction, reverseFlow]); return (