开发编程
#react
motion-foundations
Motion tokens, spring presets, performance rules, device adaptation, accessibility enforcement, and SSR safety for React / Next.js using motion/react. Foundation layer — all other motion skills depend on this. Use when setting up motion tokens, spring presets, reduced-motion handling, or SSR-safe animation in React or Next.js.
DeepseekModel
官方收录技能
质量 优秀 · 90
v1.0.0
获取
https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-skills-motion-foundations-skill-md&format=skill
下载 .skill
标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用
.skill 文件中 system_prompt 字段的实际内容。
name motion-foundations description Motion tokens, spring presets, performance rules, device adaptation, accessibility enforcement, and SSR safety for React / Next.js using motion/react. Foundation layer — all other motion skills depend on this. Use when setting up motion tokens, spring presets, reduced-motion handling, or SSR-safe animation in React or Next.js. tags ["motion","animation","performance","accessibility"] category frontend author jeff metadata {"version":"1.0.0"} Motion Foundations The base layer of the motion system. Defines every value, constraint, and rule that downstream skills ( motion-patterns , motion-advanced ) inherit. Load this skill before any animation work begins. When to Activate Starting any animated component from scratch Setting up tokens, spring presets, or easing values Implementing prefers-reduced-motion support Debugging hydration mismatches from animation initial states Evaluating whether an animation should exist at all Outputs This skill produces: A shared motionTokens object (duration, easing, distance, scale) A shared springs preset map (5 named configs) A shouldAnimate() gate used by all components Accessibility-compliant animation defaults via useReducedMotion SSR-safe initial states with zero hydration warnings Principles Motion must do at least one of the following or it must be removed: Guide attention Communicate state Preserve spatial continuity Responsiveness always outranks smoothness. A 60 fps animation that causes input delay is worse than no animation. Rules These are non-negotiable. They apply to every component in the system. Use motion/react only. Never import from framer-motion . Never mix the two in the same tree. initial must match server output. If the server renders opacity: 1 , the initial prop must also be opacity: 1 . No exceptions. Reduced motion overrides everything. When useReducedMotion() returns true or prefersReduced is true , all transforms are disabled. Opacity-only fades at ≤ 0.2s are the only permitted fallback. Never animate layout properties. width , height , top , left , margin , padding are banned from animate . Use transform and opacity only. All token values come from motionTokens . Hardcoded durations and easings in component files are forbidden. All spring configs come from the springs map. Inline stiffness / damping values are forbidden. "use client" is required on every file that imports from motion/react . Never read window or navigator at module level. Always guard with typeof window !== "undefined" . Decision Guidance Choosing a duration Token Use when instant Tooltip show/hide, focus ring, badge update fast Button feedback, icon swap, chip toggle normal Modal open, card expand, page element enter slow Hero entrance, full-page transition crawl Deliberate storytelling; use sparingly Choosing a spring Preset Use when snappy Default UI — buttons, chips, nav items gentle Cards, modals, panels landing softly bouncy Playful moments — empty states, onboarding instant Tooltips, popovers, dropdowns release Drag release — natural physics feel When to disable animation entirely Disable (make shouldAnimate() return false ) when: prefersReduced is true isLowEnd is true and the animation is non-essential The element is off-screen and will never enter the viewport The animation is purely decorative with no UX purpose Core Concepts Token system // lib/motion-tokens.ts export const motionTokens = { duration : { instant : 0.08 , fast : 0.18 , normal : 0.35 , slow : 0.6 , crawl : 1.0 , }, easing : { smooth : [ 0.22 , 1 , 0.36 , 1 ], sharp : [ 0.4 , 0 , 0.2 , 1 ], bounce : [ 0.34 , 1.56 , 0.64 , 1 ], linear : [ 0 , 0 , 1 , 1 ], }, distance : { xs : 4 , sm : 8 , md : 16 , lg : 24 , xl : 48 , }, scale : { subtle : 0.98 , press : 0.95 , pop : 1.04 , }, } export const springs = { snappy : { type : "spring" , stiffness : 300 , damping : 30 }, gentle : { type : "spring" , stiffness : 120 , damping : 14 }, bouncy : { type : "spring" , stiffness : 400 , damping : 10 }, instant : { type : "spring" , stiffness : 600 , damping : 35 }, release : { type : "spring" , stiffness : 200 , damping : 20 , restDelta : 0.001 }, } Runtime flags // lib/motion-config.ts export const motionConfig = { isLowEnd ( ) { return ( typeof navigator !== "undefined" && navigator. hardwareConcurrency <= 4 ) }, prefersReduced ( ) { return ( typeof window !== "undefined" && window . matchMedia ( "(prefers-reduced-motion: reduce)" ). matches ) }, shouldAnimate ( { essential = false } = {} ) { if ( this . prefersReduced ()) return false if (!essential && this . isLowEnd ()) return false return true }, duration ( ) { return this . isLowEnd () || this . prefersReduced () ? motionTokens. duration . instant : motionTokens. duration . normal }, } Accessibility Priority order (highest to lowest): prefers-reduced-motion: reduce — disables all transforms, limits opacity transitions to ≤ 0.2s Low-end device detection — reduces duration, removes non-essential animations Design preference — everything else Motion must degrade gracefully. It must never disappear abruptly in a way that causes layout shift or confuses orientation. // hooks/use-reduced-motion.tsx "use client" import { useReducedMotion } from "motion/react" export function useSafeMotion ( fullY : number = 16 ) { const reduce = useReducedMotion () return { initial : { opacity : 0 , y : reduce ? 0 : fullY }, animate : { opacity : 1 , y : 0 }, exit : { opacity : 0 , y : reduce ? 0 : -fullY }, } } /* globals.css */ @media ( prefers-reduced-motion : reduce) { .motion-safe-transition { transition : opacity 0.15s ; } .motion-reduce-transform { transform : none !important ; } } <!-- Tailwind --> < div class = "motion-safe:animate-fade motion-reduce:opacity-100" > </ div > SSR / hydration safety Rule: initial must always match what the server renders. // WRONG — server renders opacity:1 but initial says 0 → hydration mismatch <motion. div initial={{ opacity : 0 }} animate={{ opacity : 1 }} /> // CORRECT — use AnimatePresence or defer to client mount "use client" const [mounted, setMounted] = useState ( false ) useEffect ( () => setMounted ( true ), []) <motion. div initial={{ opacity : mounted ? 0 : 1 }} animate={{ opacity : 1 }} /> Code Examples End-to-end: tokens + springs + accessibility + SSR guard // components/fade-in-card.tsx "use client" import { useState, useEffect } from "react" import { motion } from "motion/react" import { motionTokens, springs } from "@/lib/motion-tokens" import { useSafeMotion } from "@/hooks/use-reduced-motion" import { motionConfig } from "@/lib/motion-config" interface FadeInCardProps { children : React . ReactNode delay ?: number } export function FadeInCard ( { children, delay = 0 }: FadeInCardProps ) { // SSR guard — initial must match server output (opacity: 1) const [mounted, setMounted] = useState ( false ) useEffect ( () => setMounted ( true ), []) // Accessibility — disables transform when reduced motion is preferred const safeMotion = useSafeMotion (motionTokens. distance . md ) // Device gate — skip animation on low-end hardware if (!motionConfig. shouldAnimate () || !mounted) { return < div > {children} </ div > } return ( < motion.div initial = {safeMotion.initial} animate = {safeMotion.animate} exit = {safeMotion.exit} transition = {{ ...springs.gentle , delay , }} whileHover = {{ scale: motionTokens.scale.pop }} whileTap = {{ scale: motionTokens.scale.press }} > {children} </ motion.div > ) } Constraints / Non-Goals This skill does not cover: UI component patterns (button, modal, stagger) → see motion-patterns Drag, gestures, SVG, text animations, custom hooks → see motion-advanced CSS-only animations or Tailwind animate-* classes without motion/react Third-party animation libraries (GSAP, anime.js, etc.) Motion design decisions (when to animate, what to emphasize) — that is a design concern, not a code constraint Anti-Patterns Anti-pattern Rule violated Fix import { motion } from "framer-motion" Rule 1 Use motion/react initial={{ opacity: 0 }} on SSR component Rule 2 Add mount guard Skipping useReducedMotion check Rule 3 Use useSafeMotion hook animate={{ width: "100%" }} Rule 4 Use scaleX transform instead transition={{ duration: 0.4 }} inline Rule 5 Use motionTokens.duration.normal { stiffness: 300, damping: 30 } inline Rule 6 Use springs.snappy Missing "use client" directive Rule 7 Add to top of file navigator.hardwareConcurrency at module level Rule 8 Wrap in typeof navigator !== "undefined" Related Skills motion-patterns — consumes tokens and springs defined here to build button, modal, stagger, page transition, and scroll patterns. Does not redefine any values. motion-advanced — consumes tokens and springs defined here for drag, SVG, text, and gesture patterns. Adds useAnimate sequences and custom hooks on top of this foundation.
Agent 识别该技能的关键词,点击任意一个即可复制。
该技能未提供触发词。
下载的 .skill 包内含以下字段。
| 字段 | 说明 |
|---|---|
| format | 格式标识(skill/v1) |
| skill_id | 技能唯一 ID |
| name | 技能名称 |
| version | 版本号 |
| description | 技能描述 |
| category | 所属分类(数组) |
| trigger_words | 触发词列表 |
| tags | 标签列表 |
| source | 来源标识 |
| source_url | 来源链接(本页地址) |
| exported_at | 导出时间(每次下载生成) |
| system_prompt | 系统提示词正文 |
| model_config | 模型参数:provider / model / temperature / max_tokens / top_p |
| examples | 示例 |
| install_guide | 各平台导入说明(Coze / Dify / Claude / 自定义框架) |