Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion public/r/ScrollVelocity-JS-CSS.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 <span className={className} key={i} ref={i === 0 ? copyRef : null}>\n {children}\n </span>\n );\n }\n\n return (\n <div className={parallaxClassName} style={parallaxStyle}>\n <motion.div className={scrollerClassName} style={{ x, ...scrollerStyle }}>\n {spans}\n </motion.div>\n </div>\n );\n }\n\n return (\n <section>\n {texts.map((text, index) => (\n <VelocityText\n key={index}\n className={className}\n baseVelocity={index % 2 !== 0 ? -velocity : velocity}\n scrollContainerRef={scrollContainerRef}\n damping={damping}\n stiffness={stiffness}\n numCopies={numCopies}\n velocityMapping={velocityMapping}\n parallaxClassName={parallaxClassName}\n scrollerClassName={scrollerClassName}\n parallaxStyle={parallaxStyle}\n scrollerStyle={scrollerStyle}\n >\n {text}&nbsp;\n </VelocityText>\n ))}\n </section>\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 <span className={className} key={i} ref={i === 0 ? copyRef : null}>\n {children}&nbsp;\n </span>\n );\n }\n\n return (\n <div className={parallaxClassName} style={parallaxStyle}>\n <motion.div className={scrollerClassName} style={{ x, ...scrollerStyle }}>\n {spans}\n </motion.div>\n </div>\n );\n }\n\n return (\n <section>\n {texts.map((text, index) => (\n <VelocityText\n key={index}\n className={className}\n baseVelocity={index % 2 !== 0 ? -velocity : velocity}\n scrollContainerRef={scrollContainerRef}\n damping={damping}\n stiffness={stiffness}\n numCopies={numCopies}\n velocityMapping={velocityMapping}\n parallaxClassName={parallaxClassName}\n scrollerClassName={scrollerClassName}\n parallaxStyle={parallaxStyle}\n scrollerStyle={scrollerStyle}\n >\n {text}\n </VelocityText>\n ))}\n </section>\n );\n};\n\nexport default ScrollVelocity;\n"
}
],
"registryDependencies": [],
Expand Down
2 changes: 1 addition & 1 deletion public/r/ScrollVelocity-JS-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 <span className={`flex-shrink-0 ${className}`} key={i} ref={i === 0 ? copyRef : null}>\n {children}\n </span>\n );\n }\n\n return (\n <div className={`${parallaxClassName} relative overflow-hidden`} style={parallaxStyle}>\n <motion.div\n className={`${scrollerClassName} flex whitespace-nowrap text-center font-sans text-4xl font-bold tracking-[-0.02em] drop-shadow md:text-[5rem] md:leading-[5rem]`}\n style={{ x, ...scrollerStyle }}\n >\n {spans}\n </motion.div>\n </div>\n );\n }\n\n return (\n <section>\n {texts.map((text, index) => (\n <VelocityText\n key={index}\n className={className}\n baseVelocity={index % 2 !== 0 ? -velocity : velocity}\n scrollContainerRef={scrollContainerRef}\n damping={damping}\n stiffness={stiffness}\n numCopies={numCopies}\n velocityMapping={velocityMapping}\n parallaxClassName={parallaxClassName}\n scrollerClassName={scrollerClassName}\n parallaxStyle={parallaxStyle}\n scrollerStyle={scrollerStyle}\n >\n {text}&nbsp;\n </VelocityText>\n ))}\n </section>\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 <span className={`flex-shrink-0 ${className}`} key={i} ref={i === 0 ? copyRef : null}>\n {children}&nbsp;\n </span>\n );\n }\n\n return (\n <div className={`${parallaxClassName} relative overflow-hidden`} style={parallaxStyle}>\n <motion.div\n className={`${scrollerClassName} flex whitespace-nowrap text-center font-sans text-4xl font-bold tracking-[-0.02em] drop-shadow md:text-[5rem] md:leading-[5rem]`}\n style={{ x, ...scrollerStyle }}\n >\n {spans}\n </motion.div>\n </div>\n );\n }\n\n return (\n <section>\n {texts.map((text, index) => (\n <VelocityText\n key={index}\n className={className}\n baseVelocity={index % 2 !== 0 ? -velocity : velocity}\n scrollContainerRef={scrollContainerRef}\n damping={damping}\n stiffness={stiffness}\n numCopies={numCopies}\n velocityMapping={velocityMapping}\n parallaxClassName={parallaxClassName}\n scrollerClassName={scrollerClassName}\n parallaxStyle={parallaxStyle}\n scrollerStyle={scrollerStyle}\n >\n {text}\n </VelocityText>\n ))}\n </section>\n );\n};\n\nexport default ScrollVelocity;\n"
}
],
"registryDependencies": [],
Expand Down
Loading