123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 |
- <template>
- <div class="animations">
- <template v-if="props.pen.animations.length">
- <t-collapse
- v-model="openedCollapses"
- :borderless="true"
- :expand-on-row-click="true"
- >
- <t-collapse-panel v-for="(item, i) in props.pen.animations" :value="i">
- <template #header>
- <div class="flex middle" @click.stop>
- <t-input v-model="item.name" autoWidth class="mr-8" />
- <t-icon
- v-if="isPlaying === i"
- name="stop-circle-1"
- class="hover primary"
- style="font-size: 16px"
- @click="stop"
- />
- <t-icon
- v-else
- name="play-circle"
- class="hover"
- style="font-size: 16px"
- @click="play(i)"
- />
- </div>
- </template>
- <template #headerRightContent>
- <t-space size="small" @click.stop>
- <t-icon
- v-if="!props.pen.type && item.animate"
- name="edit"
- class="hover mr-4"
- @click="animate = item"
- />
- <t-popconfirm
- content="确认删除该动画吗"
- placement="left"
- @confirm="
- props.pen.animations.splice(i, 1);
- animate = undefined;
- "
- >
- <t-icon name="delete" class="hover" />
- </t-popconfirm>
- </t-space>
- </template>
- <template v-if="props.pen.type">
- <div class="form-item">
- <label>动画类型</label>
- <t-select v-model="item.lineAnimateType" placeholder="水流">
- <t-option :key="0" :value="0" label="水流" />
- <t-option :key="1" :value="1" label="水珠" />
- <t-option :key="2" :value="2" label="圆点" />
- </t-select>
- </div>
- <div class="form-item mt-8">
- <label>运动速度</label>
- <t-slider
- class="ml-12"
- v-model="item.animateSpan"
- :show-tooltip="true"
- :min="1"
- :max="10"
- />
- </div>
- <div class="form-item mt-8">
- <label>动画颜色</label>
- <t-color-picker
- class="w-full"
- format="CSS"
- :enable-alpha="true"
- :color-modes="['monochrome']"
- :show-primary-color-preview="false"
- :clearable="true"
- v-model="item.animateColor"
- />
- </div>
- <div class="form-item mt-8">
- <label>轨迹宽度</label>
- <t-input-number
- v-model="item.animateLineWidth"
- theme="column"
- :min="1"
- placeholder="默认"
- />
- </div>
- <div class="form-item mt-8">
- <label>反向流动</label>
- <t-switch
- class="ml-8 mt-8"
- size="small"
- v-model="item.animateReverse"
- />
- </div>
- <div class="form-item mt-8">
- <label>播放次数</label>
- <t-input-number
- v-model="item.animateCycle"
- theme="column"
- :min="1"
- placeholder="无限"
- title="缺省无限循环播放"
- />
- </div>
- <div class="form-item mt-8">
- <label>自动播放</label>
- <t-switch
- class="ml-8 mt-8"
- size="small"
- v-model="item.autoPlay"
- />
- </div>
- <div
- class="form-item mt-8"
- title="当前动画结束后自动播放下一个对象的动画"
- >
- <label>下个动画</label>
- <t-tree-select
- v-model="item.nextAnimate"
- :data="penTree"
- filterable
- placeholder="无"
- />
- </div>
- </template>
- <template v-else>
- <div class="form-item">
- <label>动画类型</label>
- <t-select
- v-model="item.animate"
- clearable
- placeholder="动画"
- :options="animateList"
- @change="changeAnimate(item)"
- />
- </div>
- <div class="form-item mt-8">
- <label>播放次数</label>
- <t-input-number
- v-model="item.animateCycle"
- theme="column"
- :min="1"
- placeholder="无限"
- title="缺省无限循环播放"
- />
- </div>
- <div class="form-item mt-8">
- <label>结束状态</label>
- <t-select
- v-model="item.keepanimationstate"
- placeholder="初始状态"
- >
- <t-option :key="false" :value="false" label="初始状态" />
- <t-option :key="true" :value="true" label="当前状态" />
- </t-select>
- </div>
- <div class="form-item mt-8">
- <label>线性播放</label>
- <t-tooltip content="仅支持数字属性匀速线性播放" placement="top">
- <t-select v-model="item.linear" placeholder="是">
- <t-option :key="true" :value="true" label="是" />
- <t-option :key="false" :value="false" label="否" />
- </t-select>
- </t-tooltip>
- </div>
- <div class="form-item mt-8">
- <label>自动播放</label>
- <t-switch
- class="ml-8 mt-8"
- size="small"
- v-model="item.autoPlay"
- @change="changeAnimateAutoPlay($event,item)"
- />
- </div>
- <div
- class="form-item mt-8"
- title="当前动画结束后自动播放下一个对象的动画"
- >
- <label>下个动画</label>
- <t-tree-select
- v-model="item.nextAnimate"
- :data="penTree"
- filterable
- placeholder="无"
- />
- </div>
- </template>
- </t-collapse-panel>
- </t-collapse>
- <t-divider />
- <div class="p-16">
- <t-button class="w-full" @click="addAnimate" style="height: 30px">
- 添加动画
- </t-button>
- </div>
- </template>
- <div class="flex column center blank" v-else>
- <img src="/img/blank.png" />
- <div class="gray center">还没有动画</div>
- <div class="mt-8">
- <t-button @click="addAnimate" style="height: 30px">添加动画</t-button>
- </div>
- </div>
- </div>
- <AnimateFrames
- v-if="animate"
- :animate="animate"
- @close="animate = undefined"
- />
- </template>
- <script lang="ts" setup>
- import { onBeforeMount, ref, watch, onUnmounted } from 'vue';
- import { getPenTree } from '@/services/common';
- import { deepClone } from '@meta2d/core';
- import AnimateFrames from './AnimateFrames.vue';
- const props = defineProps<{
- pen: any;
- }>();
- function changeAnimateAutoPlay(value,item) {
- props.pen.animations.forEach(i=>{
- if(i.name !== item.name){
- i.autoPlay = false
- }
- })
- item.autoPlay = true
- }
- const penTree: any = ref([]);
- const openedCollapses = ref([0]);
- const animate: any = ref(undefined);
- const animateList = [
- {
- label: '闪烁',
- value: '闪烁',
- data: [
- {
- visible: true,
- duration: 100,
- },
- {
- visible: false,
- duration: 100,
- },
- ],
- },
- {
- label: '缩放',
- value: '缩放',
- data: [
- {
- scale: 1.1,
- duration: 100,
- },
- {
- scale: 1,
- duration: 400,
- },
- ],
- },
- {
- label: '旋转',
- value: '旋转',
- data: [
- {
- rotate: 360,
- duration: 1000,
- },
- ],
- },
- {
- label: '上下跳动',
- value: '上下跳动',
- data: [
- {
- y: -10,
- duration: 100,
- },
- { y: 0, duration: 100 },
- { y: -10, duration: 200 },
- ],
- },
- {
- label: '左右跳动',
- value: '左右跳动',
- data: [
- {
- x: -10,
- duration: 100,
- },
- {
- x: 10,
- duration: 80,
- },
- {
- x: -10,
- duration: 50,
- },
- {
- x: 10,
- duration: 30,
- },
- {
- x: 0,
- duration: 300,
- },
- ],
- },
- {
- label: '颜色变化',
- value: '颜色变化',
- data: [
- { color: '#4583ff', duration: 200 },
- { color: '#ff4000', duration: 200 },
- ],
- },
- {
- label: '背景变化',
- value: '背景变化',
- data: [
- { background: '#4583ff', duration: 200 },
- { background: '#ff4000', duration: 200 },
- ],
- },
- {
- label: '文字变化',
- value: '文字变化',
- data: [
- { text: '乐吾乐', duration: 200 },
- { text: 'le5le', duration: 200 },
- ],
- },
- {
- label: '状态变化',
- value: '状态变化',
- data: [
- { showChild: 0, duration: 200 },
- { showChild: 1, duration: 200 },
- ],
- },
- {
- label: '翻转',
- value: '翻转',
- data: [
- { flipX: true, flipY: true, duration: 200 },
- { flipX: false, flipY: false, duration: 200 },
- ],
- },
- {
- label: '自定义',
- value: 'custom',
- data: [],
- },
- ];
- const isPlaying = ref(-1);
- onBeforeMount(() => {
- if (!props.pen.animations) {
- props.pen.animations = [];
- }
- const p = meta2d.findOne(props.pen.id);
- if (p?.calculative?.start) {
- // @ts-ignore
- isPlaying.value = p?.currentAnimation;
- }
- penTree.value = getPenTree();
- });
- const watcher = watch(
- () => props.pen.id,
- () => {
- const p = meta2d.findOne(props.pen.id);
- if (p?.calculative?.start) {
- // @ts-ignore
- isPlaying.value = p?.currentAnimation;
- } else {
- isPlaying.value = -1;
- }
- }
- );
- const addAnimate = () => {
- openedCollapses.value.push(props.pen.animations.length);
- props.pen.animations.push({
- name: '动画' + (props.pen.animations.length + 1),
- });
- };
- const changeAnimate = (item: any) => {
- const animate: any = animateList.find((elem: any) => {
- return elem.value === item.animate;
- });
- if (!animate) {
- return;
- }
- item.frames = deepClone(animate.data);
- };
- const play = (i: number) => {
- meta2d.startAnimate(props.pen.id, i);
- isPlaying.value = i;
- };
- const stop = () => {
- meta2d.stopAnimate(props.pen.id);
- isPlaying.value = -1;
- };
- onUnmounted(() => {
- watcher();
- });
- </script>
- <style lang="postcss" scoped>
- .animations {
- height: 100%;
- .blank {
- height: 70%;
- img {
- padding: 16px;
- opacity: 0.9;
- }
- }
- :deep(.t-collapse) {
- .t-collapse-panel__header {
- .t-input {
- border-color: transparent;
- &:hover {
- border-color: var(--color-border-input);
- }
- }
- }
- .t-collapse-panel__icon:hover {
- background: none;
- svg {
- color: var(--color-primary);
- }
- }
- }
- }
- </style>
|