文档

文档

Vue

motion

motion

motion 组件驱动了 Vue 的 Motion 库中的大多数动画。

每个 HTML 和 SVG 元素都有一个 motion 组件,例如 motion.divmotion.circle 等。可以将其视为普通的 Vue 组件,但它被增强为支持 120fps 的动画和手势。

用法

motion-v 导入 motion

import { motion } from "motion-v"

现在你可以像使用任何普通的 HTML/SVG 组件一样使用它

<motion.div class="box" />

但你也可以访问强大的动画 API,例如 animatelayoutwhileInView 属性等等。

<motion.div
  class="box"
  // Animate when this value changes:
  :animate="{ scale: 2 }"
  // Fade in when the element enters the viewport:
  :whileInView="{ opacity: 1 }"
  // Animate the component when its layout changes:
  layout
  // Style now supports indepedent transforms:
  :style="{ x: 100 }"
/>

查看动画指南以获得关于 Vue 的 Motion 库中动画的完整概述。

性能

motion 组件在 Vue 渲染周期之外对值进行动画处理,以提高性能。

使用motion values(Motion 值)而不是 Vue 状态来更新 style 也可以避免重新渲染。

<script setup>
  import { useMotionValue } from "motion-v"
  
  const x = useMotionValue(0)
  let timeout;
  
  onMounted(() => {
    // Won't trigger a re-render!
    timeout = setTimeout(() => x.set(100), 1000)
  })
  
  onUnMounted(()=>{
    clearTimeout(timeout)
  })
</script>

<template>  
   <motion.div :style="{ x }" />
</template>

服务器端渲染

motion 组件与服务器端渲染完全兼容,这意味着组件的初始状态将反映在服务器生成的输出中。

// Server will output `translateX(100px)`
<motion.div :initial="false" :animate="{ x: 100 }" />

但某些 SVG 属性(如 transform)除外,这些属性需要 DOM 测量才能计算。

自定义组件

任何 Vue 组件都可以通过将其作为函数传递给 motion.create() 来增强为 motion 组件。

const MotionComponent = motion.create(Component)

重要提示:请确保不要在模板中调用 motion.create()!这将使每次渲染都创建一个新组件,从而破坏你的动画。

也可以将字符串传递给 motion.create,这将创建自定义 DOM 元素。

// Will render <custom-element /> into HTML
const MotionComponent = motion.create('custom-element')

默认情况下,所有 motion 属性(如 animate 等)都会从转发到所提供组件的 props 中过滤掉。通过提供 forwardMotionProps 配置,所提供的组件将接收这些属性。

motion.create(Component, { forwardMotionProps: true })

Motion Primitive(Motion 原始组件)

对于那些熟悉 Radix UI Primitives 的人来说,Motion 通过 <Motion /> 组件提供类似的原始组件模式。

通过 as 属性更改渲染的元素

<script setup>
import { Motion } from "motion-v"
</script>
<template>
  <Motion as="button">
    Click me
  </Motion>
</template>

将子元素用作渲染的元素

<script setup>
import { Motion } from "motion-v"
</script>
<template>
  <Motion as-child>
    <button>Click me</button>
  </Motion>
</template>

属性

motion 组件接受以下属性。

动画

initial

motion 组件的初始视觉状态。

可以设置为动画目标

<motion.section :initial="{ opacity: 0, x: 0 }" />

变体

<motion.li initial="visible" />
<motion.div :initial="['visible', 'active']" />

或者设置为 false 以禁用进入动画,并最初渲染为在 animate 中找到的值。

<motion.div :initial="false" :animate="{ opacity: 0 }" />

animate

进入和更新时要动画到的目标。

可以设置为动画目标

<motion.div
  :initial="{ boxShadow: '0px 0px #000' }"
  :animate="{ boxShadow: '10px 10px #000' }"
/>

或变体

<motion.li animate="visible" />
<motion.div initial="hidden" :animate="['visible', 'active']" />

exit

当组件从树中移除时要动画到的目标。可以设置为动画目标或变体。

注意:由于 Vue Transition 组件的限制,要移除的组件必须AnimatePresence直接子组件才能启用此动画。

<AnimatePresence>
    <ul v-if="isVisible"  key="list">
      <motion.li :exit="{ opacity: 0 }" />
    </ul>
</AnimatePresence>

transition

当动画属性(animatewhileHover 等)没有定义 transition 时,此组件要使用的默认过渡。

<motion.div :transition="{ type: 'spring' }" :animate="{ scale: 1.2 }" />

variants

此组件的variants变体。

<script setup>
  const variants = {
    active: {
        backgroundColor: "#f00"
    },
    inactive: {
      backgroundColor: "#fff",
      transition: { duration: 2 }
    }
  }
</script>

<template>  
  <motion.div
    :variants="variants"
    :animate="isActive ? 'active' : 'inactive'"
  />
</template>

style

普通的 Vue DOM style 属性,增加了对motion values(Motion 值)和独立变换的支持。

<script setup>
  const x = useMotionValue(30)
</script>

<tempalte>
  <motion.div :style="{ x, rotate: 90, originX: 0.5 }" />
</tempalte>

onUpdate

motion 组件上的任何值更新时,每帧触发的回调。它提供一个参数,其中包含最新的值。

<motion.article
  :animate="{ opacity: 1 }"
  :@update="latest => console.log(latest.opacity)"
/>

onAnimationStart

当任何动画(布局动画除外,请参阅 onLayoutAnimationStart)开始时触发的回调。

它提供一个参数,其中包含已启动动画的目标或变体名称。

<motion.circle
  :animate="{ r: 10 }"
  @animationStart="latest => console.log(latest.r)"
/>

onAnimationComplete

当任何动画(布局动画除外,请参阅 onLayoutAnimationComplete)完成时触发的回调。

它提供一个参数,其中包含已完成动画的目标或变体名称。

<motion.circle
  :animate="{ r: 10 }"
  @animationComplete="latest => console.log(latest.r)"
/>

Hover(悬停)

whileHover

当悬停手势处于活动状态时要标记到的目标或变体。

<!-- As target -->
<motion.button :whileHover="{ scale: 1.2 }" />
<!-- As variants -->
<motion.div whileHover="hovered" />

onHoverStart

当指针开始悬停在组件上时触发的回调函数。提供触发的 PointerEvent

<motion.div @hoverStart="(event) => console.log(event)" />

onHoverEnd

当指针停止悬停在组件上时触发的回调函数。提供触发的 PointerEvent

<motion.div @hoverEnd="(event) => console.log(event)" />

