Skip to content

Commit a0518e4

Browse files
authored
Merge pull request #50 from unovue/feat/animation-control
update docs
2 parents 8b28052 + 7c18d7a commit a0518e4

File tree

13 files changed

+287
-23
lines changed

13 files changed

+287
-23
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<script setup lang="ts">
2+
type PropDef = {
3+
name?: string
4+
required?: boolean
5+
default?: string | boolean
6+
type: string
7+
typeSimple: string
8+
description?: string
9+
}
10+
11+
interface PropsTableProps {
12+
data: PropDef[]
13+
}
14+
const { data } = defineProps<PropsTableProps>()
15+
</script>
16+
17+
<template>
18+
<ProseTable class="rounded-md border border-border/50 bg-white">
19+
<ProseThead>
20+
<ProseTr>
21+
<ProseTh class="w-1/6 bg-muted/30 py-3 text-sm font-medium">
22+
<span>Prop</span>
23+
</ProseTh>
24+
<ProseTh class="w-1/6 bg-muted/30 py-3 text-sm font-medium">
25+
<span>Default</span>
26+
</ProseTh>
27+
<ProseTh class="w-2/3 bg-muted/30 py-3 text-sm font-medium">
28+
<span>Type</span>
29+
</ProseTh>
30+
</ProseTr>
31+
</ProseThead>
32+
33+
<ProseTbody>
34+
<ProseTr
35+
v-for="(prop, index) in data"
36+
:key="`${prop.name}-${index}`"
37+
class=" transition-colors"
38+
>
39+
<ProseTd class="py-3">
40+
<div class="flex h-full items-start gap-1">
41+
<ProseCodeInline class="text-[13px] font-medium text-primary">
42+
{{ prop.name }}{{ prop.required ? "*" : null }}
43+
</ProseCodeInline>
44+
</div>
45+
</ProseTd>
46+
47+
<ProseTd class="py-3">
48+
<div
49+
v-if="prop.default"
50+
class="flex h-full items-start gap-1"
51+
>
52+
<ProseCodeInline
53+
variant="secondary"
54+
class="text-muted-foreground"
55+
>
56+
{{ prop.default }}
57+
</ProseCodeInline>
58+
</div>
59+
<template v-else>
60+
<div
61+
as="{AccessibleIcon}"
62+
label="No default value"
63+
class="text-muted-foreground/50"
64+
>
65+
<!-- <Icon name="da" /> -->
66+
</div>
67+
</template>
68+
</ProseTd>
69+
70+
<ProseTd class="py-3">
71+
<div class="flex flex-col">
72+
<ProseCodeInline
73+
variant="secondary"
74+
class="w-max text-sm text-primary/80"
75+
>
76+
{{ prop.typeSimple ? prop.typeSimple : prop.type }}
77+
</ProseCodeInline>
78+
<div
79+
class="mt-2 flex flex-col gap-2 text-sm text-muted-foreground [&_p]:mb-0 [&_p]:mt-0"
80+
v-html="prop.description"
81+
/>
82+
</div>
83+
</ProseTd>
84+
</ProseTr>
85+
</ProseTbody>
86+
</ProseTable>
87+
</template>

docs/components/content/ProseCodeInline.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<code class="inline-code relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono">
2+
<code class="inline-code relative rounded bg-primary/10 px-[0.3rem] py-[0.2rem] font-mono">
33
<slot />
44
</code>
55
</template>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<thead>
2+
<thead class="border-b border-border bg-muted/50">
33
<slot />
44
</thead>
55
</template>

docs/components/content/ProseTr.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<tr class="m-0 border-t p-0 even:bg-muted/50">
2+
<tr class="m-0 border-t p-0 bg-background even:bg-muted">
33
<slot />
44
</tr>
55
</template>

