|
|
@@ -1,12 +1,13 @@
|
|
|
<template>
|
|
|
- <el-scrollbar :height="'calc(100vh - 198px)'" class="config pr-10px pl-10px">
|
|
|
+ <el-scrollbar :height="'calc(100vh - 198px)'" class="config">
|
|
|
<el-form label-position="top">
|
|
|
- <div class="title flex justify-between items-center h-28px mb-10px">
|
|
|
- <span class="text-14px">设置动画</span>
|
|
|
- <el-icon class="cursor-pointer" @click.stop="addAnimation">
|
|
|
- <Plus />
|
|
|
- </el-icon>
|
|
|
- </div>
|
|
|
+ <ViewTitle title="设置动画">
|
|
|
+ <template #right>
|
|
|
+ <el-button type="text" @click="addAnimation"
|
|
|
+ ><el-icon class="cursor-pointer" @click.stop="addAnimation"> <Plus /> </el-icon
|
|
|
+ ></el-button>
|
|
|
+ </template>
|
|
|
+ </ViewTitle>
|
|
|
<div v-for="item in data" :key="item.id">
|
|
|
<el-collapse v-model="activeNames">
|
|
|
<el-collapse-item :name="item.id">
|
|
|
@@ -23,98 +24,103 @@
|
|
|
</el-icon>
|
|
|
</div>
|
|
|
</template>
|
|
|
- <el-input v-model="item.name" placeholder="动画名称" class="mt-10px" />
|
|
|
- <div v-for="(animationItem, index) in item.timeline" :key="index" class="mb-20px">
|
|
|
- <div class="mt-10px mb-10px">动画属性</div>
|
|
|
- <div
|
|
|
- class="flex flex-wrap gap-10px mb-10px pb-20px"
|
|
|
- style="border-bottom: 1px solid var(--el-border-color-lighter)"
|
|
|
+ <div class="px-10px">
|
|
|
+ <el-input v-model="item.name" placeholder="动画名称" class="my-10px" />
|
|
|
+ <el-card
|
|
|
+ v-for="(animationItem, index) in item.timeline"
|
|
|
+ :key="index"
|
|
|
+ class="mb-10px relative"
|
|
|
>
|
|
|
- <el-input-number
|
|
|
- v-model="animationItem.start"
|
|
|
- placeholder="开始值"
|
|
|
- :step="0.1"
|
|
|
- :min="0"
|
|
|
- style="flex: 0 0 calc(50% - 5px)"
|
|
|
- />
|
|
|
- <el-input-number
|
|
|
- v-model="animationItem.end"
|
|
|
- placeholder="结束值"
|
|
|
- :step="0.1"
|
|
|
- :min="0"
|
|
|
- style="flex: 0 0 calc(50% - 5px)"
|
|
|
- />
|
|
|
- <el-input-number
|
|
|
- v-model="animationItem.duration"
|
|
|
- placeholder="动画时间"
|
|
|
- :step="0.1"
|
|
|
- :min="0"
|
|
|
- style="flex: 0 0 calc(50% - 5px)"
|
|
|
- />
|
|
|
- <el-input-number
|
|
|
- v-model="animationItem.delay"
|
|
|
- placeholder="延迟时间"
|
|
|
- :step="0.1"
|
|
|
- :min="0"
|
|
|
- style="flex: 0 0 calc(50% - 5px)"
|
|
|
- />
|
|
|
- <el-select
|
|
|
- v-model="animationItem.timingFunction"
|
|
|
- placeholder="动画效果"
|
|
|
- style="flex: 0 0 calc(50% - 5px)"
|
|
|
+ <el-icon
|
|
|
+ class="absolute! right-12px bottom-10px cursor-pointer"
|
|
|
+ @click.stop="handletTimingFunction(item.timeline, 'delete', animationItem)"
|
|
|
>
|
|
|
- <el-option
|
|
|
- v-for="timing in timingFunctions"
|
|
|
- :key="timing.value"
|
|
|
- :value="timing.value"
|
|
|
- :label="timing.label"
|
|
|
+ <Delete />
|
|
|
+ </el-icon>
|
|
|
+ <div class="mt-10px mb-10px flex justify-between items-center">
|
|
|
+ <span>动画属性</span>
|
|
|
+ <el-select
|
|
|
+ style="width: 100px"
|
|
|
+ v-model="animationItem.target"
|
|
|
+ placeholder="目标属性"
|
|
|
+ size="small"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="target in animationTargets"
|
|
|
+ :key="target.value"
|
|
|
+ :value="target.value"
|
|
|
+ :label="target.label"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="flex flex-wrap gap-10px mb-10px pb-20px">
|
|
|
+ <el-input-number
|
|
|
+ v-model="animationItem.start"
|
|
|
+ controls-position="right"
|
|
|
+ placeholder="开始值"
|
|
|
+ :step="0.1"
|
|
|
+ :min="0"
|
|
|
+ style="flex: 0 0 calc(50% - 5px)"
|
|
|
/>
|
|
|
- </el-select>
|
|
|
- <el-select
|
|
|
- v-model="animationItem.iterationCount"
|
|
|
- placeholder="循环次数"
|
|
|
- style="flex: 0 0 calc(50% - 5px)"
|
|
|
- >
|
|
|
- <el-option
|
|
|
- v-for="iteration in iterationCounts"
|
|
|
- :key="iteration.value"
|
|
|
- :value="iteration.value"
|
|
|
- :label="iteration.label"
|
|
|
+ <el-input-number
|
|
|
+ v-model="animationItem.end"
|
|
|
+ controls-position="right"
|
|
|
+ placeholder="结束值"
|
|
|
+ :step="0.1"
|
|
|
+ :min="0"
|
|
|
+ style="flex: 0 0 calc(50% - 5px)"
|
|
|
/>
|
|
|
- </el-select>
|
|
|
- </div>
|
|
|
- <div class="flex justify-between items-center gap-10px">
|
|
|
- <el-select v-model="animationItem.target" placeholder="目标属性">
|
|
|
- <el-option
|
|
|
- v-for="target in animationTargets"
|
|
|
- :key="target.value"
|
|
|
- :value="target.value"
|
|
|
- :label="target.label"
|
|
|
+ <el-input-number
|
|
|
+ v-model="animationItem.duration"
|
|
|
+ controls-position="right"
|
|
|
+ placeholder="动画时间"
|
|
|
+ :step="0.1"
|
|
|
+ :min="0"
|
|
|
+ style="flex: 0 0 calc(50% - 5px)"
|
|
|
/>
|
|
|
- </el-select>
|
|
|
- <el-button
|
|
|
- v-if="index !== item.timeline.length - 1"
|
|
|
- type="info"
|
|
|
- style="flex: 0 0 calc(50% - 5px)"
|
|
|
- @click="handletTimingFunction(item.timeline, 'delete', animationItem)"
|
|
|
- >删除</el-button
|
|
|
- >
|
|
|
+ <el-input-number
|
|
|
+ v-model="animationItem.delay"
|
|
|
+ controls-position="right"
|
|
|
+ placeholder="延迟时间"
|
|
|
+ :step="0.1"
|
|
|
+ :min="0"
|
|
|
+ style="flex: 0 0 calc(50% - 5px)"
|
|
|
+ />
|
|
|
+ <el-select
|
|
|
+ v-model="animationItem.timingFunction"
|
|
|
+ placeholder="动画效果"
|
|
|
+ style="flex: 0 0 calc(50% - 5px)"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="timing in timingFunctions"
|
|
|
+ :key="timing.value"
|
|
|
+ :value="timing.value"
|
|
|
+ :label="timing.label"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <el-select
|
|
|
+ v-model="animationItem.iterationCount"
|
|
|
+ placeholder="循环次数"
|
|
|
+ style="flex: 0 0 calc(50% - 5px)"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="iteration in iterationCounts"
|
|
|
+ :key="iteration.value"
|
|
|
+ :value="iteration.value"
|
|
|
+ :label="iteration.label"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ <div class="flex justify-between items-center gap-10px">
|
|
|
<el-button
|
|
|
- v-if="index === item.timeline.length - 1"
|
|
|
type="primary"
|
|
|
- style="flex: 0 0 calc(50% - 5px)"
|
|
|
+ style="width: 100%"
|
|
|
@click="handletTimingFunction(item.timeline, 'add', '')"
|
|
|
- >添加</el-button
|
|
|
+ >添加属性</el-button
|
|
|
>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <el-button
|
|
|
- v-if="!item.timeline.length"
|
|
|
- type="primary"
|
|
|
- style="width: 100%; margin-top: 10px"
|
|
|
- @click="handletTimingFunction(item.timeline, 'add', '')"
|
|
|
- >添加</el-button
|
|
|
- >
|
|
|
</el-collapse-item>
|
|
|
</el-collapse>
|
|
|
</div>
|
|
|
@@ -123,7 +129,7 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, watch, defineEmits } from 'vue'
|
|
|
+import { ref, watch } from 'vue'
|
|
|
import type { Animation } from '@/types/animation'
|
|
|
import { ArrowRight, Plus, Delete } from '@element-plus/icons-vue'
|
|
|
import { ElMessageBox } from 'element-plus'
|
|
|
@@ -141,11 +147,13 @@ const data = ref<Animation[]>(props.animation || ({} as Animation[]))
|
|
|
watch(data, (val) => emit('update:animation', val))
|
|
|
|
|
|
const addAnimation = () => {
|
|
|
+ const id = v4()
|
|
|
data.value.push({
|
|
|
- id: v4(),
|
|
|
- name: '',
|
|
|
+ id,
|
|
|
+ name: `animation_${data.value.length + 1}`,
|
|
|
timeline: []
|
|
|
})
|
|
|
+ activeNames.value.push(id)
|
|
|
}
|
|
|
|
|
|
const handleAnimationRemove = (animation) => {
|
|
|
@@ -165,12 +173,12 @@ const handletTimingFunction = (timeline, name, animationItem) => {
|
|
|
if (name === 'add') {
|
|
|
timeline.push({
|
|
|
target: '',
|
|
|
- start: 0,
|
|
|
- end: 0,
|
|
|
- delay: 0,
|
|
|
- duration: 0,
|
|
|
+ start: undefined,
|
|
|
+ end: undefined,
|
|
|
+ delay: undefined,
|
|
|
+ duration: undefined,
|
|
|
timingFunction: '',
|
|
|
- iterationCount: 0
|
|
|
+ iterationCount: undefined
|
|
|
})
|
|
|
} else {
|
|
|
const index = timeline.findIndex((item) => item.id === animationItem.id)
|
|
|
@@ -195,6 +203,8 @@ const handletTimingFunction = (timeline, name, animationItem) => {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
width: 100%;
|
|
|
+ padding: 0 12px;
|
|
|
+ box-sizing: border-box;
|
|
|
}
|
|
|
|
|
|
.arrow {
|