Press(按下)

whilePress

当按下手势处于活动状态时要标记到的目标或变体。

<!-- // As target -->
<motion.button :whilePress="{ scale: 0.9 }" />
<!-- // As variants -->
<motion.div whilePress="tapped" />

onPressStart

当指针开始按下组件时触发的回调函数。提供触发的 PointerEvent

<motion.div @pressStart="(event) => console.log(event)" />

onPress

当指针停止按下组件并且指针在组件内部释放时触发的回调函数。提供触发的 PointerEvent

<motion.div @press="(event) => console.log(event)" />

onPressCancel

当指针停止按下组件并且指针在组件外部释放时触发的回调函数。提供触发的 PointerEvent

<motion.div @pressCancel="(event) => console.log(event)" />

Focus(焦点)

whileFocus

当焦点手势处于活动状态时要标记到的目标或变体。

<!-- As target -->
<motion.button :whileFocus="{ outline: 'dashed #000' }" />
 <!-- As variants -->
<motion.div whileFocus="focused" />

Pan(平移)

onPan

当在此元素上识别到平移手势时触发的回调函数。

注意:为了使平移手势能够正确地与触摸输入一起工作,元素需要在 x/y 轴或两个轴上禁用触摸滚动,使用 touch-action CSS 规则。

function onPan(event, info) {
  console.log(info.point.x, info.point.y)
}

<motion.div @pan="onPan" />

平移和拖动手势事件提供原始 PointerEvent 以及一个 info 对象,该对象包含以下内容的 xy 点值

  • point:相对于设备或页面。

  • delta:自上次事件以来的距离。

  • offset:与原始事件的距离。

  • velocity:指针的当前速度。

onPanStart

当平移手势开始时触发的回调函数。提供触发的 PointerEventinfo

<motion.div @panStart="(event, info) => console.log(info.delta.x)" />

onPanEnd

当平移手势结束时触发的回调函数。提供触发的 PointerEventinfo

<motion.div @panEnd="(event, info) => console.log(info.delta.x)" />

Drag(拖动)

drag

默认值:false

为此元素启用拖动。设置为 true 以在两个方向上拖动。设置为 "x""y" 以仅在特定方向上拖动。

<motion.div drag />

whileDrag

当拖动手势处于活动状态时要标记到的目标或变体。

<!-- // As target -->
<motion.div drag :whileDrag="{ scale: 0.9 }" />
<!-- // As variants -->
<motion.div drag whileDrag="dragging" />

dragConstraints

对可拖动区域应用约束。

设置为可选 topleftrightbottom 值的对象,以像素为单位测量

<motion.div
  drag="x"
  :dragConstraints="{ left: 0, right: 300 }"
/>

或作为对另一个元素的 ref,以使用其边界框作为可拖动约束

<script setup>
  import { useDomRef } from "motion-v"
  const constraintsRef = useDomRef()
</script>
<template>
  <motion.div ref="constraintsRef">
    <motion.div drag :dragConstraints="constraintsRef" />
  </motion.div>
</template>

dragSnapToOrigin

默认值:false

如果为 true,则可拖动元素在释放时将动画返回到其中心/原点。

<motion.div drag dragSnapToOrigin />

dragElastic

默认值:0.5

约束外部允许的移动程度。0 = 不移动,1 = 完全移动。

默认设置为 0.5。也可以设置为 false 以禁用移动。

通过传递 top/right/bottom/left 的对象,可以为每个约束设置单独的值。任何缺失的值都将设置为 0

<motion.div
  drag
  :dragConstraints="{ left: 0, right: 300 }"
  :dragElastic="0.2"
/>

dragMomentum

默认值:true

在拖动完成时,将来自平移手势的动量应用于组件。默认设置为 true

<motion.div
  drag
  :dragConstraints="{ left: 0, right: 300 }"
  :dragMomentum="false"
/>

dragTransition

允许你更改拖动动量过渡。当释放可拖动元素时,会启动类型为 "inertia" 的动画。动画基于你的拖动速度。此属性允许你自定义它。

<motion.div
  drag
  :dragTransition="{ bounceStiffness: 600, bounceDamping: 10 }"
/>

dragDirectionLock

默认值:false

将拖动方向锁定到最早检测到的方向。例如,如果在拖动手势开始之前,组件在 x 轴上的移动多于 y 轴,则在手势的剩余时间内,它将x 轴上拖动。

<motion.div drag dragDirectionLock />

dragPropagation

默认值:false

允许拖动手势传播到子组件。

<motion.div drag="x" dragPropagation />

dragControls

通常,拖动是通过按下组件并移动它来启动的。对于某些用例,例如单击视频 scrub bar 上的任意点,我们可能希望从与可拖动组件不同的组件启动拖动。

通过使用 useDragControls 创建 dragControls钩子,我们可以将其传递到可拖动组件的 dragControls 属性中。它公开了一个 start 方法,该方法可以从其他组件上的指针事件开始拖动。

<script setup>
  const dragControls = useDragControls()
  
  function startDrag(event) {
    dragControls.start(event, { snapToCursor: true })
  }
</script>

<template>
  <div @pointerDown="startDrag" />
  <motion.div drag="x" :dragControls="dragControls" />
</template>

注意: 鉴于通过设置 dragControls 你正在控制启动拖动手势,因此可以通过设置 :dragListener="false" 来禁用可拖动元素作为启动器。

dragListener

确定是否从事件侦听器触发拖动手势。如果传递 dragControls,则将其设置为 false 将确保拖动只能由控件启动,而不是由可拖动元素上的 pointerdown 事件启动。

onDrag

当在此元素上识别到拖动手势时触发的回调函数。

function onDrag(event, info) {
  console.log(info.point.x, info.point.y)
}

<motion.div drag @drag="onDrag" />

平移和拖动手势事件提供原始 PointerEvent 以及一个 info 对象,该对象包含以下内容的 xy 点值

  • point:相对于设备或页面。

  • delta:自上次事件以来的距离。

  • offset:与原始事件的距离。

  • velocity:指针的当前速度。

onDragStart

当拖动手势开始时触发的回调函数。提供触发的 PointerEventinfo

<motion.div drag @dragStart="(event, info) => console.log(info.delta.x)" />

onDragEnd

当拖动手势结束时触发的回调函数。提供触发的 PointerEventinfo

<motion.div drag @dragEnd="(event, info) => console.log(info.delta.x)" />

onDirectionLock

当拖动方向确定时触发的回调函数。

<motion.div
  drag
  dragDirectionLock
  @directionLock="axis => console.log(axis)"
