motion-specs
استانداردسازی مشخصات انیمیشن برای تحویل دقیق از طراحی به توسعه
این Skill برای مستندسازی انیمیشنهای رابط کاربری، ساخت motion style guide و تولید مستندات قابلاستفاده برای توسعهدهندگان طراحی شده است. مشخصات شامل trigger، property، duration، easing، state و رفتارهای دسترسپذیری است.
خروجی را میتوان بهصورت JSON یا YAML ساخت و به CSS، TypeScript و Figma Variables تبدیل کرد. پشتیبانی از token reference، تنظیمات اختصاصی Web، iOS و Android و گزینههای reduced motion، هماهنگی بین تیم طراحی و توسعه را سادهتر میکند.
چه چیزی میگیرید
- ساخت Motion Specification برای انیمیشنهای منفرد و componentها
- تعریف state، transition، trigger، keyframe، duration و easing
- ثبت reduced motion، محدودیتهای vestibular و نیازهای screen reader
- تنظیم platform override برای Web، iOS، Android و video
- خروجی قابلاستفاده برای JSON، YAML، CSS، TypeScript و Figma Variables
برای چه کاری خوب است
- تیمهای طراحی و توسعهای که به handoff استاندارد برای انیمیشن نیاز دارند
- ساخت motion style guide برای یک design system
- مستندسازی transitionهای componentهایی مانند Modal، Button و Dialog
- پروژههایی که دسترسپذیری و پیادهسازی چندسکویی اهمیت دارد
برای چه کاری نیست
- ساخت مستقیم فایل انیمیشن یا اجرای کد در مرورگر
- پروژههایی که فقط به یک نمونه بصری بدون مستندات فنی نیاز دارند
- تولید انیمیشنهای پیچیده سینمایی یا تدوین ویدیو
دربارهٔ این اسکیل
Motion Specifications
Standardized format for animation handoff from design to development.
Specification Format
Single Animation Spec
{
"$schema": "motion-spec/1.0",
"name": "button-press",
"description": "Tactile feedback for button tap",
"trigger": "pointerdown",
"animation": {
"property": "transform",
"from": "scale(1)",
"to": "scale(0.95)",
"duration": "100ms",
"easing": "ease-out",
"token": "{motion.duration.short-2}"
},
"reducedMotion": {
"alternative": "opacity",
"from": 1,
"to": 0.8,
"duration": "50ms"
},
"platform": {
"web": {
"css": "transform 100ms ease-out",
"willChange": "transform"
},
"ios": {
"api": "UIView.animate",
"duration": 0.1,
"curve": ".curveEaseOut"
},
"android": {
"api": "ViewPropertyAnimator",
"duration": 100,
"interpolator": "FastOutSlowInInterpolator"
}
}
}
Component Animation Spec
{
"component": "Modal",
"version": "1.0",
"states": {
"closed": {
"opacity": 0,
"scale": 0.95,
"y": 16
},
"open": {
"opacity": 1,
"scale": 1,
"y": 0
}
},
"transitions": {
"closed-to-open": {
"duration": "250ms",
"easing": "emphasized-decelerate",
"properties": ["opacity", "scale", "y"],
"stagger": null
},
"open-to-closed": {
"duration": "200ms",
"easing": "emphasized-accelerate",
"properties": ["opacity", "scale"],
"stagger": null
}
},
"backdrop": {
"opacity": { "from": 0, "to": 0.5 },
"blur": { "from": 0, "to": 4 },
"duration": "250ms"
}
}
Specification Sections
1. Metadata
name: animation-name
version: 1.0.0
author: designer@company.com
created: 2024-01-15
updated: 2024-01-20
status: approved # draft | review | approved | deprecated
2. Trigger Definition
| Trigger Type | Description | Example |
|---|---|---|
click | Mouse/touch tap | Button press |
hover | Pointer enter | Card lift |
focus | Keyboard focus | Input ring |
scroll | Scroll position | Parallax |
load | Page/component load | Entrance |
state | State change | Toggle |
gesture | Swipe/drag | Dismiss |
3. Animation Properties
{
"animations": [
{
"target": ".element",
"property": "transform",
"keyframes": [
{ "offset": 0, "value": "translateY(20px)" },
{ "offset": 1, "value": "translateY(0)" }
],
"duration": 300,
"delay": 0,
"easing": [0.05, 0.7, 0.1, 1],
"fill": "forwards"
}
]
}
4. Accessibility
{
"accessibility": {
"reducedMotion": {
"behavior": "simplify", // simplify | remove | instant
"alternative": {
"duration": 0,
"properties": ["opacity"]
}
},
"vestibular": {
"maxDistance": 100,
"avoidParallax": true
},
"screenReader": {
"announce": "Dialog opened",
"role": "dialog"
}
}
}
5. Platform Overrides
{
"platforms": {
"web": {
"implementation": "css",
"fallback": "js"
},
"ios": {
"implementation": "UIViewPropertyAnimator",
"haptic": "impact-light"
},
"android": {
"implementation": "ObjectAnimator",
"haptic": "VIRTUAL_KEY"
},
"video": {
"duration": "multiply(0.6)",
"maxDuration": 400
}
}
}
Handoff Checklist
Designer Deliverables
- ☐ Animation spec JSON/YAML
- ☐ Style frames (PNG/Figma)
- ☐ Timing diagram
- ☐ Easing curve visualization
- ☐ Reduced motion alternative
- ☐ Interaction prototype
Developer Checklist
- ☐ Token references resolved
- ☐ Platform implementation chosen
- ☐ Accessibility tested
- ☐ Performance benchmarked
- ☐ Reduced motion verified
Token Resolution
From Spec to Code
// Spec uses token reference
{
"duration": "{motion.duration.medium-1}",
"easing": "{motion.easing.emphasized-decelerate}"
}
// Resolved values
{
"duration": "250ms",
"easing": [0.05, 0.7, 0.1, 1]
}
Resolution Function
function resolveTokens(spec, tokens) {
return JSON.parse(
JSON.stringify(spec).replace(
/\{([^}]+)\}/g,
(match, path) => {
const value = path.split('.').reduce(
(obj, key) => obj?.[key],
tokens
);
return value?.$value ?? match;
}
)
);
}
Export Formats
CSS Variables
:root {
--motion-button-press-duration: 100ms;
--motion-button-press-easing: ease-out;
--motion-modal-enter-duration: 250ms;
--motion-modal-enter-easing: cubic-bezier(0.05, 0.7, 0.1, 1);
}
.button:active {
transition: transform var(--motion-button-press-duration)
var(--motion-button-press-easing);
}
TypeScript Constants
export const MOTION_SPECS = {
buttonPress: {
duration: 100,
easing: 'ease-out',
transform: { scale: 0.95 }
},
modalEnter: {
duration: 250,
easing: [0.05, 0.7, 0.1, 1],
from: { opacity: 0, scale: 0.95, y: 16 },
to: { opacity: 1, scale: 1, y: 0 }
}
} as const;
Figma Variables
{
"motion/duration/button-press": {
"type": "FLOAT",
"value": 100,
"description": "Button press feedback duration (ms)"
},
"motion/easing/emphasized-decelerate": {
"type": "STRING",
"value": "cubic-bezier(0.05, 0.7, 0.1, 1)",
"description": "M3 entrance easing"
}
}
Validation Schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["name", "animation"],
"properties": {
"name": { "type": "string" },
"animation": {
"type": "object",
"required": ["property", "duration"],
"properties": {
"property": { "type": "string" },
"duration": {
"oneOf": [
{ "type": "string", "pattern": "^\\d+ms$" },
{ "type": "string", "pattern": "^\\{.*\\}$" }
]
}
}
}
}
}
Related Skills
- Dependencies: easing, duration, tokens
- See also: storyboarding, code-generation, export
- Output formats: JSON, YAML, CSS, TypeScript