diff --git a/public/r/ScrollVelocity-JS-CSS.json b/public/r/ScrollVelocity-JS-CSS.json index 2b7047c0..925419de 100644 --- a/public/r/ScrollVelocity-JS-CSS.json +++ b/public/r/ScrollVelocity-JS-CSS.json @@ -13,7 +13,7 @@ { "type": "registry:component", "path": "ScrollVelocity/ScrollVelocity.jsx", - "content": "import { useRef, useLayoutEffect, useState } from 'react';\nimport {\n motion,\n useScroll,\n useSpring,\n useTransform,\n useMotionValue,\n useVelocity,\n useAnimationFrame\n} from 'motion/react';\nimport './ScrollVelocity.css';\n\nfunction useElementWidth(ref) {\n const [width, setWidth] = useState(0);\n\n useLayoutEffect(() => {\n function updateWidth() {\n if (ref.current) {\n setWidth(ref.current.offsetWidth);\n }\n }\n updateWidth();\n window.addEventListener('resize', updateWidth);\n return () => window.removeEventListener('resize', updateWidth);\n }, [ref]);\n\n return width;\n}\n\nexport const ScrollVelocity = ({\n scrollContainerRef,\n texts = [],\n velocity = 100,\n className = '',\n damping = 50,\n stiffness = 400,\n numCopies = 6,\n velocityMapping = { input: [0, 1000], output: [0, 5] },\n parallaxClassName = 'parallax',\n scrollerClassName = 'scroller',\n parallaxStyle,\n scrollerStyle\n}) => {\n function VelocityText({\n children,\n baseVelocity = velocity,\n scrollContainerRef,\n className = '',\n damping,\n stiffness,\n numCopies,\n velocityMapping,\n parallaxClassName,\n scrollerClassName,\n parallaxStyle,\n scrollerStyle\n }) {\n const baseX = useMotionValue(0);\n const scrollOptions = scrollContainerRef ? { container: scrollContainerRef } : {};\n const { scrollY } = useScroll(scrollOptions);\n const scrollVelocity = useVelocity(scrollY);\n const smoothVelocity = useSpring(scrollVelocity, {\n damping: damping ?? 50,\n stiffness: stiffness ?? 400\n });\n const velocityFactor = useTransform(\n smoothVelocity,\n velocityMapping?.input || [0, 1000],\n velocityMapping?.output || [0, 5],\n { clamp: false }\n );\n\n const copyRef = useRef(null);\n const copyWidth = useElementWidth(copyRef);\n\n function wrap(min, max, v) {\n const range = max - min;\n const mod = (((v - min) % range) + range) % range;\n return mod + min;\n }\n\n const x = useTransform(baseX, v => {\n if (copyWidth === 0) return '0px';\n return `${wrap(-copyWidth, 0, v)}px`;\n });\n\n const directionFactor = useRef(1);\n useAnimationFrame((t, delta) => {\n let moveBy = directionFactor.current * baseVelocity * (delta / 1000);\n\n if (velocityFactor.get() < 0) {\n directionFactor.current = -1;\n } else if (velocityFactor.get() > 0) {\n directionFactor.current = 1;\n }\n\n moveBy += directionFactor.current * moveBy * velocityFactor.get();\n baseX.set(baseX.get() + moveBy);\n });\n\n const spans = [];\n for (let i = 0; i < numCopies; i++) {\n spans.push(\n \n {children}\n \n );\n }\n\n return (\n
\n \n {spans}\n \n
\n );\n }\n\n return (\n
\n {texts.map((text, index) => (\n \n {text} \n \n ))}\n
\n );\n};\n\nexport default ScrollVelocity;\n" + "content": "import { useRef, useLayoutEffect, useState } from 'react';\nimport {\n motion,\n useScroll,\n useSpring,\n useTransform,\n useMotionValue,\n useVelocity,\n useAnimationFrame\n} from 'motion/react';\nimport './ScrollVelocity.css';\n\nfunction useElementWidth(ref) {\n const [width, setWidth] = useState(0);\n\n useLayoutEffect(() => {\n function updateWidth() {\n if (ref.current) {\n setWidth(ref.current.offsetWidth);\n }\n }\n updateWidth();\n window.addEventListener('resize', updateWidth);\n return () => window.removeEventListener('resize', updateWidth);\n }, [ref]);\n\n return width;\n}\n\nexport const ScrollVelocity = ({\n scrollContainerRef,\n texts = [],\n velocity = 100,\n className = '',\n damping = 50,\n stiffness = 400,\n numCopies = 6,\n velocityMapping = { input: [0, 1000], output: [0, 5] },\n parallaxClassName = 'parallax',\n scrollerClassName = 'scroller',\n parallaxStyle,\n scrollerStyle\n}) => {\n function VelocityText({\n children,\n baseVelocity = velocity,\n scrollContainerRef,\n className = '',\n damping,\n stiffness,\n numCopies,\n velocityMapping,\n parallaxClassName,\n scrollerClassName,\n parallaxStyle,\n scrollerStyle\n }) {\n const baseX = useMotionValue(0);\n const scrollOptions = scrollContainerRef ? { container: scrollContainerRef } : {};\n const { scrollY } = useScroll(scrollOptions);\n const scrollVelocity = useVelocity(scrollY);\n const smoothVelocity = useSpring(scrollVelocity, {\n damping: damping ?? 50,\n stiffness: stiffness ?? 400\n });\n const velocityFactor = useTransform(\n smoothVelocity,\n velocityMapping?.input || [0, 1000],\n velocityMapping?.output || [0, 5],\n { clamp: false }\n );\n\n const copyRef = useRef(null);\n const copyWidth = useElementWidth(copyRef);\n\n function wrap(min, max, v) {\n const range = max - min;\n const mod = (((v - min) % range) + range) % range;\n return mod + min;\n }\n\n const x = useTransform(baseX, v => {\n if (copyWidth === 0) return '0px';\n return `${wrap(-copyWidth, 0, v)}px`;\n });\n\n const directionFactor = useRef(1);\n useAnimationFrame((t, delta) => {\n let moveBy = directionFactor.current * baseVelocity * (delta / 1000);\n\n if (velocityFactor.get() < 0) {\n directionFactor.current = -1;\n } else if (velocityFactor.get() > 0) {\n directionFactor.current = 1;\n }\n\n moveBy += directionFactor.current * moveBy * velocityFactor.get();\n baseX.set(baseX.get() + moveBy);\n });\n\n const spans = [];\n for (let i = 0; i < numCopies; i++) {\n spans.push(\n \n {children} \n \n );\n }\n\n return (\n
\n \n {spans}\n \n
\n );\n }\n\n return (\n
\n {texts.map((text, index) => (\n \n {text}\n \n ))}\n
\n );\n};\n\nexport default ScrollVelocity;\n" } ], "registryDependencies": [], diff --git a/public/r/ScrollVelocity-JS-TW.json b/public/r/ScrollVelocity-JS-TW.json index d8fe0f5e..9c1b8216 100644 --- a/public/r/ScrollVelocity-JS-TW.json +++ b/public/r/ScrollVelocity-JS-TW.json @@ -8,7 +8,7 @@ { "type": "registry:component", "path": "ScrollVelocity/ScrollVelocity.jsx", - "content": "import { useRef, useLayoutEffect, useState } from 'react';\nimport {\n motion,\n useScroll,\n useSpring,\n useTransform,\n useMotionValue,\n useVelocity,\n useAnimationFrame\n} from 'motion/react';\n\nfunction useElementWidth(ref) {\n const [width, setWidth] = useState(0);\n\n useLayoutEffect(() => {\n function updateWidth() {\n if (ref.current) {\n setWidth(ref.current.offsetWidth);\n }\n }\n updateWidth();\n window.addEventListener('resize', updateWidth);\n return () => window.removeEventListener('resize', updateWidth);\n }, [ref]);\n\n return width;\n}\n\nexport const ScrollVelocity = ({\n scrollContainerRef,\n texts = [],\n velocity = 100,\n className = '',\n damping = 50,\n stiffness = 400,\n numCopies = 6,\n velocityMapping = { input: [0, 1000], output: [0, 5] },\n parallaxClassName,\n scrollerClassName,\n parallaxStyle,\n scrollerStyle\n}) => {\n function VelocityText({\n children,\n baseVelocity = velocity,\n scrollContainerRef,\n className = '',\n damping,\n stiffness,\n numCopies,\n velocityMapping,\n parallaxClassName,\n scrollerClassName,\n parallaxStyle,\n scrollerStyle\n }) {\n const baseX = useMotionValue(0);\n const scrollOptions = scrollContainerRef ? { container: scrollContainerRef } : {};\n const { scrollY } = useScroll(scrollOptions);\n const scrollVelocity = useVelocity(scrollY);\n const smoothVelocity = useSpring(scrollVelocity, {\n damping: damping ?? 50,\n stiffness: stiffness ?? 400\n });\n const velocityFactor = useTransform(\n smoothVelocity,\n velocityMapping?.input || [0, 1000],\n velocityMapping?.output || [0, 5],\n { clamp: false }\n );\n\n const copyRef = useRef(null);\n const copyWidth = useElementWidth(copyRef);\n\n function wrap(min, max, v) {\n const range = max - min;\n const mod = (((v - min) % range) + range) % range;\n return mod + min;\n }\n\n const x = useTransform(baseX, v => {\n if (copyWidth === 0) return '0px';\n return `${wrap(-copyWidth, 0, v)}px`;\n });\n\n const directionFactor = useRef(1);\n useAnimationFrame((t, delta) => {\n let moveBy = directionFactor.current * baseVelocity * (delta / 1000);\n\n if (velocityFactor.get() < 0) {\n directionFactor.current = -1;\n } else if (velocityFactor.get() > 0) {\n directionFactor.current = 1;\n }\n\n moveBy += directionFactor.current * moveBy * velocityFactor.get();\n baseX.set(baseX.get() + moveBy);\n });\n\n const spans = [];\n for (let i = 0; i < (numCopies ?? 1); i++) {\n spans.push(\n \n {children}\n \n );\n }\n\n return (\n
\n \n {spans}\n \n
\n );\n }\n\n return (\n
\n {texts.map((text, index) => (\n \n {text} \n \n ))}\n
\n );\n};\n\nexport default ScrollVelocity;\n" + "content": "import { useRef, useLayoutEffect, useState } from 'react';\nimport {\n motion,\n useScroll,\n useSpring,\n useTransform,\n useMotionValue,\n useVelocity,\n useAnimationFrame\n} from 'motion/react';\n\nfunction useElementWidth(ref) {\n const [width, setWidth] = useState(0);\n\n useLayoutEffect(() => {\n function updateWidth() {\n if (ref.current) {\n setWidth(ref.current.offsetWidth);\n }\n }\n updateWidth();\n window.addEventListener('resize', updateWidth);\n return () => window.removeEventListener('resize', updateWidth);\n }, [ref]);\n\n return width;\n}\n\nexport const ScrollVelocity = ({\n scrollContainerRef,\n texts = [],\n velocity = 100,\n className = '',\n damping = 50,\n stiffness = 400,\n numCopies = 6,\n velocityMapping = { input: [0, 1000], output: [0, 5] },\n parallaxClassName,\n scrollerClassName,\n parallaxStyle,\n scrollerStyle\n}) => {\n function VelocityText({\n children,\n baseVelocity = velocity,\n scrollContainerRef,\n className = '',\n damping,\n stiffness,\n numCopies,\n velocityMapping,\n parallaxClassName,\n scrollerClassName,\n parallaxStyle,\n scrollerStyle\n }) {\n const baseX = useMotionValue(0);\n const scrollOptions = scrollContainerRef ? { container: scrollContainerRef } : {};\n const { scrollY } = useScroll(scrollOptions);\n const scrollVelocity = useVelocity(scrollY);\n const smoothVelocity = useSpring(scrollVelocity, {\n damping: damping ?? 50,\n stiffness: stiffness ?? 400\n });\n const velocityFactor = useTransform(\n smoothVelocity,\n velocityMapping?.input || [0, 1000],\n velocityMapping?.output || [0, 5],\n { clamp: false }\n );\n\n const copyRef = useRef(null);\n const copyWidth = useElementWidth(copyRef);\n\n function wrap(min, max, v) {\n const range = max - min;\n const mod = (((v - min) % range) + range) % range;\n return mod + min;\n }\n\n const x = useTransform(baseX, v => {\n if (copyWidth === 0) return '0px';\n return `${wrap(-copyWidth, 0, v)}px`;\n });\n\n const directionFactor = useRef(1);\n useAnimationFrame((t, delta) => {\n let moveBy = directionFactor.current * baseVelocity * (delta / 1000);\n\n if (velocityFactor.get() < 0) {\n directionFactor.current = -1;\n } else if (velocityFactor.get() > 0) {\n directionFactor.current = 1;\n }\n\n moveBy += directionFactor.current * moveBy * velocityFactor.get();\n baseX.set(baseX.get() + moveBy);\n });\n\n const spans = [];\n for (let i = 0; i < (numCopies ?? 1); i++) {\n spans.push(\n \n {children} \n \n );\n }\n\n return (\n
\n \n {spans}\n \n
\n );\n }\n\n return (\n
\n {texts.map((text, index) => (\n \n {text}\n \n ))}\n
\n );\n};\n\nexport default ScrollVelocity;\n" } ], "registryDependencies": [], diff --git a/public/r/ScrollVelocity-TS-CSS.json b/public/r/ScrollVelocity-TS-CSS.json index 94b532bb..d7400f6b 100644 --- a/public/r/ScrollVelocity-TS-CSS.json +++ b/public/r/ScrollVelocity-TS-CSS.json @@ -13,7 +13,7 @@ { "type": "registry:component", "path": "ScrollVelocity/ScrollVelocity.tsx", - "content": "import React, { useRef, useLayoutEffect, useState } from 'react';\nimport {\n motion,\n useScroll,\n useSpring,\n useTransform,\n useMotionValue,\n useVelocity,\n useAnimationFrame\n} from 'motion/react';\nimport './ScrollVelocity.css';\n\ninterface VelocityMapping {\n input: [number, number];\n output: [number, number];\n}\n\ninterface VelocityTextProps {\n children: React.ReactNode;\n baseVelocity: number;\n scrollContainerRef?: React.RefObject;\n className?: string;\n damping?: number;\n stiffness?: number;\n numCopies?: number;\n velocityMapping?: VelocityMapping;\n parallaxClassName?: string;\n scrollerClassName?: string;\n parallaxStyle?: React.CSSProperties;\n scrollerStyle?: React.CSSProperties;\n}\n\ninterface ScrollVelocityProps {\n scrollContainerRef?: React.RefObject;\n texts: string[];\n velocity?: number;\n className?: string;\n damping?: number;\n stiffness?: number;\n numCopies?: number;\n velocityMapping?: VelocityMapping;\n parallaxClassName?: string;\n scrollerClassName?: string;\n parallaxStyle?: React.CSSProperties;\n scrollerStyle?: React.CSSProperties;\n}\n\nfunction useElementWidth(ref: React.RefObject): number {\n const [width, setWidth] = useState(0);\n\n useLayoutEffect(() => {\n function updateWidth() {\n if (ref.current) {\n setWidth(ref.current.offsetWidth);\n }\n }\n updateWidth();\n window.addEventListener('resize', updateWidth);\n return () => window.removeEventListener('resize', updateWidth);\n }, [ref]);\n\n return width;\n}\n\nexport const ScrollVelocity: React.FC = ({\n scrollContainerRef,\n texts = [],\n velocity = 100,\n className = '',\n damping = 50,\n stiffness = 400,\n numCopies = 6,\n velocityMapping = { input: [0, 1000], output: [0, 5] },\n parallaxClassName = 'parallax',\n scrollerClassName = 'scroller',\n parallaxStyle,\n scrollerStyle\n}) => {\n function VelocityText({\n children,\n baseVelocity = velocity,\n scrollContainerRef,\n className = '',\n damping,\n stiffness,\n numCopies,\n velocityMapping,\n parallaxClassName,\n scrollerClassName,\n parallaxStyle,\n scrollerStyle\n }: VelocityTextProps) {\n const baseX = useMotionValue(0);\n const scrollOptions = scrollContainerRef ? { container: scrollContainerRef } : {};\n const { scrollY } = useScroll(scrollOptions);\n const scrollVelocity = useVelocity(scrollY);\n const smoothVelocity = useSpring(scrollVelocity, {\n damping: damping ?? 50,\n stiffness: stiffness ?? 400\n });\n const velocityFactor = useTransform(\n smoothVelocity,\n velocityMapping?.input || [0, 1000],\n velocityMapping?.output || [0, 5],\n { clamp: false }\n );\n\n const copyRef = useRef(null);\n const copyWidth = useElementWidth(copyRef);\n\n function wrap(min: number, max: number, v: number): number {\n const range = max - min;\n const mod = (((v - min) % range) + range) % range;\n return mod + min;\n }\n\n const x = useTransform(baseX, v => {\n if (copyWidth === 0) return '0px';\n return `${wrap(-copyWidth, 0, v)}px`;\n });\n\n const directionFactor = useRef(1);\n useAnimationFrame((t, delta) => {\n let moveBy = directionFactor.current * baseVelocity * (delta / 1000);\n\n if (velocityFactor.get() < 0) {\n directionFactor.current = -1;\n } else if (velocityFactor.get() > 0) {\n directionFactor.current = 1;\n }\n\n moveBy += directionFactor.current * moveBy * velocityFactor.get();\n baseX.set(baseX.get() + moveBy);\n });\n\n const spans = [];\n for (let i = 0; i < numCopies!; i++) {\n spans.push(\n \n {children}\n \n );\n }\n\n return (\n
\n \n {spans}\n \n
\n );\n }\n\n return (\n
\n {texts.map((text: string, index: number) => (\n \n {text} \n \n ))}\n
\n );\n};\n\nexport default ScrollVelocity;\n" + "content": "import React, { useRef, useLayoutEffect, useState } from 'react';\nimport {\n motion,\n useScroll,\n useSpring,\n useTransform,\n useMotionValue,\n useVelocity,\n useAnimationFrame\n} from 'motion/react';\nimport './ScrollVelocity.css';\n\ninterface VelocityMapping {\n input: [number, number];\n output: [number, number];\n}\n\ninterface VelocityTextProps {\n children: React.ReactNode;\n baseVelocity: number;\n scrollContainerRef?: React.RefObject;\n className?: string;\n damping?: number;\n stiffness?: number;\n numCopies?: number;\n velocityMapping?: VelocityMapping;\n parallaxClassName?: string;\n scrollerClassName?: string;\n parallaxStyle?: React.CSSProperties;\n scrollerStyle?: React.CSSProperties;\n}\n\ninterface ScrollVelocityProps {\n scrollContainerRef?: React.RefObject;\n texts: React.ReactNode[];\n velocity?: number;\n className?: string;\n damping?: number;\n stiffness?: number;\n numCopies?: number;\n velocityMapping?: VelocityMapping;\n parallaxClassName?: string;\n scrollerClassName?: string;\n parallaxStyle?: React.CSSProperties;\n scrollerStyle?: React.CSSProperties;\n}\n\nfunction useElementWidth(ref: React.RefObject): number {\n const [width, setWidth] = useState(0);\n\n useLayoutEffect(() => {\n function updateWidth() {\n if (ref.current) {\n setWidth(ref.current.offsetWidth);\n }\n }\n updateWidth();\n window.addEventListener('resize', updateWidth);\n return () => window.removeEventListener('resize', updateWidth);\n }, [ref]);\n\n return width;\n}\n\nexport const ScrollVelocity: React.FC = ({\n scrollContainerRef,\n texts = [],\n velocity = 100,\n className = '',\n damping = 50,\n stiffness = 400,\n numCopies = 6,\n velocityMapping = { input: [0, 1000], output: [0, 5] },\n parallaxClassName = 'parallax',\n scrollerClassName = 'scroller',\n parallaxStyle,\n scrollerStyle\n}) => {\n function VelocityText({\n children,\n baseVelocity = velocity,\n scrollContainerRef,\n className = '',\n damping,\n stiffness,\n numCopies,\n velocityMapping,\n parallaxClassName,\n scrollerClassName,\n parallaxStyle,\n scrollerStyle\n }: VelocityTextProps) {\n const baseX = useMotionValue(0);\n const scrollOptions = scrollContainerRef ? { container: scrollContainerRef } : {};\n const { scrollY } = useScroll(scrollOptions);\n const scrollVelocity = useVelocity(scrollY);\n const smoothVelocity = useSpring(scrollVelocity, {\n damping: damping ?? 50,\n stiffness: stiffness ?? 400\n });\n const velocityFactor = useTransform(\n smoothVelocity,\n velocityMapping?.input || [0, 1000],\n velocityMapping?.output || [0, 5],\n { clamp: false }\n );\n\n const copyRef = useRef(null);\n const copyWidth = useElementWidth(copyRef);\n\n function wrap(min: number, max: number, v: number): number {\n const range = max - min;\n const mod = (((v - min) % range) + range) % range;\n return mod + min;\n }\n\n const x = useTransform(baseX, v => {\n if (copyWidth === 0) return '0px';\n return `${wrap(-copyWidth, 0, v)}px`;\n });\n\n const directionFactor = useRef(1);\n useAnimationFrame((t, delta) => {\n let moveBy = directionFactor.current * baseVelocity * (delta / 1000);\n\n if (velocityFactor.get() < 0) {\n directionFactor.current = -1;\n } else if (velocityFactor.get() > 0) {\n directionFactor.current = 1;\n }\n\n moveBy += directionFactor.current * moveBy * velocityFactor.get();\n baseX.set(baseX.get() + moveBy);\n });\n\n const spans = [];\n for (let i = 0; i < (numCopies ?? 6); i++) {\n spans.push(\n \n {children} \n \n );\n }\n\n return (\n
\n \n {spans}\n \n
\n );\n }\n\n return (\n
\n {texts.map((text, index) => (\n \n {text}\n \n ))}\n
\n );\n};\n\nexport default ScrollVelocity;\n" } ], "registryDependencies": [], diff --git a/public/r/ScrollVelocity-TS-TW.json b/public/r/ScrollVelocity-TS-TW.json index 8cb66b96..e3872326 100644 --- a/public/r/ScrollVelocity-TS-TW.json +++ b/public/r/ScrollVelocity-TS-TW.json @@ -8,7 +8,7 @@ { "type": "registry:component", "path": "ScrollVelocity/ScrollVelocity.tsx", - "content": "import React, { useRef, useLayoutEffect, useState } from 'react';\nimport {\n motion,\n useScroll,\n useSpring,\n useTransform,\n useMotionValue,\n useVelocity,\n useAnimationFrame\n} from 'motion/react';\n\ninterface VelocityMapping {\n input: [number, number];\n output: [number, number];\n}\n\ninterface VelocityTextProps {\n children: React.ReactNode;\n baseVelocity: number;\n scrollContainerRef?: React.RefObject;\n className?: string;\n damping?: number;\n stiffness?: number;\n numCopies?: number;\n velocityMapping?: VelocityMapping;\n parallaxClassName?: string;\n scrollerClassName?: string;\n parallaxStyle?: React.CSSProperties;\n scrollerStyle?: React.CSSProperties;\n}\n\ninterface ScrollVelocityProps {\n scrollContainerRef?: React.RefObject;\n texts: string[];\n velocity?: number;\n className?: string;\n damping?: number;\n stiffness?: number;\n numCopies?: number;\n velocityMapping?: VelocityMapping;\n parallaxClassName?: string;\n scrollerClassName?: string;\n parallaxStyle?: React.CSSProperties;\n scrollerStyle?: React.CSSProperties;\n}\n\nfunction useElementWidth(ref: React.RefObject): number {\n const [width, setWidth] = useState(0);\n\n useLayoutEffect(() => {\n function updateWidth() {\n if (ref.current) {\n setWidth(ref.current.offsetWidth);\n }\n }\n updateWidth();\n window.addEventListener('resize', updateWidth);\n return () => window.removeEventListener('resize', updateWidth);\n }, [ref]);\n\n return width;\n}\n\nexport const ScrollVelocity: React.FC = ({\n scrollContainerRef,\n texts = [],\n velocity = 100,\n className = '',\n damping = 50,\n stiffness = 400,\n numCopies = 6,\n velocityMapping = { input: [0, 1000], output: [0, 5] },\n parallaxClassName,\n scrollerClassName,\n parallaxStyle,\n scrollerStyle\n}) => {\n function VelocityText({\n children,\n baseVelocity = velocity,\n scrollContainerRef,\n className = '',\n damping,\n stiffness,\n numCopies,\n velocityMapping,\n parallaxClassName,\n scrollerClassName,\n parallaxStyle,\n scrollerStyle\n }: VelocityTextProps) {\n const baseX = useMotionValue(0);\n const scrollOptions = scrollContainerRef ? { container: scrollContainerRef } : {};\n const { scrollY } = useScroll(scrollOptions);\n const scrollVelocity = useVelocity(scrollY);\n const smoothVelocity = useSpring(scrollVelocity, {\n damping: damping ?? 50,\n stiffness: stiffness ?? 400\n });\n const velocityFactor = useTransform(\n smoothVelocity,\n velocityMapping?.input || [0, 1000],\n velocityMapping?.output || [0, 5],\n { clamp: false }\n );\n\n const copyRef = useRef(null);\n const copyWidth = useElementWidth(copyRef);\n\n function wrap(min: number, max: number, v: number): number {\n const range = max - min;\n const mod = (((v - min) % range) + range) % range;\n return mod + min;\n }\n\n const x = useTransform(baseX, v => {\n if (copyWidth === 0) return '0px';\n return `${wrap(-copyWidth, 0, v)}px`;\n });\n\n const directionFactor = useRef(1);\n useAnimationFrame((t, delta) => {\n let moveBy = directionFactor.current * baseVelocity * (delta / 1000);\n\n if (velocityFactor.get() < 0) {\n directionFactor.current = -1;\n } else if (velocityFactor.get() > 0) {\n directionFactor.current = 1;\n }\n\n moveBy += directionFactor.current * moveBy * velocityFactor.get();\n baseX.set(baseX.get() + moveBy);\n });\n\n const spans = [];\n for (let i = 0; i < numCopies!; i++) {\n spans.push(\n \n {children}\n \n );\n }\n\n return (\n
\n \n {spans}\n \n
\n );\n }\n\n return (\n
\n {texts.map((text: string, index: number) => (\n \n {text} \n \n ))}\n
\n );\n};\n\nexport default ScrollVelocity;\n" + "content": "import React, { useRef, useLayoutEffect, useState } from 'react';\nimport {\n motion,\n useScroll,\n useSpring,\n useTransform,\n useMotionValue,\n useVelocity,\n useAnimationFrame\n} from 'motion/react';\n\ninterface VelocityMapping {\n input: [number, number];\n output: [number, number];\n}\n\ninterface VelocityTextProps {\n children: React.ReactNode;\n baseVelocity: number;\n scrollContainerRef?: React.RefObject;\n className?: string;\n damping?: number;\n stiffness?: number;\n numCopies?: number;\n velocityMapping?: VelocityMapping;\n parallaxClassName?: string;\n scrollerClassName?: string;\n parallaxStyle?: React.CSSProperties;\n scrollerStyle?: React.CSSProperties;\n}\n\ninterface ScrollVelocityProps {\n scrollContainerRef?: React.RefObject;\n texts: React.ReactNode[];\n velocity?: number;\n className?: string;\n damping?: number;\n stiffness?: number;\n numCopies?: number;\n velocityMapping?: VelocityMapping;\n parallaxClassName?: string;\n scrollerClassName?: string;\n parallaxStyle?: React.CSSProperties;\n scrollerStyle?: React.CSSProperties;\n}\n\nfunction useElementWidth(ref: React.RefObject): number {\n const [width, setWidth] = useState(0);\n\n useLayoutEffect(() => {\n function updateWidth() {\n if (ref.current) {\n setWidth(ref.current.offsetWidth);\n }\n }\n updateWidth();\n window.addEventListener('resize', updateWidth);\n return () => window.removeEventListener('resize', updateWidth);\n }, [ref]);\n\n return width;\n}\n\nexport const ScrollVelocity: React.FC = ({\n scrollContainerRef,\n texts = [],\n velocity = 100,\n className = '',\n damping = 50,\n stiffness = 400,\n numCopies = 6,\n velocityMapping = { input: [0, 1000], output: [0, 5] },\n parallaxClassName,\n scrollerClassName,\n parallaxStyle,\n scrollerStyle\n}) => {\n function VelocityText({\n children,\n baseVelocity = velocity,\n scrollContainerRef,\n className = '',\n damping,\n stiffness,\n numCopies,\n velocityMapping,\n parallaxClassName,\n scrollerClassName,\n parallaxStyle,\n scrollerStyle\n }: VelocityTextProps) {\n const baseX = useMotionValue(0);\n const scrollOptions = scrollContainerRef ? { container: scrollContainerRef } : {};\n const { scrollY } = useScroll(scrollOptions);\n const scrollVelocity = useVelocity(scrollY);\n const smoothVelocity = useSpring(scrollVelocity, {\n damping: damping ?? 50,\n stiffness: stiffness ?? 400\n });\n const velocityFactor = useTransform(\n smoothVelocity,\n velocityMapping?.input || [0, 1000],\n velocityMapping?.output || [0, 5],\n { clamp: false }\n );\n\n const copyRef = useRef(null);\n const copyWidth = useElementWidth(copyRef);\n\n function wrap(min: number, max: number, v: number): number {\n const range = max - min;\n const mod = (((v - min) % range) + range) % range;\n return mod + min;\n }\n\n const x = useTransform(baseX, v => {\n if (copyWidth === 0) return '0px';\n return `${wrap(-copyWidth, 0, v)}px`;\n });\n\n const directionFactor = useRef(1);\n useAnimationFrame((t, delta) => {\n let moveBy = directionFactor.current * baseVelocity * (delta / 1000);\n\n if (velocityFactor.get() < 0) {\n directionFactor.current = -1;\n } else if (velocityFactor.get() > 0) {\n directionFactor.current = 1;\n }\n\n moveBy += directionFactor.current * moveBy * velocityFactor.get();\n baseX.set(baseX.get() + moveBy);\n });\n\n const spans = [];\n for (let i = 0; i < (numCopies ?? 6); i++) {\n spans.push(\n \n {children} \n \n );\n }\n\n return (\n
\n \n {spans}\n \n
\n );\n }\n\n return (\n
\n {texts.map((text, index) => (\n \n {text}\n \n ))}\n
\n );\n};\n\nexport default ScrollVelocity;\n" } ], "registryDependencies": [], diff --git a/src/content/TextAnimations/ScrollVelocity/ScrollVelocity.jsx b/src/content/TextAnimations/ScrollVelocity/ScrollVelocity.jsx index 981e50bb..bdf4a6ae 100644 --- a/src/content/TextAnimations/ScrollVelocity/ScrollVelocity.jsx +++ b/src/content/TextAnimations/ScrollVelocity/ScrollVelocity.jsx @@ -102,7 +102,7 @@ export const ScrollVelocity = ({ for (let i = 0; i < numCopies; i++) { spans.push( - {children} + {children}  ); } @@ -133,7 +133,7 @@ export const ScrollVelocity = ({ parallaxStyle={parallaxStyle} scrollerStyle={scrollerStyle} > - {text}  + {text} ))} diff --git a/src/demo/TextAnimations/ScrollVelocityDemo.jsx b/src/demo/TextAnimations/ScrollVelocityDemo.jsx index 6baa707a..8167e156 100644 --- a/src/demo/TextAnimations/ScrollVelocityDemo.jsx +++ b/src/demo/TextAnimations/ScrollVelocityDemo.jsx @@ -33,9 +33,9 @@ const ScrollVelocityDemo = () => { }, { name: 'texts', - type: 'string[]', + type: 'React.ReactNode[]', default: '[]', - description: 'Array of strings to display as scrolling text.' + description: 'Array of items to display as scrolling content. Accepts strings, JSX elements, icons, or any valid React node.' }, { name: 'velocity', diff --git a/src/tailwind/TextAnimations/ScrollVelocity/ScrollVelocity.jsx b/src/tailwind/TextAnimations/ScrollVelocity/ScrollVelocity.jsx index 1b57c04c..3e206f9f 100644 --- a/src/tailwind/TextAnimations/ScrollVelocity/ScrollVelocity.jsx +++ b/src/tailwind/TextAnimations/ScrollVelocity/ScrollVelocity.jsx @@ -101,7 +101,7 @@ export const ScrollVelocity = ({ for (let i = 0; i < (numCopies ?? 1); i++) { spans.push( - {children} + {children}  ); } @@ -135,7 +135,7 @@ export const ScrollVelocity = ({ parallaxStyle={parallaxStyle} scrollerStyle={scrollerStyle} > - {text}  + {text} ))} diff --git a/src/ts-default/TextAnimations/ScrollVelocity/ScrollVelocity.tsx b/src/ts-default/TextAnimations/ScrollVelocity/ScrollVelocity.tsx index 5465420e..ac1b5421 100644 --- a/src/ts-default/TextAnimations/ScrollVelocity/ScrollVelocity.tsx +++ b/src/ts-default/TextAnimations/ScrollVelocity/ScrollVelocity.tsx @@ -32,7 +32,7 @@ interface VelocityTextProps { interface ScrollVelocityProps { scrollContainerRef?: React.RefObject; - texts: string[]; + texts: React.ReactNode[]; velocity?: number; className?: string; damping?: number; @@ -134,10 +134,10 @@ export const ScrollVelocity: React.FC = ({ }); const spans = []; - for (let i = 0; i < numCopies!; i++) { + for (let i = 0; i < (numCopies ?? 6); i++) { spans.push( - {children} + {children}  ); } @@ -153,7 +153,7 @@ export const ScrollVelocity: React.FC = ({ return (
- {texts.map((text: string, index: number) => ( + {texts.map((text, index) => ( = ({ parallaxStyle={parallaxStyle} scrollerStyle={scrollerStyle} > - {text}  + {text} ))}
diff --git a/src/ts-tailwind/TextAnimations/ScrollVelocity/ScrollVelocity.tsx b/src/ts-tailwind/TextAnimations/ScrollVelocity/ScrollVelocity.tsx index 3b37deae..0996e043 100644 --- a/src/ts-tailwind/TextAnimations/ScrollVelocity/ScrollVelocity.tsx +++ b/src/ts-tailwind/TextAnimations/ScrollVelocity/ScrollVelocity.tsx @@ -31,7 +31,7 @@ interface VelocityTextProps { interface ScrollVelocityProps { scrollContainerRef?: React.RefObject; - texts: string[]; + texts: React.ReactNode[]; velocity?: number; className?: string; damping?: number; @@ -133,10 +133,10 @@ export const ScrollVelocity: React.FC = ({ }); const spans = []; - for (let i = 0; i < numCopies!; i++) { + for (let i = 0; i < (numCopies ?? 6); i++) { spans.push( - {children} + {children}  ); } @@ -155,7 +155,7 @@ export const ScrollVelocity: React.FC = ({ return (
- {texts.map((text: string, index: number) => ( + {texts.map((text, index) => ( = ({ parallaxStyle={parallaxStyle} scrollerStyle={scrollerStyle} > - {text}  + {text} ))}