/>

Viewport(视口)

whileInView

当元素在视口中时要标记到的目标或变体。

<!-- As target -->
<motion.div :whileInView="{ opacity: 1 }" />
// As variants
<motion.div whileInView="visible" />

inViewOptions

用于定义如何在视口中跟踪元素的可选配置。

<motion.section
  :whileInView="{ opacity: 1 }"
  :inViewOptions="{ once: true }"
/>

可用选项

  • once:如果为 true,则元素一旦进入视口,将不再检测后续的离开/进入事件。

  • root:祖先可滚动元素的 ref,用于检测与其的交叉(而不是 window)。

  • margin:添加到视口的边距,以更改检测区域。默认为 "0px"。使用多个值来调整上/右/下/左,例如 "0px -20px 0px 100px"

  • amount:元素应进入视口才能被视为“已进入”的数量。可以是 "some""all" 或介于 01 之间的数字。默认为 "some"

onViewportEnter

当元素进入视口时触发的回调函数。提供 IntersectionObserverEntry,其中包含交叉事件的详细信息。

<motion.div @viewportEnter="(entry) => console.log(entry.isIntersecting)" />

onViewportLeave

当元素进入视口时触发的回调函数。提供 IntersectionObserverEntry,其中包含交叉事件的详细信息。

<motion.div @viewportLeave="(entry) => console.log(entry.intersectionRect)" />

布局

layout

默认值:false

如果为 true,则此组件将动画化其布局的更改.

<motion.div layout />

如果设置为 "position""size",则分别仅动画化其位置或大小。

<motion.img layout="position" />

layoutId

如果设置,此组件将动画化其布局的更改。此外,当新元素进入 DOM 并且已存在具有匹配 layoutId 的元素时,它将从先前元素的大小/位置动画移出。

 <motion.li v-for="item in items" layout>
    {{item.name}}
    <motion.div v-if="item.isSelected" layoutId="underline" />
 </motion.li>

如果先前的组件保留在树中,则这两个元素将交叉淡入淡出。

layoutDependency

默认情况下,每次渲染都会检测布局更改。为了减少测量次数并提高性能,你可以传递 layoutDependency 属性。仅当此值更改时才会进行测量。

<motion.nav layout :layoutDependency="isOpen" />

layoutScroll

为了使布局动画在可滚动元素中正确工作,需要测量其滚动偏移量。出于性能原因,Motion 不会测量每个祖先的滚动偏移量。将 layoutScroll 属性添加到应测量的元素。

<motion.div layoutScroll style="{ overflow: 'scroll' }">
  <motion.div layout />
</motion.div>

layoutRoot

为了使布局动画在 position: fixed 元素中正确工作,我们需要考虑页面滚动。添加 layoutRoot 以将元素标记为 position: fixed

<motion.div layoutRoot :style="{ position: 'fixed' }">
  <motion.div layout />
</motion.div>

onLayoutAnimationStart

布局动画开始时要运行的回调。

onLayoutAnimationComplete

布局动画完成时要运行的回调。

Advanced(高级)

inherit

设置为 false 以防止组件继承或传播父变体中的更改。

custom

要传递给动态变体的自定义数据。

<script setup>  
  const variants = {
    visible: (custom) => ({
      opacity: 1,
      transition: { delay: custom * 0.2 }
    })
  }
</script>

<template>
  <motion.ul animate="visible">
    <motion.li :custom="0" :variants="variants" />
    <motion.li :custom="1" :variants="variants" />
    <motion.li :custom="2" :variants="variants" />
  </motion.ul>
</template>

transformTemplate

默认情况下,变换按 translatescalerotateskew 的顺序应用。

要更改此顺序,可以将 transformTemplate 设置为一个函数,该函数接受最新的变换和生成的变换字符串,并返回一个新的变换字符串。

<!-- // Use the latest transform values -->
<motion.div
  :style="{ x: 0, rotate: 180 }"
  :transformTemplate="({ x, rotate }) => `rotate(${rotate}deg) translateX(${x}px)`"
/>
<!-- // Or the generated transform string -->
<motion.div
  :style="{ x: 0, rotate: 180 }"
  :transformTemplate="(latest, generated) => `translate(-50%, -50%) ${generated}`"
/>

motion 组件驱动了 Vue 的 Motion 库中的大多数动画。

每个 HTML 和 SVG 元素都有一个 motion 组件,例如 motion.divmotion.circle 等。可以将其视为普通的 Vue 组件,但它被增强为支持 120fps 的动画和手势。

用法

motion-v 导入 motion

import { motion } from "motion-v"

现在你可以像使用任何普通的 HTML/SVG 组件一样使用它

<motion.div class="box" />

但你也可以访问强大的动画 API,例如 animatelayoutwhileInView 属性等等。

<motion.div
  class="box"
  // Animate when this value changes:
  :animate="{ scale: 2 }"
  // Fade in when the element enters the viewport:
  :whileInView="{ opacity: 1 }"
  // Animate the component when its layout changes:
  layout
  // Style now supports indepedent transforms:
  :style="{ x: 100 }"
/>

查看动画指南以获得关于 Vue 的 Motion 库中动画的完整概述。

性能

motion 组件在 Vue 渲染周期之外对值进行动画处理,以提高性能。

使用motion values(Motion 值)而不是 Vue 状态来更新 style 也可以避免重新渲染。

<script setup>
  import { useMotionValue } from "motion-v"
  
  const x = useMotionValue(0)
  let timeout;
  
  onMounted(() => {
    // Won't trigger a re-render!
    timeout = setTimeout(() => x.set(100), 1000)
  })
  
  onUnMounted(()=>{
    clearTimeout(timeout)
  })
</script>

<template>  
   <motion.div :style="{ x }" />
</template>

服务器端渲染

motion 组件与服务器端渲染完全兼容,这意味着组件的初始状态将反映在服务器生成的输出中。

// Server will output `translateX(100px)`
<motion.div :initial="false" :animate="{ x: 100 }" />

但某些 SVG 属性(如 transform)除外,这些属性需要 DOM 测量才能计算。

自定义组件

任何 Vue 组件都可以通过将其作为函数传递给 motion.create() 来增强为 motion 组件。

const MotionComponent = motion.create(Component)

重要提示:请确保不要在模板中调用 motion.create()!这将使每次渲染都创建一个新组件,从而破坏你的动画。

也可以将字符串传递给 motion.create,这将创建自定义 DOM 元素。

// Will render <custom-element /> into HTML
const MotionComponent = motion.create('custom-element')

