Extension Icon

Motion Rosetta

Translate easing curves and springs with explicit conversion fidelity.
Overview

Motion Rosetta

Explore how an easing moves on interface components, then convert it to code with an explicit statement of what each output preserves, approximates, or loses.

How it works

  1. Open Convert Easing and paste an easing into the search bar, or choose a preset.
  2. Watch it on Sheet, Toggle, Tooltip, or Staggered List using the Preview tags, then scroll the detail to inspect the response curve and code.
  3. Select Duration → Edit to enter whole milliseconds in the same search bar. Apply to confirm or use Cancel Duration Edit to discard.
  4. Select an output format and press Return to copy it, or use Actions to copy another. View Full Conversion shows the complete code, fidelity notes, target crossings, and timing details.

A theme-matched component poster stays visible while the animation loads, and the last preview component is remembered.

Features

  • Generated component previews: previews are generated from your input and its duration, including custom values, rather than predefined animations.
  • Duration and fidelity together: applying a new duration updates every conversion and recalculates its fidelity.
  • Explicit conversion limits: every output is labeled Exact, Sampled, Lossy, or Unavailable and explains what it preserves, approximates, or loses.
  • Multiformat input and output: detects pasted CSS, Figma, Motion, SwiftUI, Jetpack Compose, Tailwind, and DTCG easing values and springs, and converts them to the same platforms.
  • Presets as starting points: five CSS keywords, Motion Back In / Back Out, and six authored Rosetta physical springs. These are not claimed as Figma presets; see sources and asset provenance.
  • Input stays data: pasted input is parsed and never executed. Invalid input disables copying instead of copying a previous result, and the previous valid curve is labeled as such.

Supported inputs

InputExample
CSS keywordease-in-out
Figma / bare Bézier0.42, 0, 0.58, 1
CSS cubic Béziercubic-bezier(0.42, 0, 0.58, 1)
Four-number array[0.42, 0, 0.58, 1]
CSS piecewise linearlinear(0, 0.35 20%, 1.15 55%, 1)
Motion physics spring{ type: "spring", stiffness: 100, damping: 10, mass: 1 }
Motion time spring{ type: "spring", visualDuration: 0.5, bounce: 0.6 }
SwiftUI spring.spring(duration: 0.5, bounce: 0.6)
CSS stepssteps(4, jump-end)

Also accepted: .timingCurve(...), physical .interpolatingSpring(...), Compose CubicBezierEasing(...), Bézier tween(...) and spring<Float>(...), Motion { ease: [...] }, CSS transition declarations, Tailwind easing classes, and DTCG cubicBezier tokens. Linear and steps snippets generated by Motion Rosetta can be pasted back unchanged; modified functions and arbitrary application code are not input formats.

Outputs and fidelity

Outputs include Figma, CSS cubic-bezier, CSS linear(), Motion, SwiftUI, Jetpack Compose, Tailwind, and DTCG 2025.10.

  • Exact preserves the mathematical curve or physical response, subject to decimal precision and platform runtime thresholds.
  • Sampled is a finite approximation. Notes report sampling and measured interpolation error, not a proven global error bound.
  • Lossy identifies discarded information.
  • Unavailable means no supported faithful representation is emitted; copying is disabled.

FAQ

Why is CSS cubic-bezier Unavailable for some springs?

Springs are never automatically fitted to cubic Bézier. A spring that crosses its target two or more times cannot be a single cubic-bezier, so none is emitted. Use the sampled CSS linear() output instead, which discloses its timing and tail truncation.

Will the preview match iOS, Android, or the browser exactly?

Previews demonstrate the response, not each platform's animation engine. Exact outputs keep the same curve or physical response, but completion behavior may differ between platforms.

What does duration mean for a spring?

The editor changes the Apple duration parameter, the undamped period, not settling time. It preserves mass, damping ratio, and initial velocity, and the metadata reports the distinct settling window. Curves without timing default to 0.5 seconds, labeled assumed, and a new pasted input does not inherit the previous edit.

Why are some Figma, Compose, or DTCG outputs Lossy?

Figma Motion exports bounce only and loses natural frequency, while Figma Prototype preserves physical spring parameters. Compose has no mass, so stiffness is normalized to k/m; a nonzero initial velocity must be supplied separately to its animation API, so that output is Lossy. DTCG 2025.10 has no spring token, so a spring can export only its undamped period as a duration.

What does the SwiftUI output for linear and steps curves require?

It uses CustomAnimation (iOS 17+ / macOS 14+). Nonstandard endpoints are marked lossy because SwiftUI finishes at its target.

Does Motion Rosetta run the code I paste?

No. Pasted input is parsed as data and never executed, and invalid input disables copying.

Keyboard shortcuts

Open Actions → Open Shortcut Preferences to edit bindings in native extension preferences. Use text such as cmd+shift+3; none disables a binding and blank fields use the default. Reopen the command after changes. Invalid or duplicate bindings show an error and fall back to the defaults.

Defaults include Ctrl+1–4 for components and ⌘↵ to confirm input. The Actions menu shows each format's binding. Bindings follow the output identity, not list position. The launcher hotkey is configured separately by Raycast. Escape remains Raycast navigation; use the explicit cancel action when editing duration.

Privacy and local storage

No API keys, Keychain access, networking, or external analytics are used by the command. Pasted input is parsed locally as data.

Previews are encoded locally with pure JavaScript and cached in the extension's support directory, up to 200 files or 20 MiB, whichever comes first; the least recently used previews are removed first. If a preview can't be generated or stored, the static poster stays visible with an explanation. If previews keep reporting that the cache is busy, restarting Raycast clears it.

More details

Input limits, Apple spring formulas, and platform-specific conversion notes are in Conversion notes.

References

MIT license.