Skip to main content

Motion

note

The Motion API is available in Beta. This API is subject to change.

These types describe Motion animation styles, keyframes, timelines, and easing values used by figma.motion and Motion node properties.

Available animation style

AvailableAnimationStyle is returned by figma.motion.figmaAnimationStyles(). Its props values are type/default descriptions for each configurable property.

interface AvailableAnimationStyle {
readonly styleId: string
readonly name: string
readonly description?: string
readonly props?: { readonly [key: string]: AvailableAnimationStylePropValue }
}

Available animation style prop value

type AvailableAnimationStylePropValue = string

Applied animation style

AppliedAnimationStyle is returned by node.animationStyles. Its duration and timelineOffset values are expressed in seconds. Its props values are the configured property values for that node.

interface AppliedAnimationStyle {
readonly id: string
readonly styleId: string
readonly name: string
readonly duration?: number
readonly timelineOffset?: number
readonly props?: { readonly [key: string]: AnimationStylePropValue }
}

Animation style prop value

type AnimationStylePropValue =
string | number | boolean | MotionEasing | VariableAlias

Animation style configuration

duration and timelineOffset values are expressed in seconds.

interface AnimationStyleConfiguration {
readonly duration?: number
readonly timelineOffset?: number
readonly props?: { readonly [key: string]: AnimationStylePropValue }
}

Motion easing

Timeline values are expressed in seconds. MotionEasing uses the same easing names as prototyping transitions, with the additional "HOLD" value for keyframes that hold their current value until the next keyframe. Custom spring easing uses a normalized bounce value from 0 to 1; use figma.motion.physicalSpringToNormalized() to convert physical spring parameters.

interface MotionEasing {
readonly type:
| 'EASE_IN'
| 'EASE_OUT'
| 'EASE_IN_AND_OUT'
| 'LINEAR'
| 'EASE_IN_BACK'
| 'EASE_OUT_BACK'
| 'EASE_IN_AND_OUT_BACK'
| 'CUSTOM_CUBIC_BEZIER'
| 'GENTLE'
| 'QUICK'
| 'BOUNCY'
| 'SLOW'
| 'CUSTOM_SPRING'
| 'HOLD'
readonly easingFunctionCubicBezier?: EasingFunctionBezier
readonly easingFunctionSpring?: NormalizedSpring
}

Normalized spring

bounce is a normalized value from 0 to 1.

interface NormalizedSpring {
readonly bounce: number
}

Physical spring

PhysicalSpring is passed to figma.motion.physicalSpringToNormalized() to convert physical spring parameters into Motion's normalized bounce value from 0 to 1.

interface PhysicalSpring {
readonly mass: number
readonly stiffness: number
readonly damping: number
}

Keyframe value

type KeyframeValue =
| { readonly type: 'FLOAT'; readonly value: number }
| { readonly type: 'COLOR'; readonly value: RGBA }
| { readonly type: 'TEXT_DATA'; readonly value: string }
| { readonly type: 'VECTOR'; readonly value: Vector }
| { readonly type: 'BOOL'; readonly value: boolean }
| { readonly type: 'CIRCLE'; readonly value: { readonly x: number; readonly y: number; readonly radius: number } }
| { readonly type: 'LINE'; readonly value: { readonly x: number; readonly y: number; readonly x2: number; readonly y2: number } }
| {
readonly type: 'CIRCLE_POINT'
readonly value: { readonly x: number; readonly y: number; readonly radius: number; readonly angle: number }
}
| { readonly type: 'COLOR_POINT'; readonly value: { readonly x: number; readonly y: number; readonly color: RGBA } }

Manual keyframe input

timelinePosition is expressed in seconds.

interface ManualKeyframeInput {
readonly id?: string
readonly timelinePosition: number
readonly easing?: MotionEasing | VariableAlias
readonly value: KeyframeValue
}

Manual keyframe track input

interface ManualKeyframeTrackInput {
readonly id?: string
readonly baseValue?: KeyframeValue
readonly keyframes: ReadonlyArray<ManualKeyframeInput>
}

Manual keyframe

interface ManualKeyframe extends ManualKeyframeInput {
readonly id: string
readonly easing: MotionEasing | VariableAlias
}

Manual keyframe binding

ManualKeyframeBinding is returned by node.manualKeyframeTracks. It includes the current base value for the field, plus the sorted manual keyframes applied to that field.

interface ManualKeyframeBinding {
readonly id: string
readonly baseValue: KeyframeValue
readonly keyframes: ReadonlyArray<ManualKeyframe>
}

Manual keyframe track

interface ManualKeyframeTrack {
readonly id: string
readonly keyframeOperation: 'SET' | 'OFFSET' | 'SCALE'
readonly keyframes: ReadonlyArray<ManualKeyframe>
}

Keyframe binding