默认情况下,所有 motion 属性(如 animate 等)都会从转发到所提供组件的 props 中过滤掉。通过提供 forwardMotionProps 配置,所提供的组件将接收这些属性。

motion.create(Component, { forwardMotionProps: true })

Motion Primitive(Motion 原始组件)

对于那些熟悉 Radix UI Primitives 的人来说,Motion 通过 <Motion /> 组件提供类似的原始组件模式。

通过 as 属性更改渲染的元素

<script setup>
import { Motion } from "motion-v"
</script>
<template>
  <Motion as="button">
    Click me
  </Motion>
</template>

将子元素用作渲染的元素

<script setup>
import { Motion } from "motion-v"
</script>
<template>
  <Motion as-child>
    <button>Click me</button>
  </Motion>
</template>

属性

motion 组件接受以下属性。

动画

initial

motion 组件的初始视觉状态。

可以设置为动画目标

<motion.section :initial="{ opacity: 0, x: 0 }" />

变体

<motion.li initial="visible" />
<motion.div :initial="['visible', 'active']" />

或者设置为 false 以禁用进入动画,并最初渲染为在 animate 中找到的值。

<motion.div :initial="false" :animate="{ opacity: 0 }" />

animate

进入和更新时要动画到的目标。

可以设置为动画目标

<motion.div
  :initial="{ boxShadow: '0px 0px #000' }"
  :animate="{ boxShadow: '10px 10px #000' }"
/>

或变体

<motion.li animate="visible" />
<motion.div initial="hidden" :animate="['visible', 'active']" />

exit

当组件从树中移除时要动画到的目标。可以设置为动画目标或变体。

注意:由于 Vue Transition 组件的限制,要移除的组件必须AnimatePresence直接子组件才能启用此动画。

<AnimatePresence>
    <ul v-if="isVisible"  key="list">
      <motion.li :exit="{ opacity: 0 }" />
    </ul>
</AnimatePresence>

transition

当动画属性(animatewhileHover 等)没有定义 transition 时,此组件要使用的默认过渡。

<motion.div :transition="{ type: 'spring' }" :animate="{ scale: 1.2 }" />

variants

此组件的variants变体。

<script setup>
  const variants = {
    active: {
        backgroundColor: "#f00"
    },
    inactive: {
      backgroundColor: "#fff",
      transition: { duration: 2 }
    }
  }
</script>

<template>  
  <motion.div
    :variants="variants"
    :animate="isActive ? 'active' : 'inactive'"
  />
</template>

style

普通的 Vue DOM style 属性,增加了对motion values(Motion 值)和独立变换的支持。

<script setup>
  const x = useMotionValue(30)
</script>

<tempalte>
  <motion.div :style="{ x, rotate: 90, originX: 0.5 }" />
</tempalte>

onUpdate

motion 组件上的任何值更新时,每帧触发的回调。它提供一个参数,其中包含最新的值。

<motion.article
  :animate="{ opacity: 1 }"
  :@update="latest => console.log(latest.opacity)"
/>

onAnimationStart

当任何动画(布局动画除外,请参阅 onLayoutAnimationStart)开始时触发的回调。

它提供一个参数,其中包含已启动动画的目标或变体名称。

<motion.circle
  :animate="{ r: 10 }"
  @animationStart="latest => console.log(latest.r)"
/>

onAnimationComplete

当任何动画(布局动画除外,请参阅 onLayoutAnimationComplete)完成时触发的回调。

它提供一个参数,其中包含已完成动画的目标或变体名称。

<motion.circle
  :animate="{ r: 10 }"
  @animationComplete="latest => console.log(latest.r)"
/>

Hover(悬停)

whileHover

当悬停手势处于活动状态时要标记到的目标或变体。

<!-- As target -->
<motion.button :whileHover="{ scale: 1.2 }" />
<!-- As variants -->
<motion.div whileHover="hovered" />

onHoverStart

当指针开始悬停在组件上时触发的回调函数。提供触发的 PointerEvent

<motion.div @hoverStart="(event) => console.log(event)" />

onHoverEnd

当指针停止悬停在组件上时触发的回调函数。提供触发的 PointerEvent

<motion.div @hoverEnd="(event) => console.log(event)" />

Press(按下)

whilePress

当按下手势处于活动状态时要标记到的目标或变体。

<!-- // As target -->
<motion.button :whilePress="{ scale: 0.9 }" />
<!-- // As variants -->
<motion.div whilePress="tapped" />

onPressStart

当指针开始按下组件时触发的回调函数。提供触发的 PointerEvent

<motion.div @pressStart="(event) => console.log(event)" />

onPress

当指针停止按下组件并且指针在组件内部释放时触发的回调函数。提供触发的 PointerEvent

<motion.div @press="(event) => console.log(event)" />

onPressCancel

当指针停止按下组件并且指针在组件外部释放时触发的回调函数。提供触发的 PointerEvent

<motion.div @pressCancel="(event) => console.log(event)" />

Focus(焦点)

whileFocus

当焦点手势处于活动状态时要标记到的目标或变体。

<!-- As target -->
<motion.button :whileFocus="{ outline: 'dashed #000' }" />
 <!-- As variants -->
<motion.div whileFocus="focused" />

Pan(平移)

onPan

当在此元素上识别到平移手势时触发的回调函数。

注意:为了使平移手势能够正确地与触摸输入一起工作,元素需要在 x/y 轴或两个轴上禁用触摸滚动,使用 touch-action CSS 规则。

function onPan(event, info) {
  console.log(info.point.x, info.point.y)
}

<motion.div @pan="onPan" />

平移和拖动手势事件提供原始 PointerEvent 以及一个 info 对象,该对象包含以下内容的 xy 点值

  • point:相对于设备或页面。

  • delta:自上次事件以来的距离。

  • offset:与原始事件的距离。

  • velocity:指针的当前速度。

onPanStart

当平移手势开始时触发的回调函数。提供触发的 PointerEventinfo

<motion.div @panStart="(event, info) => console.log(info.delta.x)" />

onPanEnd

当平移手势结束时触发的回调函数。提供触发的 PointerEventinfo

<motion.div @panEnd="(event, info) => console.log(info.delta.x)" />

Drag(拖动)

drag

默认值:false

为此元素启用拖动。设置为 true 以在两个方向上拖动。设置为 "x""y" 以仅在特定方向上拖动。

<motion.div drag />

whileDrag

当拖动手势处于活动状态时要标记到的目标或变体。

