{"version":3,"file":"InfiniteTicker.BLIn98Sy.mjs","names":["useRef","useState","useCallback","useMemo"],"sources":["https:/framerusercontent.com/modules/rHO4aNIIkGiQnPDOPXfp/pxB9o5vu2iO01Qf1gAct/InfiniteTicker.js"],"sourcesContent":["// Simple infinite and seamless ticker component that accepts child frames\nimport{jsx as _jsx}from\"react/jsx-runtime\";import{addPropertyControls,ControlType}from\"framer\";import{motion,useMotionValue,useAnimationFrame}from\"framer-motion\";import{useRef,useLayoutEffect,useState,startTransition,useMemo,useEffect,useCallback}from\"react\";/**\n * @framerDisableUnlink\n *\n * @framerSupportedLayoutWidth fixed\n * @framerSupportedLayoutHeight fixed\n */export default function InfiniteTicker(props){const{children,speed=50,direction=\"left\",gap=20,verticalAlign=\"center\",scrollToReverse=false,scrollToSpeed=false}=props;const contentRef=useRef(null);const containerRef=useRef(null);const[contentWidth,setContentWidth]=useState(0);const[containerWidth,setContainerWidth]=useState(0);const[maxHeight,setMaxHeight]=useState(0);const lastScrollY=useRef(0);const scrollVelocity=useRef(0);const lastScrollTime=useRef(0);const scrollRAF=useRef(null);const resizeTimeout=useRef(null);const currentDirectionRef=useRef(direction);const x=useMotionValue(0);// Memoize measurement function\nconst measureContent=useCallback(()=>{if(!contentRef.current)return;const width=contentRef.current.offsetWidth;const childElements=contentRef.current.children;let tallest=0;Array.from(childElements).forEach(child=>{const childHeight=child.offsetHeight;if(childHeight>tallest)tallest=childHeight;});// Batch state updates\nstartTransition(()=>{setContentWidth(width);setMaxHeight(tallest);});},[]);const measureContainer=useCallback(()=>{if(!containerRef.current)return;startTransition(()=>{setContainerWidth(containerRef.current.offsetWidth);});},[]);useLayoutEffect(()=>{measureContent();measureContainer();// Debounced ResizeObserver\nconst resizeObserver=new ResizeObserver(()=>{if(resizeTimeout.current!==null){cancelAnimationFrame(resizeTimeout.current);}resizeTimeout.current=requestAnimationFrame(()=>{measureContent();measureContainer();});});if(contentRef.current){resizeObserver.observe(contentRef.current);}if(containerRef.current){resizeObserver.observe(containerRef.current);}return()=>{resizeObserver.disconnect();if(resizeTimeout.current!==null){cancelAnimationFrame(resizeTimeout.current);}};},[children,gap,measureContent,measureContainer]);// Calculate how many copies we need to fill the screen plus buffers\nconst numCopies=useMemo(()=>{return contentWidth>0?Math.ceil(containerWidth*3/(contentWidth+gap))+2:3;},[contentWidth,containerWidth,gap]);useEffect(()=>{if(typeof window===\"undefined\"||!scrollToReverse&&!scrollToSpeed)return;currentDirectionRef.current=direction;let isScrolling=false;const handleScroll=()=>{if(!isScrolling){isScrolling=true;if(scrollRAF.current!==null){cancelAnimationFrame(scrollRAF.current);}scrollRAF.current=requestAnimationFrame(()=>{const currentScrollY=window.scrollY;const currentTime=Date.now();const timeDelta=currentTime-lastScrollTime.current;const scrollDelta=Math.abs(currentScrollY-lastScrollY.current);if(scrollToSpeed&&timeDelta>0){// Calculate scroll velocity in pixels per second\nscrollVelocity.current=scrollDelta/timeDelta*1e3;}if(scrollToReverse){if(currentScrollY<lastScrollY.current){// Scrolling up - reverse direction\ncurrentDirectionRef.current=direction===\"left\"?\"right\":\"left\";}else if(currentScrollY>lastScrollY.current){// Scrolling down - return to default\ncurrentDirectionRef.current=direction;}}lastScrollY.current=currentScrollY;lastScrollTime.current=currentTime;isScrolling=false;});}};// Decay scroll velocity when not scrolling - only if scrollToSpeed is enabled\nconst decayInterval=scrollToSpeed?setInterval(()=>{scrollVelocity.current*=.9;if(scrollVelocity.current<1){scrollVelocity.current=0;}},50):null;window.addEventListener(\"scroll\",handleScroll,{passive:true});return()=>{window.removeEventListener(\"scroll\",handleScroll);if(decayInterval)clearInterval(decayInterval);if(scrollRAF.current!==null){cancelAnimationFrame(scrollRAF.current);}};},[direction,scrollToReverse,scrollToSpeed]);// Continuous animation loop\nuseAnimationFrame((t,delta)=>{if(contentWidth===0)return;const effectiveSpeed=scrollToSpeed?speed+scrollVelocity.current:speed;const moveDistance=effectiveSpeed*delta/1e3;const currentX=x.get();const loopDistance=contentWidth+gap;if(currentDirectionRef.current===\"left\"){const newX=currentX-moveDistance;x.set(newX<=-loopDistance?newX+loopDistance:newX);}else{const newX=currentX+moveDistance;x.set(newX>=0?newX-loopDistance:newX);}});// Memoize alignment style\nconst alignmentStyle=useMemo(()=>({alignItems:verticalAlign===\"top\"?\"flex-start\":verticalAlign===\"bottom\"?\"flex-end\":\"center\"}),[verticalAlign]);return /*#__PURE__*/_jsx(\"div\",{ref:containerRef,style:{width:\"100%\",height:maxHeight>0?`${maxHeight}px`:\"100%\",minHeight:\"5px\",overflow:\"visible\",position:\"relative\",display:\"flex\"},children:/*#__PURE__*/_jsx(motion.div,{style:{display:\"flex\",gap:`${gap}px`,position:\"absolute\",left:0,willChange:\"transform\",height:\"100%\",x},children:Array.from({length:numCopies}).map((_,index)=>/*#__PURE__*/_jsx(\"div\",{ref:index===0?contentRef:null,style:{display:\"flex\",gap:`${gap}px`,...alignmentStyle,height:\"100%\"},\"aria-hidden\":index>0,children:children},index))})});}addPropertyControls(InfiniteTicker,{children:{type:ControlType.Array,control:{type:ControlType.ComponentInstance},title:\"Items\"},speed:{type:ControlType.Number,title:\"Speed\",defaultValue:50,min:1,max:500,step:1},direction:{type:ControlType.Enum,title:\"Direction\",options:[\"left\",\"right\"],optionTitles:[\"Left\",\"Right\"],defaultValue:\"left\",displaySegmentedControl:true},gap:{type:ControlType.Number,title:\"Gap\",defaultValue:20,min:0,max:500,step:1,unit:\"px\"},verticalAlign:{type:ControlType.Enum,title:\"Alignment\",options:[\"top\",\"center\",\"bottom\"],optionTitles:[\"Top\",\"Center\",\"Bottom\"],defaultValue:\"center\",displaySegmentedControl:true},scrollToReverse:{type:ControlType.Boolean,title:\"Scroll to Reverse\",defaultValue:false,enabledTitle:\"On\",disabledTitle:\"Off\"},scrollToSpeed:{type:ControlType.Boolean,title:\"Scroll to Speed\",defaultValue:false,enabledTitle:\"On\",disabledTitle:\"Off\",description:\"Component made by Anton Drukarov\"}});\nexport const __FramerMetadata__ = {\"exports\":{\"default\":{\"type\":\"reactComponent\",\"name\":\"InfiniteTicker\",\"slots\":[\"children\"],\"annotations\":{\"framerContractVersion\":\"1\",\"framerDisableUnlink\":\"*\",\"framerSupportedLayoutHeight\":\"fixed\",\"framerSupportedLayoutWidth\":\"fixed\"}},\"__FramerMetadata__\":{\"type\":\"variable\"}}}\n//# sourceMappingURL=./InfiniteTicker.map"],"mappings":"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"}