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 TypeDescriptionExample
clickMouse/touch tapButton press
hoverPointer enterCard lift
focusKeyboard focusInput ring
scrollScroll positionParallax
loadPage/component loadEntrance
stateState changeToggle
gestureSwipe/dragDismiss

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

دانلود ZIP