<!-- // As target -->
<motion.div drag :whileDrag="{ scale: 0.9 }" />
<!-- // As variants -->
<motion.div drag whileDrag="dragging" />

dragConstraints

对可拖动区域应用约束。

设置为可选 topleftrightbottom 值的对象,以像素为单位测量

<motion.div
  drag="x"
  :dragConstraints="{ left: 0, right: 300 }"
/>

或作为对另一个元素的 ref,以使用其边界框作为可拖动约束

<script setup>
  import { useDomRef } from "motion-v"
  const constraintsRef = useDomRef()
</script>
<template>
  <motion.div ref="constraintsRef">
    <motion.div drag :dragConstraints="constraintsRef" />
  </motion.div>
</template>

dragSnapToOrigin

默认值:false

如果为 true,则可拖动元素在释放时将动画返回到其中心/原点。

<motion.div drag dragSnapToOrigin />

dragElastic

默认值:0.5

约束外部允许的移动程度。0 = 不移动,1 = 完全移动。

默认设置为 0.5。也可以设置为 false 以禁用移动。

通过传递 top/right/bottom/left 的对象,可以为每个约束设置单独的值。任何缺失的值都将设置为 0

<motion.div
  drag
  :dragConstraints="{ left: 0, right: 300 }"
  :dragElastic="0.2"
/>

dragMomentum

默认值:true

在拖动完成时,将来自平移手势的动量应用于组件。默认设置为 true

<motion.div
  drag
  :dragConstraints="{ left: 0, right: 300 }"
  :dragMomentum="false"
/>

dragTransition

允许你更改拖动动量过渡。当释放可拖动元素时,会启动类型为 "inertia" 的动画。动画基于你的拖动速度。此属性允许你自定义它。

<motion.div
  drag
  :dragTransition="{ bounceStiffness: 600, bounceDamping: 10 }"
/>

dragDirectionLock

默认值:false

将拖动方向锁定到最早检测到的方向。例如,如果在拖动手势开始之前,组件在 x 轴上的移动多于 y 轴,则在手势的剩余时间内,它将x 轴上拖动。

<motion.div drag dragDirectionLock />

dragPropagation

默认值:false

允许拖动手势传播到子组件。

<motion.div drag="x" dragPropagation />

dragControls

通常,拖动是通过按下组件并移动它来启动的。对于某些用例,例如单击视频 scrub bar 上的任意点,我们可能希望从与可拖动组件不同的组件启动拖动。

通过使用 useDragControls 创建 dragControls钩子,我们可以将其传递到可拖动组件的 dragControls 属性中。它公开了一个 start 方法,该方法可以从其他组件上的指针事件开始拖动。

<script setup>
  const dragControls = useDragControls()
  
  function startDrag(event) {
    dragControls.start(event, { snapToCursor: true })
  }
</script>

<template>
  <div @pointerDown="startDrag" />
  <motion.div drag="x" :dragControls="dragControls" />
</template>

注意: 鉴于通过设置 dragControls 你正在控制启动拖动手势,因此可以通过设置 :dragListener="false" 来禁用可拖动元素作为启动器。

dragListener

确定是否从事件侦听器触发拖动手势。如果传递 dragControls,则将其设置为 false 将确保拖动只能由控件启动,而不是由可拖动元素上的 pointerdown 事件启动。

onDrag

当在此元素上识别到拖动手势时触发的回调函数。

function onDrag(event, info) {
  console.log(info.point.x, info.point.y)
}

<motion.div drag @drag="onDrag" />

平移和拖动手势事件提供原始 PointerEvent 以及一个 info 对象,该对象包含以下内容的 xy 点值

  • point:相对于设备或页面。

  • delta:自上次事件以来的距离。

  • offset:与原始事件的距离。

  • velocity:指针的当前速度。

onDragStart

当拖动手势开始时触发的回调函数。提供触发的 PointerEventinfo

<motion.div drag @dragStart="(event, info) => console.log(info.delta.x)" />

onDragEnd

当拖动手势结束时触发的回调函数。提供触发的 PointerEventinfo

<motion.div drag @dragEnd="(event, info) => console.log(info.delta.x)" />

onDirectionLock

当拖动方向确定时触发的回调函数。

<motion.div
  drag
  dragDirectionLock
  @directionLock="axis => console.log(axis)"
/>

Viewport(视口)

whileInView

当元素在视口中时要标记到的目标或变体。

<!-- As target -->
<motion.div :whileInView="{ opacity: 1 }" />
// As variants
<motion.div whileInView="visible" />

inViewOptions

用于定义如何在视口中跟踪元素的可选配置。

<motion.section
  :whileInView="{ opacity: 1 }"
  :inViewOptions="{ once: true }"
/>

可用选项

  • once:如果为 true,则元素一旦进入视口,将不再检测后续的离开/进入事件。

  • root:祖先可滚动元素的 ref,用于检测与其的交叉(而不是 window)。

  • margin:添加到视口的边距,以更改检测区域。默认为 "0px"。使用多个值来调整上/右/下/左,例如 "0px -20px 0px 100px"

  • amount:元素应进入视口才能被视为“已进入”的数量。可以是 "some""all" 或介于 01 之间的数字。默认为 "some"

onViewportEnter

当元素进入视口时触发的回调函数。提供 IntersectionObserverEntry,其中包含交叉事件的详细信息。

<motion.div @viewportEnter="(entry) => console.log(entry.isIntersecting)" />

onViewportLeave

当元素进入视口时触发的回调函数。提供 IntersectionObserverEntry,其中包含交叉事件的详细信息。

<motion.div @viewportLeave="(entry) => console.log(entry.intersectionRect)" />

布局

layout

默认值:false

如果为 true,则此组件将动画化其布局的更改.

<motion.div layout />

如果设置为 "position""size",则分别仅动画化其位置或大小。

<motion.img layout="position" />

layoutId

如果设置,此组件将动画化其布局的更改。此外,当新元素进入 DOM 并且已存在具有匹配 layoutId 的元素时,它将从先前元素的大小/位置动画移出。

 <motion.li v-for="item in items" layout>
    {{item.name}}
    <motion.div v-if="item.isSelected" layoutId="underline" />
 </motion.li>

如果先前的组件保留在树中,则这两个元素将交叉淡入淡出。

layoutDependency

默认情况下,每次渲染都会检测布局更改。为了减少测量次数并提高性能,你可以传递 layoutDependency 属性。仅当此值更改时才会进行测量。

<motion.nav layout :layoutDependency="isOpen" />

layoutScroll

