Motion

Renders an animatable HTML or SVG element.

<Motion :animate="{ opacity: 1 }"></Motion>

Usage

Import Motion from "motion/vue" and register it with your component.

<template>
  <Motion />
</template>

<script>
import { Motion } from "motion/vue"

export default {
  components: { Motion }
}
</script>

<style scoped>
div {
  width: 100px;
  height: 100px;
  border-radius: 10px;
  background-color: var(--splash);
}
</style>

Motion accepts an animate prop. Add the following to the editable example above:

<Motion :animate="{ rotate: 45, backgroundColor: 'var(--red)' }"></Motion>

The animate prop accepts all the same values and keyframes as Motion One's animate function.

Transition settings

We can change the type of animation used by passing a transition prop.

<Motion
  :animate="{ rotate: 90, backgroundColor: 'var(--yellow)' }"
  :transition="{ duration: 1, easing: 'ease-out' }"
>
</Motion>

By default transition options are applied to all values, but we can also override on a per-value basis:

<Motion
  :animate="{ rotate: 90, backgroundColor: 'var(--yellow)' }"
  :transition="{
    duration: 1,
    x: { duration: 2 },
  }"
>
</Motion>

All the same transition options from Motion One's animate function are accepted. You can even import custom easing from Motion One, like spring:

<template>
  <Motion
    :animate="{ rotate: 90, backgroundColor: 'var(--yellow)' }"
    :transition="transition"
  />
</template>

<script>
import { spring } from "motion"
import { Motion } from "motion/vue"

export default {
  components: { Motion },
  setup() {
    return {
      transition: {
        delay: 1,
        easing: spring()
      },
    }
  },
}
</script>

<style scoped>
div {
  width: 100px;
  height: 100px;
  border-radius: 10px;
  background-color: var(--splash);
}
</style>

Props

tag

Default: "div"

Define a HTML or SVG tag to render.

<Motion tag="li"></Motion>

animate

A target of values to animate to.

<Motion :animate="{ backgroundColor: 'white' }"></Motion>

Whenever a value in animate changes, the element will automatically animate to the latest value.

The animate prop accepts all the same values and keyframes as Motion One's animate function.

initial

A target of values to animate from when the element is first rendered.

<Motion :initial="{ x: 100 }" :animate="{ x: 0 }"></Motion>

If set to false, the target defined in animate will be immediately set when the element is first rendered. Only subsequent changes to animate will animate.

<Motion :initial="false" :animate="{ x: 100 }"></Motion>

exit

A target of values to animate to when the element is hidden via v-if or v-show.

The element must be a direct child of the Presence component.

<template>
  <div class="container">
    <Presence>
      <Motion
        v-show="show"
        :initial="{ opacity: 0, scale: 0 }"
        :animate="{ opacity: 1, scale: 1 }"
        :exit="{ opacity: 0, scale: 0.6 }"
        class="box"
      />
    </Presence>
    <button @click="show = !show">
      Toggle
    </button>
  </div>
</template>

<script>
import { Motion, Presence } from "motion/vue"

export default {
  components: { Motion, Presence },
  data() {
    return { show: true }
  }
}
</script>

<style>
.container {
  width: 100px;
  height: 150px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

.container button {
  cursor: pointer;
}
.box {
  width: 100px;
  height: 100px;
  border-radius: 10px;
  background-color: var(--splash);
}
</style>

Note: This animation is only interruptible if the element is hidden via v-show.

The exit prop accepts all the same values and keyframes as Motion One's animate function.

transition

Provides a default transition for all animations to use.

<Motion :animate="{ x: 100 }" :transition="{ duration: 0.5 }">
</Motion>

Supports all animate options.

The transition defined in this prop can be overridden for specific animation props by passing those a transition option:

<Motion
  :animate="{
    x: 100,
    transition: { duration: 0.2 },
  }"
  :exit="{
    x: 0,
    transition: { duration: 1 },
  }"
  :transition="{ duration: 0.5 }"
>
</Motion>

Events

The Motion components emit custom DOM events to the rendered element. The detail prop is provided data on the related animation.

<template>
  <Motion
    :initial="{ opacity: 0 }"
    :animate="{ opacity: 1 }"
    @motionstart="logStart"
    @motioncomplete="logComplete"
  />
</template>

<script>
import { Motion } from "motion/vue"

export default {
  components: { Motion },
  methods: {
    logStart: ({ detail }) => console.log("Start: ", detail),
    logComplete: ({ detail }) => console.log("Complete: ", detail)
  }
}
</script>

<style scoped>
div {
  width: 100px;
  height: 100px;
  border-radius: 10px;
  background-color: var(--splash);
}
</style>

motionstart

Fires when any animation is started.

motioncomplete

Fires when any animation is completed.

Have you seen Motion DevTools?

It's an incredible new developer tool for Chrome that let you inspect, edit and export Motion One and CSS animations. Animate like the good-ol' days of Flash!