interface KeyframeBinding {
readonly baseValue: KeyframeValue
readonly timelineDuration: number
readonly tracks: ReadonlyArray<ManualKeyframeTrack>
}

Keyframe property field name

type KeyframePropertyFieldName =
| 'CORNER_RADIUS'
| 'STROKE_WEIGHT'
| 'STACK_SPACING'
| 'STACK_PADDING_LEFT'
| 'STACK_PADDING_TOP'
| 'STACK_PADDING_RIGHT'
| 'STACK_PADDING_BOTTOM'
| 'WIDTH'
| 'HEIGHT'
| 'RECTANGLE_TOP_LEFT_CORNER_RADIUS'
| 'RECTANGLE_TOP_RIGHT_CORNER_RADIUS'
| 'RECTANGLE_BOTTOM_LEFT_CORNER_RADIUS'
| 'RECTANGLE_BOTTOM_RIGHT_CORNER_RADIUS'
| 'BORDER_TOP_WEIGHT'
| 'BORDER_BOTTOM_WEIGHT'
| 'BORDER_LEFT_WEIGHT'
| 'BORDER_RIGHT_WEIGHT'
| 'STACK_COUNTER_SPACING'
| 'OPACITY'
| 'GRID_ROW_GAP'
| 'GRID_COLUMN_GAP'
| 'TRANSLATION_X'
| 'TRANSLATION_Y'
| 'TRANSLATION_XY'
| 'ROTATION'
| 'SCALE_X'
| 'SCALE_Y'
| 'SCALE_XY'
| 'PATH_TRIM_START'
| 'PATH_TRIM_END'

Effect keyframe field name

type EffectKeyframeFieldName =
| 'OFFSET_X'
| 'OFFSET_Y'
| 'RADIUS'
| 'SPREAD'
| 'COLOR'
| 'REFRACTION_RADIUS'
| 'SPECULAR_ANGLE'
| 'SPECULAR_INTENSITY'
| 'CHROMATIC_ABERRATION'
| 'SPLAY'
| 'REFRACTION_INTENSITY'
| 'START_RADIUS'
| 'NOISE_SIZE_X'
| 'NOISE_SIZE_Y'
| 'DENSITY'
| 'EFFECT_OPACITY'
| 'SECONDARY_COLOR'

Keyframe field

type KeyframeField =
| { readonly type: 'PROPERTY'; readonly name: KeyframePropertyFieldName }
| {
readonly type: 'INDEXED_ITEM'
readonly collection: 'fills' | 'strokes'
readonly index: number
}
| {
readonly type: 'INDEXED_ITEM'
readonly collection: 'fills' | 'strokes'
readonly index: number
readonly propertyId: string
}
| {
readonly type: 'INDEXED_ITEM'
readonly collection: 'effects'
readonly index: number
readonly field: EffectKeyframeFieldName
}
| {
readonly type: 'INDEXED_ITEM'
readonly collection: 'effects'
readonly index: number
readonly propertyId: string
}

Component prop keyframe tracks

type ComponentPropKeyframeTracks = Partial<Record<string, ManualKeyframeBinding>>

Component prop keyframe bindings

type ComponentPropKeyframeBindings = Partial<Record<string, KeyframeBinding>>

Paint manual keyframe track

type PaintManualKeyframeTrack =
| ManualKeyframeBinding
| { readonly properties: ComponentPropKeyframeTracks }

Paint keyframe binding

type PaintKeyframeBinding =
| KeyframeBinding
| { readonly properties: ComponentPropKeyframeBindings }

Effect manual keyframe tracks

type EffectManualKeyframeTracks = Partial<
Record<EffectKeyframeFieldName, ManualKeyframeBinding>
> & {
readonly properties?: ComponentPropKeyframeTracks
}

Effect keyframe bindings

type EffectKeyframeBindings = Partial<
Record<EffectKeyframeFieldName, KeyframeBinding>
> & {
readonly properties?: ComponentPropKeyframeBindings
}

Manual keyframe tracks

type ManualKeyframeTracks = Partial<
Record<KeyframePropertyFieldName, ManualKeyframeBinding>
> & {
readonly fills?: Partial<Record<number, PaintManualKeyframeTrack>>
readonly strokes?: Partial<Record<number, PaintManualKeyframeTrack>>
readonly effects?: Partial<Record<number, EffectManualKeyframeTracks>>
}

Animations

type Animations = Partial<
Record<KeyframePropertyFieldName, KeyframeBinding>
> & {
readonly fills?: Partial<Record<number, PaintKeyframeBinding>>
readonly strokes?: Partial<Record<number, PaintKeyframeBinding>>
readonly effects?: Partial<Record<number, EffectKeyframeBindings>>
}

Timeline

duration is expressed in seconds.

interface Timeline {
readonly id: string
readonly duration: number
}