为了使布局动画在可滚动元素中正确工作,需要测量其滚动偏移量。出于性能原因,Motion 不会测量每个祖先的滚动偏移量。将 layoutScroll 属性添加到应测量的元素。

<motion.div layoutScroll style="{ overflow: 'scroll' }">
  <motion.div layout />
</motion.div>

layoutRoot

为了使布局动画在 position: fixed 元素中正确工作,我们需要考虑页面滚动。添加 layoutRoot 以将元素标记为 position: fixed

<motion.div layoutRoot :style="{ position: 'fixed' }">
  <motion.div layout />
</motion.div>

onLayoutAnimationStart

布局动画开始时要运行的回调。

onLayoutAnimationComplete

布局动画完成时要运行的回调。

Advanced(高级)

inherit

设置为 false 以防止组件继承或传播父变体中的更改。

custom

要传递给动态变体的自定义数据。

<script setup>  
  const variants = {
    visible: (custom) => ({
      opacity: 1,
      transition: { delay: custom * 0.2 }
    })
  }
</script>

<template>
  <motion.ul animate="visible">
    <motion.li :custom="0" :variants="variants" />
    <motion.li :custom="1" :variants="variants" />
    <motion.li :custom="2" :variants="variants" />
  </motion.ul>
</template>

transformTemplate

默认情况下,变换按 translatescalerotateskew 的顺序应用。

要更改此顺序,可以将 transformTemplate 设置为一个函数,该函数接受最新的变换和生成的变换字符串,并返回一个新的变换字符串。

<!-- // Use the latest transform values -->
<motion.div
  :style="{ x: 0, rotate: 180 }"
  :transformTemplate="({ x, rotate }) => `rotate(${rotate}deg) translateX(${x}px)`"
/>
<!-- // Or the generated transform string -->
<motion.div
  :style="{ x: 0, rotate: 180 }"
  :transformTemplate="(latest, generated) => `translate(-50%, -50%) ${generated}`"
/>

motion 组件驱动了 Vue 的 Motion 库中的大多数动画。

每个 HTML 和 SVG 元素都有一个 motion 组件,例如 motion.divmotion.circle 等。可以将其视为普通的 Vue 组件,但它被增强为支持 120fps 的动画和手势。

用法

motion-v 导入 motion

import { motion } from "motion-v"

现在你可以像使用任何普通的 HTML/SVG 组件一样使用它

<motion.div class="box" />

但你也可以访问强大的动画 API,例如 animatelayoutwhileInView 属性等等。

<motion.div
  class="box"
  // Animate when this value changes:
  :animate="{ scale: 2 }"
  // Fade in when the element enters the viewport:
  :whileInView="{ opacity: 1 }"
  // Animate the component when its layout changes:
  layout
  // Style now supports indepedent transforms:
  :style="{ x: 100 }"
/>

查看动画指南以获得关于 Vue 的 Motion 库中动画的完整概述。

性能

motion 组件在 Vue 渲染周期之外对值进行动画处理,以提高性能。

使用motion values(Motion 值)而不是 Vue 状态来更新 style 也可以避免重新渲染。

<script setup>
  import { useMotionValue } from "motion-v"
  
  const x = useMotionValue(0)
  let timeout;
  
  onMounted(() => {
    // Won't trigger a re-render!
    timeout = setTimeout(() => x.set(100), 1000)
  })
  
  onUnMounted(()=>{
    clearTimeout(timeout)
  })
</script>

<template>  
   <motion.div :style="{ x }" />
</template>

服务器端渲染

motion 组件与服务器端渲染完全兼容,这意味着组件的初始状态将反映在服务器生成的输出中。

// Server will output `translateX(100px)`
<motion.div :initial="false" :animate="{ x: 100 }" />

但某些 SVG 属性(如 transform)除外,这些属性需要 DOM 测量才能计算。

自定义组件

任何 Vue 组件都可以通过将其作为函数传递给 motion.create() 来增强为 motion 组件。

const MotionComponent = motion.create(Component)

重要提示:请确保不要在模板中调用 motion.create()!这将使每次渲染都创建一个新组件,从而破坏你的动画。

也可以将字符串传递给 motion.create,这将创建自定义 DOM 元素。

// Will render <custom-element /> into HTML
const MotionComponent = motion.create('custom-element')

默认情况下,所有 motion 属性(如 animate 等)都会从转发到所提供组件的 props 中过滤掉。通过提供 forwardMotionProps 配置,所提供的组件将接收这些属性。

motion.create(Component, { forwardMotionProps: true })

Motion Primitive(Motion 原始组件)

对于那些熟悉 Radix UI Primitives 的人来说,Motion 通过 <Motion /> 组件提供类似的原始组件模式。

通过 as 属性更改渲染的元素

<script setup>
import { Motion } from "motion-v"
</script>
<template>
  <Motion as="button">
    Click me
  </Motion>
</template>

将子元素用作渲染的元素

<script setup>
import { Motion } from "motion-v"
</script>
<template>
  <Motion as-child>
    <button>Click me</button>
  </Motion>
</template>

属性

motion 组件接受以下属性。

动画

initial

motion 组件的初始视觉状态。

可以设置为动画目标

<motion.section :initial="{ opacity: 0, x: 0 }" />

变体

<motion.li initial="visible" />
<motion.div :initial="['visible', 'active']" />

或者设置为 false 以禁用进入动画,并最初渲染为在 animate 中找到的值。

<motion.div :initial="false" :animate="{ opacity: 0 }" />

animate

进入和更新时要动画到的目标。

可以设置为动画目标

<motion.div
  :initial="{ boxShadow: '0px 0px #000' }"
  :animate="{ boxShadow: '10px 10px #000' }"
/>

或变体

<motion.li animate="visible" />
<motion.div initial="hidden" :animate="['visible', 'active']" />

exit

当组件从树中移除时要动画到的目标。可以设置为动画目标或变体。

注意:由于 Vue Transition 组件的限制,要移除的组件必须AnimatePresence直接子组件才能启用此动画。

<AnimatePresence>
    <ul v-if="isVisible"  key="list">
      <motion.li :exit="{ opacity: 0 }" />
    </ul>
</AnimatePresence>

transition

当动画属性(animatewhileHover 等)没有定义 transition 时,此组件要使用的默认过渡。

<motion.div :transition="{ type: 'spring' }" :animate="{ scale: 1.2 }" />

variants

此组件的variants变体。

<script setup>
  const variants = {
    active: {
        backgroundColor: "#f00"
    },
    inactive: {
      backgroundColor: "#fff",
      transition: { duration: 2 }
    }
  }
