| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- <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 'antdv-next';
- // 本例子用不到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="使用指令" :styles="{ body: { 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="使用组件(将内部作为一个整体添加动画)"
- :styles="{ body: { padding: 0 } }"
- >
- <div class="relative flex-center min-h-32 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-center min-h-32 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"
- :options="presets.map((p) => ({ label: p, value: p }))"
- />
- </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="分组动画(每个子元素都会应用相同的独立动画)"
- :styles="{ body: { padding: 0 } }"
- >
- <div class="relative flex-center min-h-32 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"
- :options="presets.map((p) => ({ label: p, value: p }))"
- />
- </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>
|