docs/components/demo/pan/index.vue

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<script setup lang="ts">
2+
import { Motion, useAnimationControls } from 'motion-v'
3+
import type { PanInfo, TransformProperties } from 'motion-v'
4+
5+
function template({ rotateY, rotateX }: TransformProperties) {
6+
return `perspective(500px) rotateX(${rotateX}) rotateY(${rotateY})`
7+
}
8+
9+
const controls = useAnimationControls()
10+
function handlePan(_: PointerEvent, info: PanInfo) {
11+
_.preventDefault()
12+
controls.set({
13+
rotateY: info.offset.x / 2,
14+
rotateX: -info.offset.y / 2,
15+
})
16+
}
17+
18+
function handlePanEnd() {
19+
controls.start({
20+
rotateY: 0,
21+
rotateX: 0,
22+
})
23+
}
24+
</script>
25+
26+
<template>
27+
<div class="flex flex-col items-center justify-center ">
28+
<Motion
29+
class="card"
30+
:transform-template="template"
31+
:animate="controls"
32+
@pan="handlePan"
33+
@pan-end="handlePanEnd"
34+
/>
35+
</div>
36+
</template>
37+
38+
<style scoped>
39+
.card {
40+
width: 400px;
41+
height: 250px;
42+
border-radius: 10px;
43+
cursor: pointer;
44+
background-image: url(/pug.jpg);
45+
background-size: cover;
46+
background-repeat: no-repeat;
47+
background-position: center center;
48+
49+
&:active {
50+
cursor: grab;
51+
}
52+
}
53+
</style>

docs/components/layout/Aside.vue

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,8 @@
11
<script setup lang="ts">
22
const props = defineProps<{ isMobile: boolean }>()
33
defineEmits(['close'])
4-
const { navDirFromPath } = useContentHelpers()
54
const { navigation } = useContent()
65
const config = useConfig()
7-
const tree = computed(() => {
8-
const route = useRoute()
9-
const path = route.path.split('/')
10-
if (config.value?.aside.useLevel) {
11-
const leveledPath = path.splice(0, 2).join('/')
12-
13-
const dir = navDirFromPath(leveledPath, navigation.value)
14-
return dir ?? []
15-
}
16-
17-
return navigation.value
18-
})
19-
onMounted(() => {
20-
console.log(tree.value, navigation)
21-
})
226
237
const path = computed(() => useRoute().path)
248
</script>

docs/content/2.components/1.motion.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ import { motion } from 'motion-v'
6969
</template>
7070
```
7171

72-
for Component, You can also use `motion.create` to create a motion version of any custom component:
72+
for Component, You can also use `motion.create` to create a motion Component of any custom component:
7373

7474
```vue
7575
<script setup lang="ts">

