Skip to content

Instantly share code, notes, and snippets.

@homanp
Last active January 5, 2026 20:39
Show Gist options
  • Select an option

  • Save homanp/a56ebddbd9321715d87480a3a71a9c8b to your computer and use it in GitHub Desktop.

Select an option

Save homanp/a56ebddbd9321715d87480a3a71a9c8b to your computer and use it in GitHub Desktop.

Revisions

  1. homanp revised this gist Jan 5, 2026. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion framer-motion.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    ## name: framer-motion-demo
    ## name: framer-motion
    description: Create polished, cinematic product demo animations using Framer Motion. Use this skill when building animated product showcases, feature reveal sequences, UI walkthroughs, marketing videos, or any React-based demo that needs professional motion design. Covers orchestration, scroll-triggered reveals, gesture animations, layout transitions, and cinematic timing patterns.

    # Framer Motion for Product Demos
  2. homanp revised this gist Jan 5, 2026. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions framer-motion.md
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,3 @@
    -----

    ## name: framer-motion-demo
    description: Create polished, cinematic product demo animations using Framer Motion. Use this skill when building animated product showcases, feature reveal sequences, UI walkthroughs, marketing videos, or any React-based demo that needs professional motion design. Covers orchestration, scroll-triggered reveals, gesture animations, layout transitions, and cinematic timing patterns.

  3. homanp created this gist Jan 5, 2026.
    252 changes: 252 additions & 0 deletions framer-motion.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,252 @@
    -----

    ## name: framer-motion-demo
    description: Create polished, cinematic product demo animations using Framer Motion. Use this skill when building animated product showcases, feature reveal sequences, UI walkthroughs, marketing videos, or any React-based demo that needs professional motion design. Covers orchestration, scroll-triggered reveals, gesture animations, layout transitions, and cinematic timing patterns.

    # Framer Motion for Product Demos

    Create cinematic, professional product demo animations that showcase features with impact.

    ## Core Setup

    ```tsx
    import { motion, AnimatePresence, useScroll, useTransform } from "motion/react"
    ```

    ## Cinematic Timing Presets

    Use these easing curves for professional feel:

    ```tsx
    const easing = {
    smooth: [0.4, 0, 0.2, 1], // General UI
    snappy: [0.4, 0, 0, 1], // Quick interactions
    dramatic: [0.16, 1, 0.3, 1], // Hero reveals
    elastic: [0.68, -0.6, 0.32, 1.6] // Playful bounce
    }
    ```

    ## Demo Animation Patterns

    ### 1. Staggered Feature Reveal

    ```tsx
    const container = {
    hidden: { opacity: 0 },
    show: {
    opacity: 1,
    transition: { staggerChildren: 0.15, delayChildren: 0.3 }
    }
    }

    const item = {
    hidden: { opacity: 0, y: 40 },
    show: { opacity: 1, y: 0, transition: { duration: 0.6, ease: easing.dramatic } }
    }

    <motion.div variants={container} initial="hidden" animate="show">
    {features.map(f => <motion.div key={f.id} variants={item}>{f.content}</motion.div>)}
    </motion.div>
    ```

    ### 2. Hero Product Entrance

    ```tsx
    <motion.div
    initial={{ scale: 0.8, opacity: 0, y: 60 }}
    animate={{ scale: 1, opacity: 1, y: 0 }}
    transition={{ duration: 1.2, ease: easing.dramatic }}
    />
    ```

    ### 3. Scroll-Triggered Sections

    ```tsx
    function ScrollReveal({ children }) {
    return (
    <motion.div
    initial={{ opacity: 0, y: 80 }}
    whileInView={{ opacity: 1, y: 0 }}
    viewport={{ once: true, margin: "-100px" }}
    transition={{ duration: 0.8, ease: easing.smooth }}
    >
    {children}
    </motion.div>
    )
    }
    ```

    ### 4. Sequenced Demo Flow

    For timed demo sequences (auto-playing walkthroughs):

    ```tsx
    function DemoSequence() {
    const [step, setStep] = useState(0)

    useEffect(() => {
    const timings = [2000, 3000, 2500, 4000] // ms per step
    const timer = setTimeout(() => {
    setStep(s => (s + 1) % timings.length)
    }, timings[step])
    return () => clearTimeout(timer)
    }, [step])

    return (
    <AnimatePresence mode="wait">
    <motion.div
    key={step}
    initial={{ opacity: 0, x: 40 }}
    animate={{ opacity: 1, x: 0 }}
    exit={{ opacity: 0, x: -40 }}
    transition={{ duration: 0.5 }}
    >
    {steps[step]}
    </motion.div>
    </AnimatePresence>
    )
    }
    ```

    ### 5. UI Interaction Highlights

    Simulate clicks, hovers, typing for demos:

    ```tsx
    // Animated cursor
    <motion.div
    className="cursor"
    animate={{ x: [0, 200, 200], y: [0, 0, 150] }}
    transition={{ duration: 2, times: [0, 0.4, 1], ease: "easeInOut" }}
    />

    // Simulated typing
    function TypeWriter({ text, delay = 0 }) {
    const [displayed, setDisplayed] = useState("")
    useEffect(() => {
    const timeout = setTimeout(() => {
    let i = 0
    const interval = setInterval(() => {
    setDisplayed(text.slice(0, i + 1))
    i++
    if (i >= text.length) clearInterval(interval)
    }, 50)
    }, delay)
    return () => clearTimeout(timeout)
    }, [text, delay])
    return <span>{displayed}<motion.span animate={{ opacity: [1, 0] }} transition={{ repeat: Infinity, duration: 0.8 }}>|</motion.span></span>
    }
    ```

    ### 6. Layout Transitions

    Smooth morphing between states:

    ```tsx
    <motion.div layout layoutId="feature-card" transition={{ type: "spring", stiffness: 300, damping: 30 }}>
    {expanded ? <ExpandedView /> : <CompactView />}
    </motion.div>
    ```

    ### 7. Parallax Depth

    ```tsx
    function ParallaxLayer({ speed = 0.5, children }) {
    const { scrollY } = useScroll()
    const y = useTransform(scrollY, [0, 1000], [0, 1000 * speed])
    return <motion.div style={{ y }}>{children}</motion.div>
    }
    ```

    ## Demo-Specific Techniques

    ### Attention Pulse

    Draw attention to features:

    ```tsx
    <motion.div
    animate={{ scale: [1, 1.05, 1], boxShadow: ["0 0 0 0 rgba(59,130,246,0)", "0 0 0 8px rgba(59,130,246,0.3)", "0 0 0 0 rgba(59,130,246,0)"] }}
    transition={{ duration: 2, repeat: Infinity }}
    />
    ```

    ### Before/After Slider

    ```tsx
    function BeforeAfter({ before, after }) {
    const [split, setSplit] = useState(50)
    return (
    <div className="relative overflow-hidden" onMouseMove={e => setSplit((e.nativeEvent.offsetX / e.currentTarget.offsetWidth) * 100)}>
    <div className="absolute inset-0">{before}</div>
    <motion.div className="absolute inset-0" style={{ clipPath: `inset(0 0 0 ${split}%)` }}>{after}</motion.div>
    </div>
    )
    }
    ```

    ### Number Counter

    ```tsx
    function Counter({ from = 0, to, duration = 2 }) {
    const [value, setValue] = useState(from)
    useEffect(() => {
    const start = Date.now()
    const tick = () => {
    const progress = Math.min((Date.now() - start) / (duration * 1000), 1)
    setValue(Math.floor(from + (to - from) * progress))
    if (progress < 1) requestAnimationFrame(tick)
    }
    tick()
    }, [from, to, duration])
    return <motion.span>{value.toLocaleString()}</motion.span>
    }
    ```

    ## Performance Guidelines

    1. Use `will-change: transform` sparingly on animated elements
    1. Prefer `transform` and `opacity` over layout-triggering properties
    1. Use `layoutId` for shared element transitions instead of manual calculations
    1. Set `viewport={{ once: true }}` for scroll animations that don’t need to repeat
    1. Use `AnimatePresence` with `mode="wait"` for clean exit/enter sequences

    ## Demo Structure Template

    ```tsx
    export default function ProductDemo() {
    return (
    <>
    {/* Hero with dramatic entrance */}
    <section><HeroReveal /></section>

    {/* Scroll-triggered feature sections */}
    {features.map(f => (
    <ScrollReveal key={f.id}><FeatureSection {...f} /></ScrollReveal>
    ))}

    {/* Interactive demo sequence */}
    <section><DemoSequence steps={demoSteps} /></section>

    {/* Stats with counters */}
    <section><StatsSection /></section>

    {/* Final CTA with attention animation */}
    <section><CTAWithPulse /></section>
    </>
    )
    }
    ```

    ## Quick Reference

    |Effect |Key Props |
    |---------|--------------------------------------------------------|
    |Fade in |`initial={{ opacity: 0 }} animate={{ opacity: 1 }}` |
    |Slide up |`initial={{ y: 40 }} animate={{ y: 0 }}` |
    |Scale |`initial={{ scale: 0.9 }} animate={{ scale: 1 }}` |
    |Stagger |Parent: `staggerChildren: 0.1` |
    |On scroll|`whileInView={{ opacity: 1 }} viewport={{ once: true }}`|
    |On hover |`whileHover={{ scale: 1.05 }}` |
    |Spring |`transition={{ type: "spring", stiffness: 300 }}` |
    |Sequence |`transition={{ delay: 0.5 }}` or keyframe arrays |