flow-scroll
obsidianui/flow-scrollFreeComponent
obsidianui publishes no description for this item.
Live preview
live · rendered by the registry
Rendered by obsidianui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://obsidianui.dev/r/flow-scroll.jsonSource
1'use client';23import { motion, MotionValue, useScroll, useTransform } from 'framer-motion';4import Image from 'next/image';5import React, { useRef } from 'react';67interface FlowScrollCardProps {8 image: string;9 index: number;10 scrollYProgress: MotionValue<number>;11 totalItems: number;12}1314const FlowScrollCard = ({ image, index, scrollYProgress, totalItems }: FlowScrollCardProps) => {15 const ITEMS_PER_ROW = 3;16 const prev = Math.max(0, index - ITEMS_PER_ROW);17 const next = Math.min(totalItems - 1, index + ITEMS_PER_ROW);1819 const previousRow = Math.floor(prev / ITEMS_PER_ROW);20 const currentRow = Math.floor(index / ITEMS_PER_ROW);21 const nextRow = Math.floor(next / ITEMS_PER_ROW);22 const totalRows = Math.floor(totalItems / ITEMS_PER_ROW);23 const scrollRangePerRow = 1 / totalRows;2425 const entryAnimation = previousRow / totalRows - scrollRangePerRow;26 const currPosition = currentRow / totalRows;27 const holdAnimationStart = currPosition;28 const holdAnimationEnd = currPosition;29 const exitAnimation = nextRow / totalRows + scrollRangePerRow * 2;3031 const offsetToAdd = (scrollRangePerRow / totalItems) * (currentRow + 2);32 const range = [0, entryAnimation - offsetToAdd, holdAnimationStart - offsetToAdd, holdAnimationEnd - offsetToAdd, exitAnimation - offsetToAdd, 1];3334 const scale = useTransform(scrollYProgress, range, [0.5, 0.5, 1, 1, 0.5, 0.5]);35 const isLeft = index % ITEMS_PER_ROW === 0;36 const isRight = index % ITEMS_PER_ROW === 2;37 const xTransform = useTransform(scrollYProgress, range, [38 isLeft ? '100%' : isRight ? '-100%' : '0%',39 isLeft ? '100%' : isRight ? '-100%' : '0%',40 '0%', '0%', '0%', '0%'41 ]);42 const rotate = useTransform(scrollYProgress, range, [isLeft ? -20 : isRight ? 20 : 0, isLeft ? -20 : isRight ? 20 : 0, 0, 0, 0, 0]);43 const shadowY = useTransform(scrollYProgress, range, [50, 50, 25, 25, -50, -50]);4445 return (46 <motion.div47 style={{48 scale,49 x: xTransform,50 rotate,51 zIndex: !isLeft && !isRight ? 1 : 0,52 boxShadow: useTransform(shadowY, (value) => `0px ${value}px 40px 10px rgba(0, 0, 0, 0.1)`)53 }}54 className="w-full sm:max-w-48 md:max-w-60 h-32 sm:h-60 md:h-72 overflow-hidden rounded-2xl"55 >56 <Image src={image} alt={image} width={1000} height={1000} className="h-full w-full object-cover" />57// … truncated
What it pulls in
npm packages
Files it writes
More from obsidianui
All 111 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| ai-inputai-input | obsidianui | Components | Free | 2 deps | |
| alertalert | obsidianui | Components | Free | no deps | |
| animated-tab-baranimated-tab-bar | obsidianui | Components | Free | no deps | |
| apple-spotlightapple-spotlight | obsidianui | Components | Free | 2 deps | |
| avataravatar | obsidianui | Components | Free | 1 dep | |
| badgebadge | obsidianui | Components | Free | 1 dep | |
| breadcrumbbreadcrumb | obsidianui | Components | Free | 2 deps | |
| buttonbutton | obsidianui | Components | Free | 1 dep |
