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.