</script>

<template>  
  <motion.div
    :variants="variants"
    :animate="isActive ? 'active' : 'inactive'"
  />
</template>

style

普通的 Vue DOM style 属性,增加了对motion values(Motion 值)和独立变换的支持。

<script setup>
  const x = useMotionValue(30)
</script>

<tempalte>
  <motion.div :style="{ x, rotate: 90, originX: 0.5 }" />
</tempalte>

onUpdate

motion 组件上的任何值更新时,每帧触发的回调。它提供一个参数,其中包含最新的值。

<motion.article
  :animate="{ opacity: 1 }"
  :@update="latest => console.log(latest.opacity)"
/>

onAnimationStart

当任何动画(布局动画除外,请参阅 onLayoutAnimationStart)开始时触发的回调。

它提供一个参数,其中包含已启动动画的目标或变体名称。

<motion.circle
  :animate="{ r: 10 }"
  @animationStart="latest => console.log(latest.r)"
/>

onAnimationComplete

当任何动画(布局动画除外,请参阅 onLayoutAnimationComplete)完成时触发的回调。

它提供一个参数,其中包含已完成动画的目标或变体名称。

<motion.circle
  :animate="{ r: 10 }"
  @animationComplete="latest => console.log(latest.r)"
/>

Hover(悬停)

whileHover

当悬停手势处于活动状态时要标记到的目标或变体。

<!-- As target -->
<motion.button :whileHover="{ scale: 1.2 }" />
<!-- As variants -->
<motion.div whileHover="hovered" />

onHoverStart

当指针开始悬停在组件上时触发的回调函数。提供触发的 PointerEvent

<motion.div @hoverStart="(event) => console.log(event)" />

onHoverEnd

当指针停止悬停在组件上时触发的回调函数。提供触发的 PointerEvent

<motion.div @hoverEnd="(event) => console.log(event)" />

Press(按下)

whilePress

当按下手势处于活动状态时要标记到的目标或变体。

<!-- // As target -->
<motion.button :whilePress="{ scale: 0.9 }" />
<!-- // As variants -->
<motion.div whilePress="tapped" />

onPressStart

当指针开始按下组件时触发的回调函数。提供触发的 PointerEvent

<motion.div @pressStart="(event) => console.log(event)" />

onPress

当指针停止按下组件并且指针在组件内部释放时触发的回调函数。提供触发的 PointerEvent

<motion.div @press="(event) => console.log(event)" />

onPressCancel

当指针停止按下组件并且指针在组件外部释放时触发的回调函数。提供触发的 PointerEvent

<motion.div @pressCancel="(event) => console.log(event)" />

Focus(焦点)

whileFocus

当焦点手势处于活动状态时要标记到的目标或变体。

<!-- As target -->
<motion.button :whileFocus="{ outline: 'dashed #000' }" />
 <!-- As variants -->
<motion.div whileFocus="focused" />

Pan(平移)

onPan

当在此元素上识别到平移手势时触发的回调函数。

注意:为了使平移手势能够正确地与触摸输入一起工作,元素需要在 x/y 轴或两个轴上禁用触摸滚动,使用 touch-action CSS 规则。

function onPan(event, info) {
  console.log(info.point.x, info.point.y)
}

<motion.div @pan="onPan" />

平移和拖动手势事件提供原始 PointerEvent 以及一个 info 对象,该对象包含以下内容的 xy 点值

  • point:相对于设备或页面。

  • delta:自上次事件以来的距离。

  • offset:与原始事件的距离。

  • velocity:指针的当前速度。

onPanStart

当平移手势开始时触发的回调函数。提供触发的 PointerEventinfo

<motion.div @panStart="(event, info) => console.log(info.delta.x)" />

onPanEnd

当平移手势结束时触发的回调函数。提供触发的 PointerEventinfo

<motion.div @panEnd="(event, info) => console.log(info.delta.x)" />

Drag(拖动)

drag

默认值:false

为此元素启用拖动。设置为 true 以在两个方向上拖动。设置为 "x""y" 以仅在特定方向上拖动。

<motion.div drag />

whileDrag

当拖动手势处于活动状态时要标记到的目标或变体。

<!-- // As target -->
<motion.div drag :whileDrag="{ scale: 0.9 }" />
<!-- // As variants -->
<motion.div drag whileDrag="dragging" />

dragConstraints

对可拖动区域应用约束。

设置为可选 topleftrightbottom 值的对象,以像素为单位测量

<motion.div
  drag="x"
  :dragConstraints="{ left: 0, right: 300 }"
/>

或作为对另一个元素的 ref,以使用其边界框作为可拖动约束

<script setup>
  import { useDomRef } from "motion-v"
  const constraintsRef = useDomRef()
</script>
<template>
  <motion.div ref="constraintsRef">
    <motion.div drag :dragConstraints="constraintsRef" />
  </motion.div>
</template>

dragSnapToOrigin

默认值:false

如果为 true,则可拖动元素在释放时将动画返回到其中心/原点。

<motion.div drag dragSnapToOrigin />

dragElastic

默认值:0.5

约束外部允许的移动程度。0 = 不移动,1 = 完全移动。

默认设置为 0.5。也可以设置为 false 以禁用移动。

通过传递 top/right/bottom/left 的对象,可以为每个约束设置单独的值。任何缺失的值都将设置为 0

<motion.div
  drag
  :dragConstraints="{ left: 0, right: 300 }"
  :dragElastic="0.2"
/>

dragMomentum

默认值:true

在拖动完成时,将来自平移手势的动量应用于组件。默认设置为 true

<motion.div
  drag
  :dragConstraints="{ left: 0, right: 300 }"
  :dragMomentum="false"
/>

dragTransition

允许你更改拖动动量过渡。当释放可拖动元素时,会启动类型为 "inertia" 的动画。动画基于你的拖动速度。此属性允许你自定义它。

<motion.div
  drag
  :dragTransition="{ bounceStiffness: 600, bounceDamping: 10 }"
/>

dragDirectionLock

默认值:false

将拖动方向锁定到最早检测到的方向。例如,如果在拖动手势开始之前,组件在 x 轴上的移动多于 y 轴,则在手势的剩余时间内,它将x 轴上拖动。

<motion.div drag dragDirectionLock />

dragPropagation

默认值:false

允许拖动手势传播到子组件。

<motion.div drag="x" dragPropagation />

dragControls

通常,拖动是通过按下组件并移动它来启动的。对于某些用例,例如单击视频 scrub bar 上的任意点,我们可能希望从与可拖动组件不同的组件启动拖动。