docs/content/3.animation/gesture.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,27 @@ Callback function that fires when a pointer stops pressing the component and the
7171
/>
7272
```
7373

74+
## Focus
75+
76+
The focus gesture detects when a component gains or loses focus, following the same rules as the CSS :focus-visible selector.
77+
78+
You can use `@focus` and `@blur` events, or the `focus` prop to animate when a component has focus. For example:
79+
80+
```vue
81+
<Motion
82+
focus="{ scale: 1.2 }"
83+
href="#"
84+
/>
85+
```
86+
87+
## Pan
88+
89+
The pan gesture recognises when a pointer presses down on a component and moves further than 3 pixels. The pan gesture is ended when the pointer is released. Unlike drag, pan only provides event handlers and does not have props for animation.
90+
91+
You can use `@pan-start`, `@pan`, `@pan-end` events to handle pan gestures:
92+
93+
<ComponentPreview name="pan" />
94+
7495
## Drag
7596

7697
The `Drag` gesture control allows you to drag an element.
@@ -84,3 +105,67 @@ and can use `whileDrag` to animate the element while dragging.
84105
### Drag with constraints
85106

86107
<ComponentPreview name="drag-with-constraints" />
108+
109+
### Drag Props
110+
111+
::PropsTable
112+
---
113+
data:
114+
- name: drag
115+
default: "false"
116+
type: "boolean | 'x' | 'y'"
117+
description: Enable dragging for this element. Set to `false` by default.
118+
- name: dragSnapToOrigin
119+
default: "false"
120+
type: "boolean"
121+
description: If `true`, this will snap back to its origin when dragging ends.
122+
- name: dragDirectionLock
123+
default: "false"
124+
type: "boolean"
125+
description: If `true`, this will lock dragging to the initially-detected direction. Defaults to `false`.
126+
- name: dragPropagation
127+
default: "false"
128+
type: "boolean"
129+
description: Allows drag gesture propagation to child components. Set to `false` by default.
130+
- name: dragConstraints
131+
default: "false"
132+
type: "false | Partial<BoundingBox> | HTMLElement"
133+
description: The drag constraints. Set to `false` by default.
134+
- name: dragElastic
135+
default: "0.5"
136+
type: "boolean | number | Partial<BoundingBox>"
137+
description: The drag elasticity. Set to `0.5` by default.
138+
- name: dragMomentum
139+
default: "true"
140+
type: "boolean"
141+
description: Apply momentum from the pan gesture to the component when dragging finishes. Set to `true` by default.
142+
- name: dragTransition
143+
type: "InertiaOptions"
144+
description: The drag transition. Set to `undefined` by default.
145+
- name: dragListener
146+
default: "true"
147+
type: "boolean"
148+
description: By default, if `drag` is defined on a component then an event listener will be attached to automatically initiate dragging when a user presses down on it. Set to `true` by default.
149+
- name: dragControls
150+
type: "DragControls"
151+
description: A drag controls object.
152+
- name: onDragStart
153+
type: "(event: PointerEvent, info: PanInfo) => void"
154+
description: Callback function that fires when dragging starts. Provided the triggering `PointerEvent` and `PanInfo`.
155+
- name: onDrag
156+
type: "(event: PointerEvent, info: PanInfo) => void"
157+
description: Callback function that fires when dragging. Provided the triggering `PointerEvent` and `PanInfo`.
158+
- name: onDragEnd
159+
type: "(event: PointerEvent, info: PanInfo) => void"
160+
description: Callback function that fires when dragging ends.
161+
- name: dragDirectionLock
162+
type: "(axis: 'x' | 'y') => void"
163+
description: Callback function that fires when the drag direction is locked to the x or y axis.
164+
- name: onDragTransitionEnd
165+
type: "() => void"
166+
description: Callback function that fires when drag momentum/bounce transition finishes.
167+
- name: onMeasureDragConstraints
168+
type: "(constraints: BoundingBox) => BoundingBox | void"
169+
description: If `dragConstraints` is set to a React ref, this callback will call with the measured drag constraints.
170+
---
171+
::
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
title: useAnimationControls
3+
description:
4+
navigation.icon: 'lucide:play'
5+
---
6+
7+
`useAnimationControls` provides an imperative way to control animations, allowing you to precisely control when animations start, stop and reset through code.
8+
9+
`useAnimationControls` returns an animation controller with `start`, `stop`, `set` methods.
10+
11+
```vue
12+
<script setup lang="ts">
13+
import { useAnimationControls } from 'motion-v'
14+
15+
const controls = useAnimationControls()
16+
</script>
17+
```
18+
19+
The returned animation controller can be passed to a motion component's `animate` prop to control its animations:
20+
21+
```vue
22+
<Motion :animate="controls" />
23+
```
24+
25+
## Basic Usage
26+
27+
<ComponentPreview name="pan" />
28+
29+
## Methods
30+
31+
### start
32+
33+
Starts an animation with a transition effect. Takes a target state and optional transition config:
34+
35+
```ts
36+
controls.start({ x: 100 })
37+
```
38+
39+
### stop
40+
41+
Stops an animation.
42+
43+
```ts
44+
controls.stop()
45+
```
46+
47+
### set
48+
49+
Sets the animation to a target state without a transition effect.
50+
51+
```ts
52+
controls.set({ x: 100 })
53+
```

docs/nuxt.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export default defineNuxtConfig({
1616
experimental: {
1717
payloadExtraction: false,
1818
},
19+
1920
compatibilityDate: '2024-12-16',
2021
devtools: { enabled: true },
2122
vite: {

docs/public/pug.jpg

55.4 KB
Loading

packages/motion/src/features/gestures/drag/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export interface DragHandlers {
9494
*/
9595
onDragTransitionEnd?: () => void
9696
/**
97-
* If `dragConstraints` is set to a React ref, this callback will call with the measured drag constraints.
97+
* If `dragConstraints` is set to a HTMLElement, this callback will call with the measured drag constraints.
9898
*
9999
* @public
100100
*/

playground/nuxt/pages/pan.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ function template({ rotateY, rotateX }: TransformProperties) {
77
}
88
99
const controls = useAnimationControls()
10-
function handlePan(_: PointerEvent, info: PanInfo) {
10+
function handlePan(e: PointerEvent, info: PanInfo) {
11+
e.preventDefault()
1112
controls.set({
1213
rotateY: info.offset.x / 2,
1314
rotateX: -info.offset.y / 2,
@@ -23,7 +24,7 @@ function handlePanEnd() {
2324
</script>
2425

2526
<template>
26-
<div class="flex flex-col items-center justify-center h-screen">
27+
<div class="flex flex-col items-center justify-center ">
2728
<Motion
2829
class="card"
2930
:transform-template="template"

0 commit comments

Comments
 (0)