Orchestration
Staggering Children
Example of how to use frame motion Orchestration.
StaggeredList
animated-svg.tsx
import StaggeredList from "@/components/animations/staggered-list"; import React from 'react' const Orchestration = () => { return ( <div className="p-5"> <StaggeredList containerVariants={{transition:{staggerChildren:0.5}}} itemVariants={{hidden:{opacity:0, y:-60}, visible:{opacity:1, y:0}}} items={[ { item: <div> <div className="w-60 h-20 rounded-xl from-orange-500 to-yellow-500 bg-gradient-to-t" /> </div> }, { item: <div> <div className="w-60 h-20 rounded-xl from-purple-500 to-pink-500 bg-gradient-to-t" /> </div> }, { item: <div> <div className="w-60 h-20 rounded-xl from-emerald-500 to-lime-500 bg-gradient-to-t" /> </div> }, { item: <div> <div className="w-60 h-20 rounded-xl from-cyan-500 to-blue-500 bg-gradient-to-t" /> </div> } ]} refresh /> </div> ) } export default Orchestration "use client" import React, { useState } from 'react'; import { Preview } from '../common/display'; import { motion } from "framer-motion"; interface StaggeredListProps { containerVariants: containerProps; itemVariants: itemProps; items: childs[]; refresh: boolean; className?:string; } interface transitionProps { staggerChildren: number; } interface containerProps { transition: transitionProps; } interface childs { item: React.ReactNode; } interface variants { opacity: number; y: number; } interface itemProps { hidden: variants; visible: variants; } const StaggeredList = ({ containerVariants, itemVariants, refresh, items ,className }: StaggeredListProps) => { const [count, setCount] = useState(0); return ( <Preview SetCount={setCount} isRefreshing={refresh} animeName='StaggeredList'> <motion.ul key={count} variants={containerVariants} initial="hidden" animate="visible" className={className}> {items.map((data, key) => ( <motion.li key={key} variants={itemVariants}>{data.item}</motion.li> ))} </motion.ul> </Preview> ) } export default StaggeredList interface PreviewerProps { children: React.ReactNode; SetCount: (count: number) => void; isRefreshing: boolean; animeName:string hideIcon?: boolean; } export const Preview = ({ children, SetCount, isRefreshing, animeName, hideIcon=false }: PreviewerProps) => { const [count, setCount] = useState(0); const [isLoading, setIsLoading] = useState(false); const handleClick = () => { setIsLoading(true); setCount(count + 1); SetCount(count + 1); setTimeout(() => { setIsLoading(false); }, 400); // Timeout duration matches the animation duration }; return ( <div className="w-full h-full flex flex-col"> <div className="w-full flex-1 flex justify-center items-center"> {children} </div> {isRefreshing && <div className="h-[50px] w-full px-6 rounded-b-[24px] flex justify-between"> <span>{animeName}</span>{!hideIcon && <RotateCw onClick={handleClick} className={isLoading ? 'animate-spin duration-200' : 'animate-none'} />} </div> } </div> ) };