通过使用 useDragControls 创建 dragControls钩子,我们可以将其传递到可拖动组件的 dragControls 属性中。它公开了一个 start 方法,该方法可以从其他组件上的指针事件开始拖动。

<script setup>
  const dragControls = useDragControls()
  
  function startDrag(event) {
    dragControls.start(event, { snapToCursor: true })
  }
</script>

<template>
  <div @pointerDown="startDrag" />
  <motion.div drag="x" :dragControls="dragControls" />
</template>

注意: 鉴于通过设置 dragControls 你正在控制启动拖动手势,因此可以通过设置 :dragListener="false" 来禁用可拖动元素作为启动器。

dragListener

确定是否从事件侦听器触发拖动手势。如果传递 dragControls,则将其设置为 false 将确保拖动只能由控件启动,而不是由可拖动元素上的 pointerdown 事件启动。

onDrag

当在此元素上识别到拖动手势时触发的回调函数。

function onDrag(event, info) {
  console.log(info.point.x, info.point.y)
}

<motion.div drag @drag="onDrag" />

平移和拖动手势事件提供原始 PointerEvent 以及一个 info 对象,该对象包含以下内容的 xy 点值

  • point:相对于设备或页面。

  • delta:自上次事件以来的距离。

  • offset:与原始事件的距离。

  • velocity:指针的当前速度。

onDragStart

当拖动手势开始时触发的回调函数。提供触发的 PointerEventinfo

<motion.div drag @dragStart="(event, info) => console.log(info.delta.x)" />

onDragEnd

当拖动手势结束时触发的回调函数。提供触发的 PointerEventinfo

<motion.div drag @dragEnd="(event, info) => console.log(info.delta.x)" />

onDirectionLock

当拖动方向确定时触发的回调函数。

<motion.div
  drag
  dragDirectionLock
  @directionLock="axis => console.log(axis)"
/>

Viewport(视口)

whileInView

当元素在视口中时要标记到的目标或变体。

<!-- As target -->
<motion.div :whileInView="{ opacity: 1 }" />
// As variants
<motion.div whileInView="visible" />

inViewOptions

用于定义如何在视口中跟踪元素的可选配置。

<motion.section
  :whileInView="{ opacity: 1 }"
  :inViewOptions="{ once: true }"
/>

可用选项

  • once:如果为 true,则元素一旦进入视口,将不再检测后续的离开/进入事件。

  • root:祖先可滚动元素的 ref,用于检测与其的交叉(而不是 window)。

  • margin:添加到视口的边距,以更改检测区域。默认为 "0px"。使用多个值来调整上/右/下/左,例如 "0px -20px 0px 100px"

  • amount:元素应进入视口才能被视为“已进入”的数量。可以是 "some""all" 或介于 01 之间的数字。默认为 "some"

onViewportEnter

当元素进入视口时触发的回调函数。提供 IntersectionObserverEntry,其中包含交叉事件的详细信息。

<motion.div @viewportEnter="(entry) => console.log(entry.isIntersecting)" />

onViewportLeave

当元素进入视口时触发的回调函数。提供 IntersectionObserverEntry,其中包含交叉事件的详细信息。

<motion.div @viewportLeave="(entry) => console.log(entry.intersectionRect)" />

布局

layout

默认值:false

如果为 true,则此组件将动画化其布局的更改.

<motion.div layout />

如果设置为 "position""size",则分别仅动画化其位置或大小。

<motion.img layout="position" />

layoutId

如果设置,此组件将动画化其布局的更改。此外,当新元素进入 DOM 并且已存在具有匹配 layoutId 的元素时,它将从先前元素的大小/位置动画移出。

 <motion.li v-for="item in items" layout>
    {{item.name}}
    <motion.div v-if="item.isSelected" layoutId="underline" />
 </motion.li>

如果先前的组件保留在树中,则这两个元素将交叉淡入淡出。

layoutDependency

默认情况下,每次渲染都会检测布局更改。为了减少测量次数并提高性能,你可以传递 layoutDependency 属性。仅当此值更改时才会进行测量。

<motion.nav layout :layoutDependency="isOpen" />

layoutScroll

为了使布局动画在可滚动元素中正确工作,需要测量其滚动偏移量。出于性能原因,Motion 不会测量每个祖先的滚动偏移量。将 layoutScroll 属性添加到应测量的元素。

<motion.div layoutScroll style="{ overflow: 'scroll' }">
  <motion.div layout />
</motion.div>

layoutRoot

为了使布局动画在 position: fixed 元素中正确工作,我们需要考虑页面滚动。添加 layoutRoot 以将元素标记为 position: fixed

<motion.div layoutRoot :style="{ position: 'fixed' }">
  <motion.div layout />
</motion.div>

onLayoutAnimationStart

布局动画开始时要运行的回调。

onLayoutAnimationComplete

布局动画完成时要运行的回调。

Advanced(高级)

inherit

设置为 false 以防止组件继承或传播父变体中的更改。

custom

要传递给动态变体的自定义数据。

<script setup>  
  const variants = {
    visible: (custom) => ({
      opacity: 1,
      transition: { delay: custom * 0.2 }
    })
  }
</script>

<template>
  <motion.ul animate="visible">
    <motion.li :custom="0" :variants="variants" />
    <motion.li :custom="1" :variants="variants" />
    <motion.li :custom="2" :variants="variants" />
  </motion.ul>
</template>

transformTemplate

默认情况下,变换按 translatescalerotateskew 的顺序应用。

要更改此顺序,可以将 transformTemplate 设置为一个函数,该函数接受最新的变换和生成的变换字符串,并返回一个新的变换字符串。

<!-- // Use the latest transform values -->
<motion.div
  :style="{ x: 0, rotate: 180 }"
  :transformTemplate="({ x, rotate }) => `rotate(${rotate}deg) translateX(${x}px)`"
/>
<!-- // Or the generated transform string -->
<motion.div
  :style="{ x: 0, rotate: 180 }"
  :transformTemplate="(latest, generated) => `translate(-50%, -50%) ${generated}`"
/>

motion

示例

超越基础功能

Motion+是一次性付费,终身会员资格。

除了高级 Motion 功能、抢先体验内容和私有 Discord 社区外,你还将解锁访问 90 多个高级示例的源代码的权限,这些示例将此页面上的 API 提升到一个新的水平。

正在加载...
正在加载...
保持关注

订阅以获取最新消息和更新。

保持关注

订阅以获取最新消息和更新。