Files
giftBook-web/playground/src/views/examples/motion/index.vue
T
2025-07-22 20:52:01 +08:00

214 lines
6.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts" setup>
import { reactive } from 'vue';
import { Page } from '@vben/common-ui';
import { Motion, MotionGroup, MotionPresets } from '@vben/plugins/motion';
import { refAutoReset, watchDebounced } from '@vueuse/core';
import {
Button,
Card,
Col,
Form,
FormItem,
InputNumber,
Row,
Select,
} from 'ant-design-vue';
// 本例子用不到visible类型的动画。带有VisibleOnce和Visible的类型会在组件进入视口被显示时执行动画,
const presets = MotionPresets.filter((v) => !v.includes('Visible'));
const showCard1 = refAutoReset(true, 100);
const showCard2 = refAutoReset(true, 100);
const showCard3 = refAutoReset(true, 100);
const motionProps = reactive({
delay: 0,
duration: 300,
enter: { scale: 1 },
hovered: { scale: 1.1, transition: { delay: 0, duration: 50 } },
preset: 'fade',
tapped: { scale: 0.9, transition: { delay: 0, duration: 50 } },
});
const motionGroupProps = reactive({
delay: 0,
duration: 300,
enter: { scale: 1 },
hovered: { scale: 1.1, transition: { delay: 0, duration: 50 } },
preset: 'fade',
tapped: { scale: 0.9, transition: { delay: 0, duration: 50 } },
});
watchDebounced(
motionProps,
() => {
showCard2.value = false;
},
{ debounce: 200, deep: true },
);
watchDebounced(
motionGroupProps,
() => {
showCard3.value = false;
},
{ debounce: 200, deep: true },
);
function openDocPage() {
window.open('https://motion.vueuse.org/', '_blank');
}
</script>
<template>
<Page title="Motion">
<template #description>
<span>一个易于使用的为其它组件赋予动画效果的组件</span>
<Button type="link" @click="openDocPage">查看文档</Button>
</template>
<Card title="使用指令" :body-style="{ minHeight: '5rem' }">
<template #extra>
<Button type="primary" @click="showCard1 = false">重载</Button>
</template>
<div>
<div class="relative flex gap-2 overflow-hidden" v-if="showCard1">
<Button v-motion-fade-visible>fade</Button>
<Button v-motion-pop-visible :duration="500">pop</Button>
<Button v-motion-slide-left>slide-left</Button>
<Button v-motion-slide-right>slide-right</Button>
<Button v-motion-slide-bottom>slide-bottom</Button>
<Button v-motion-slide-top>slide-top</Button>
</div>
</div>
</Card>
<Card
class="mt-2"
title="使用组件(将内部作为一个整体添加动画)"
:body-style="{ padding: 0 }"
>
<div
class="relative flex min-h-32 items-center justify-center gap-2 overflow-hidden"
>
<Motion
v-bind="motionProps"
v-if="showCard2"
class="flex items-center gap-2"
>
<Button size="large">这个按钮在显示时会有动画效果</Button>
<span>附属组件会作为整体处理动画</span>
</Motion>
</div>
<div
class="relative flex min-h-32 items-center justify-center gap-2 overflow-hidden"
>
<div v-if="showCard2" class="flex items-center gap-2">
<span>顺序延迟</span>
<Motion
v-bind="{
...motionProps,
delay: motionProps.delay + 100 * i,
}"
v-for="i in 5"
:key="i"
>
<Button size="large">按钮{{ i }}</Button>
</Motion>
</div>
</div>
<div>
<Form :model="motionProps" :label-col="{ span: 10 }">
<Row>
<Col :span="8">
<FormItem prop="preset" label="动画效果">
<Select v-model:value="motionProps.preset">
<Select.Option
:value="preset"
v-for="preset in presets"
:key="preset"
>
{{ preset }}
</Select.Option>
</Select>
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="duration" label="持续时间">
<InputNumber v-model:value="motionProps.duration" />
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="delay" label="延迟动画">
<InputNumber v-model:value="motionProps.delay" />
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="hovered.scale" label="Hover缩放">
<InputNumber v-model:value="motionProps.hovered.scale" />
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="hovered.tapped" label="按下时缩放">
<InputNumber v-model:value="motionProps.tapped.scale" />
</FormItem>
</Col>
</Row>
</Form>
</div>
</Card>
<Card
class="mt-2"
title="分组动画(每个子元素都会应用相同的独立动画)"
:body-style="{ padding: 0 }"
>
<div
class="relative flex min-h-32 items-center justify-center gap-2 overflow-hidden"
>
<MotionGroup v-bind="motionGroupProps" v-if="showCard3">
<Button size="large">按钮1</Button>
<Button size="large">按钮2</Button>
<Button size="large">按钮3</Button>
<Button size="large">按钮4</Button>
<Button size="large">按钮5</Button>
</MotionGroup>
</div>
<div>
<Form :model="motionGroupProps" :label-col="{ span: 10 }">
<Row>
<Col :span="8">
<FormItem prop="preset" label="动画效果">
<Select v-model:value="motionGroupProps.preset">
<Select.Option
:value="preset"
v-for="preset in presets"
:key="preset"
>
{{ preset }}
</Select.Option>
</Select>
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="duration" label="持续时间">
<InputNumber v-model:value="motionGroupProps.duration" />
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="delay" label="延迟动画">
<InputNumber v-model:value="motionGroupProps.delay" />
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="hovered.scale" label="Hover缩放">
<InputNumber v-model:value="motionGroupProps.hovered.scale" />
</FormItem>
</Col>
<Col :span="8">
<FormItem prop="hovered.tapped" label="按下时缩放">
<InputNumber v-model:value="motionGroupProps.tapped.scale" />
</FormItem>
</Col>
</Row>
</Form>
</div>
</Card>
</Page>
</template>