motion-sv

Documentation and patterns for using motion-sv, a Svelte 5 port of Motion (Framer Motion). Use this when the user wants animations, gestures, or transitions in Svelte.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "motion-sv" with this command: npx skills add sikandarjodd/animations/sikandarjodd-animations-motion-sv

Motion for Svelte (motion-sv)

A port of the Motion library (formerly Framer Motion) specifically for Svelte 5. It aligns closely with the motion-v API structure rather than the React version.

Stack Requirements

  • MUST be used with Svelte 5 (Runes).
  • Package name: motion-sv.

Core Components

motion

The primary component factory. Use dot notation to render any HTML element.

<script>
  import { motion } from "motion-sv";
</script>

<!-- Sections & Headings -->
<motion.section initial={{ opacity: 0 }} animate={{ opacity: 1 }}>
  <motion.h1 animate={{ y: 0 }}>Headline</motion.h1>
</motion.section>

<!-- Links & Buttons -->
<motion.a
  href="/about"
  whileHover={{ scale: 1.05 }}
  whilePress={{ scale: 0.95 }}
>
  Go to About
</motion.a>

Styling Pattern (Important)

ALWAYS pass styles as an object via style={{ key: value }}, never as a string. This is required to bind MotionValues correctly without triggering re-renders.

<script>
  import { motion, useMotionValue } from "motion-sv";
  const x = useMotionValue(0);
</script>

<!-- ❌ BAD: String syntax (Values won't update) -->
<motion.div style="background-color: red; transform: translateX(10px)" />

<!-- ✅ GOOD: Object syntax -->
<motion.div
  style={{
    x,
    backgroundColor: "#ff0000",
    "--custom-var": 100,
  }}
/>

Type Safety & Variants

For better developer experience and type safety, define variants using the Variants type.

<script lang="ts">
  import { motion, type Variants } from "motion-sv";

  const boxVariants: Variants = {
    hidden: { opacity: 0, scale: 0.8 },
    visible: {
      opacity: 1,
      scale: 1,
      transition: { duration: 0.5 },
    },
  };
</script>

<motion.div variants={boxVariants} initial="hidden" animate="visible" />

Supported Props

  • Animation: initial, animate, exit, transition, variants.
  • Gestures: whileHover, whilePress (preferred over whileTap), whileDrag, whileFocus.
  • Drag: drag (boolean | "x" | "y"), dragConstraints, dragElastic, dragMomentum.
  • Events: onAnimationStart, onAnimationComplete, onUpdate.
  • Gesture Events: onHoverStart, onHoverEnd, onPress, onPressStart, onPressEnd.

Viewport / Scroll Animations (Vue API Style)

Important: Use inViewOptions instead of the React viewport prop.

<motion.section
  initial={{ opacity: 0 }}
  whileInView={{ opacity: 1 }}
  inViewOptions={{
    once: true,
    amount: "some", // "some" | "all" | 0..1
    margin: "0px 0px -200px 0px",
  }}
>
  Hello
</motion.section>

AnimatePresence

Enables exit animations. Modes: "sync" (default), "wait", "popLayout".

<script>
  import { motion, AnimatePresence } from "motion-sv";
  let show = $state(true);
</script>

<AnimatePresence mode="wait">
  {#if show}
    <motion.div
      initial={{ opacity: 0 }}
      animate={{ opacity: 1 }}
      exit={{ opacity: 0 }}
      key="unique-key"
    />
  {/if}
</AnimatePresence>

Layout Animations (CRITICAL DIFFERENCE)

Svelte lacks getSnapshotBeforeUpdate. You MUST use createLayoutMotion for layout animations.

Pattern:

  1. Create a proxy object: const layout = createLayoutMotion(motion).
  2. Use <layout.div> instead of <motion.div>.
  3. Wrap state updates with layout.update.with(fn).
<script>
  import { motion, createLayoutMotion } from "motion-sv";

  let isOn = $state(false);
  const layout = createLayoutMotion(motion);

  // Wrap state mutation
  const toggle = layout.update.with(() => (isOn = !isOn));
</script>

<div onclick={toggle}>
  <!-- Use layout.div and layoutDependency or layoutId -->
  <layout.div
    layoutDependency={isOn}
    transition={{ type: "spring", stiffness: 700, damping: 30 }}
  />
</div>

Reorder (Drag & Drop Lists)

Use specific components for reordering lists.

<script>
  import { ReorderGroup, ReorderItem } from "motion-sv";
  let items = $state([0, 1, 2]);
</script>

<ReorderGroup axis="y" bind:values={items}>
  {#each items as item (item)}
    <ReorderItem value={item}>
      {item}
    </ReorderItem>
  {/each}
</ReorderGroup>

Performance (Lazy Motion)

Reduce bundle size by loading features on demand.

<script>
  import { LazyMotion, domAnimation } from "motion-sv";
</script>

<LazyMotion features={domAnimation}>
  <!-- Children using motion components -->
</LazyMotion>

Best Practices

  • API Alignment: Follow motion-v prop naming (e.g., inViewOptions, whilePress).
  • Directives: Do NOT use Svelte's transition:fn.
  • Styles: Always use the object syntax style={{ ... }}.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

ll-feishu-audio

飞书语音交互技能。支持语音消息自动识别、AI 处理、语音回复全流程。需要配置 FEISHU_APP_ID 和 FEISHU_APP_SECRET 环境变量。使用 faster-whisper 进行语音识别,Edge TTS 进行语音合成,自动转换 OPUS 格式并通过飞书发送。适用于飞书平台的语音对话场景。

Archived SourceRecently Updated
General

test_skill

import json import tkinter as tk from tkinter import messagebox, simpledialog

Archived SourceRecently Updated
General

51mee-resume-profile

简历画像。触发场景:用户要求生成候选人画像;用户想了解候选人的多维度标签和能力评估。

Archived SourceRecently Updated
General

51mee-resume-parse

简历解析。触发场景:用户上传简历文件要求解析、提取结构化信息。

Archived SourceRecently Updated