This commit is contained in:
pipipi-pikachu 2021-01-04 22:44:14 +08:00
parent 8ae3efc3d4
commit 9c233b0ce8
7 changed files with 217 additions and 14 deletions

View File

@ -34,10 +34,10 @@ export const ANIMATIONS = [
name: '旋转',
children: [
{ name: '旋转进入', value: 'rotateIn' },
{ name: '基于左下旋转进入', value: 'rotateInDownLeft' },
{ name: '基于右下旋转进入', value: 'rotateInDownRight' },
{ name: '基于左上旋转进入', value: 'rotateInUpLeft' },
{ name: '基于右上旋转进入', value: 'rotateInUpRight' },
{ name: '左下旋转进入', value: 'rotateInDownLeft' },
{ name: '右下旋转进入', value: 'rotateInDownRight' },
{ name: '左上旋转进入', value: 'rotateInUpLeft' },
{ name: '右上旋转进入', value: 'rotateInUpRight' },
],
},
{

View File

@ -1,5 +1,14 @@
const DEFAULT_COLOR = '#41464b'
export const ELEMENT_TYPE = {
'text': '文本',
'image': '图片',
'shape': '形状',
'line': '线条',
'chart': '图表',
'table': '表格',
}
export const DEFAULT_TEXT = {
content: '请输入内容',
}

View File

@ -11,13 +11,13 @@
<PictureOutlined class="handler-item" />
</FileInput>
<Popover trigger="click" v-model:visible="isOpenShapePool">
<template v-slot:content>
<template #content>
<ShapePool @select="shape => drawShape(shape)" />
</template>
<StarOutlined class="handler-item" />
</Popover>
<Popover trigger="click" v-model:visible="isOpenlinePool">
<template v-slot:content>
<template #content>
<LinePool @select="line => drawLine(line)" />
</template>
<LineOutlined class="handler-item" />

View File

@ -5,7 +5,7 @@
v-click-outside="() => setThumbnailsFocus(false)"
>
<div class="add-slide" @click="createSlide()">+ 添加幻灯片</div>
<draggable
<Draggable
class="thumbnail-list"
:modelValue="slides"
:animation="300"
@ -27,25 +27,25 @@
</div>
</div>
</template>
</draggable>
</Draggable>
</div>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue'
import draggable from 'vuedraggable'
import { useStore } from 'vuex'
import { State, MutationTypes } from '@/store'
import { fillDigit } from '@/utils/common'
import { ContextmenuItem } from '@/components/Contextmenu/types'
import useSlideHandler from '@/hooks/useSlideHandler'
import Draggable from 'vuedraggable'
import ThumbnailSlide from '@/views/components/ThumbnailSlide/index.vue'
export default defineComponent({
name: 'thumbnails',
components: {
draggable,
Draggable,
ThumbnailSlide,
},
setup() {

View File

@ -1,13 +1,201 @@
<template>
<div class="element-animation-panel">
element-animation-panel
<div class="element-animation">
<Popover trigger="click">
<template #content>
<div class="animation-pool">
<div class="pool-type" v-for="type in animations" :key="type.name">
<div class="type-title">{{type.name}}</div>
<div class="pool-item" v-for="item in type.children" :key="item.name">
<div
:class="[
'box',
'animate__animated',
hoverPreviewAnimation === item.value && `animate__${item.value}`,
]"
@mouseover="hoverPreviewAnimation = item.value"
></div>
<div class="label">{{item.name}}</div>
</div>
</div>
</div>
</template>
<Button class="element-animation-btn">旋转进入</Button>
</Popover>
</div>
<Divider />
<Draggable
class="animation-sequence"
:modelValue="animationSequence"
:animation="300"
:scroll="true"
:scrollSensitivity="50"
itemKey="id"
>
<template #item="{ element, index }">
<div class="sequence-item">
<div class="index">{{index + 1}}</div>
<div class="el-type">{{element.elType}}</div>
<div class="animation-type">{{element.animationType}}</div>
<div class="handler">
<PlayCircleOutlined class="handler-btn" />
<DeleteOutlined class="handler-btn" />
</div>
</div>
</template>
</Draggable>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { computed, defineComponent, ref, Ref } from 'vue'
import { useStore } from 'vuex'
import { State } from '@/store'
import { PPTAnimation, Slide } from '@/types/slides'
import { ANIMATIONS } from '@/configs/animation'
import { ELEMENT_TYPE } from '@/configs/element'
import Draggable from 'vuedraggable'
import { Button, Divider, Popover } from 'ant-design-vue'
import {
PlayCircleOutlined,
DeleteOutlined,
} from '@ant-design/icons-vue'
const animationTypes: { [key: string]: string } = {}
for(const type of ANIMATIONS) {
for(const animation of type.children) {
animationTypes[animation.value] = animation.name
}
}
export default defineComponent({
name: 'element-animation-panel',
components: {
Draggable,
Button,
Divider,
PlayCircleOutlined,
DeleteOutlined,
Popover,
},
setup() {
const store = useStore<State>()
const currentSlideAnimations: Ref<PPTAnimation[] | null> = computed(() => store.getters.currentSlideAnimations)
const currentSlide: Ref<Slide> = computed(() => store.getters.currentSlide)
const hoverPreviewAnimation = ref('')
const animations = ANIMATIONS
const animationSequence = computed(() => {
if(!currentSlideAnimations.value) return []
const animationSequence = []
for(const animation of currentSlideAnimations.value) {
const el = currentSlide.value.elements.find(el => el.id === animation.elId)
if(!el) continue
const elType = ELEMENT_TYPE[el.type]
const animationType = animationTypes[animation.type]
animationSequence.push({
...animation,
elType,
animationType,
})
}
return animationSequence
})
return {
animations,
animationSequence,
hoverPreviewAnimation,
}
},
})
</script>
</script>
<style lang="scss" scoped>
.element-animation-btn {
width: 100%;
}
.animation-pool {
width: 400px;
height: 500px;
overflow-y: auto;
overflow-x: hidden;
font-size: 12px;
}
.pool-type {
@include grid-layout-wrapper();
}
.type-title {
width: 100%;
font-size: 13px;
margin-bottom: 10px;
border-left: 4px solid #aaa;
background-color: #eee;
padding-left: 10px;
}
.pool-item {
@include grid-layout-item(4, 24%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-bottom: 10px;
cursor: pointer;
.box {
width: 30px;
height: 30px;
background-color: #eee;
margin-bottom: 5px;
}
.label {
text-align: center;
}
}
.sequence-item {
height: 32px;
display: flex;
align-items: center;
border: 1px solid #eee;
padding: 6px;
border-radius: $borderRadius;
margin-bottom: 5px;
&:hover {
.animation-type {
display: none;
}
.handler {
display: block;
}
}
.index {
flex: 1;
}
.el-type {
flex: 2;
}
.animation-type {
flex: 3;
text-align: right;
}
.handler {
display: none;
flex: 3;
text-align: right;
}
.handler-btn {
margin-left: 10px;
cursor: pointer;
}
}
</style>

View File

@ -50,6 +50,7 @@
<div class="row">
<div style="flex: 2;">行间距</div>
<Select style="flex: 3;">
<template #suffixIcon><ColumnHeightOutlined /></template>
<SelectOption value="jack">Jack</SelectOption>
<SelectOption value="lucy">Lucy</SelectOption>
<SelectOption value="disabled">Disabled</SelectOption>
@ -59,6 +60,7 @@
<div class="row">
<div style="flex: 2;">字间距</div>
<Select style="flex: 3;">
<template #suffixIcon><ColumnWidthOutlined /></template>
<SelectOption value="jack">Jack</SelectOption>
<SelectOption value="lucy">Lucy</SelectOption>
<SelectOption value="disabled">Disabled</SelectOption>
@ -96,6 +98,8 @@ import {
AlignRightOutlined,
OrderedListOutlined,
UnorderedListOutlined,
ColumnHeightOutlined,
ColumnWidthOutlined,
} from '@ant-design/icons-vue'
export default defineComponent({
@ -120,6 +124,8 @@ export default defineComponent({
AlignRightOutlined,
OrderedListOutlined,
UnorderedListOutlined,
ColumnHeightOutlined,
ColumnWidthOutlined,
},
})
</script>

View File

@ -1,7 +1,7 @@
<template>
<div class="slide-style-panel">
<Popover trigger="click">
<template v-slot:content>
<template #content>
<ColorPicker v-model="color" />
</template>
<button>Hover me</button>