web_ppt / frontend /src /views /Editor /MarkupPanel.vue
CatPtain's picture
Upload 339 files
89ce340 verified
raw
history blame
5.51 kB
<template>
<MoveablePanel
class="notes-panel"
:width="300"
:height="130"
title="幻灯片类型标注"
:left="-270"
:top="90"
@close="close()"
>
<div class="container">
<div class="row">
<div style="width: 40%;">当前页面类型:</div>
<Select
style="width: 60%;"
:value="slideType"
@update:value="value => updateSlide(value as SlideType | '')"
:options="slideTypeOptions"
/>
</div>
<div class="row" v-if="handleElement && (handleElement.type === 'text' || (handleElement.type === 'shape' && handleElement.text))">
<div style="width: 40%;">当前文本类型:</div>
<Select
style="width: 60%;"
:value="textType"
@update:value="value => updateElement(value as TextType | '')"
:options="textTypeOptions"
/>
</div>
<div class="row" v-else-if="handleElement && handleElement.type === 'image'">
<div style="width: 40%;">当前图片类型:</div>
<Select
style="width: 60%;"
:value="imageType"
@update:value="value => updateElement(value as ImageType | '')"
:options="imageTypeOptions"
/>
</div>
<div class="placeholder" v-else>选中图片、文字、带文字的形状,标记类型</div>
</div>
</MoveablePanel>
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useMainStore, useSlidesStore } from '@/store'
import type { ImageType, SlideType, TextType } from '@/types/slides'
import MoveablePanel from '@/components/MoveablePanel.vue'
import Select from '@/components/Select.vue'
const slidesStore = useSlidesStore()
const mainStore = useMainStore()
const { currentSlide } = storeToRefs(slidesStore)
const { handleElement, handleElementId } = storeToRefs(mainStore)
const slideTypeOptions = ref<{ label: string; value: SlideType | '' }[]>([
{ label: '未标记类型', value: '' },
{ label: '封面页', value: 'cover' },
{ label: '目录页', value: 'contents' },
{ label: '过渡页', value: 'transition' },
{ label: '内容页', value: 'content' },
{ label: '结束页', value: 'end' },
])
const textTypeOptions = ref<{ label: string; value: TextType | '' }[]>([
{ label: '未标记类型', value: '' },
{ label: '标题', value: 'title' },
{ label: '副标题', value: 'subtitle' },
{ label: '正文', value: 'content' },
{ label: '列表项目', value: 'item' },
{ label: '列表项标题', value: 'itemTitle' },
{ label: '注释', value: 'notes' },
{ label: '页眉', value: 'header' },
{ label: '页脚', value: 'footer' },
{ label: '节编号', value: 'partNumber' },
{ label: '项目编号', value: 'itemNumber' },
])
const imageTypeOptions = ref<{ label: string; value: ImageType | '' }[]>([
{ label: '未标记类型', value: '' },
{ label: '页面插图', value: 'pageFigure' },
{ label: '项目插图', value: 'itemFigure' },
{ label: '背景图', value: 'background' },
])
const slideType = computed(() => currentSlide.value?.type || '')
const textType = computed(() => {
if (!handleElement.value) return ''
if (handleElement.value.type === 'text') return handleElement.value.textType || ''
if (handleElement.value.type === 'shape' && handleElement.value.text) return handleElement.value.text.type || ''
return ''
})
const imageType = computed(() => {
if (!handleElement.value) return ''
if (handleElement.value.type === 'image') return handleElement.value.imageType || ''
return ''
})
const updateSlide = (type: SlideType | '') => {
if (type) slidesStore.updateSlide({ type })
else {
slidesStore.removeSlideProps({
id: currentSlide.value.id,
propName: 'type',
})
}
}
const updateElement = (type: TextType | ImageType | '') => {
if (!handleElement.value) return
if (handleElement.value.type === 'image') {
if (type) {
slidesStore.updateElement({ id: handleElementId.value, props: { imageType: type as ImageType } })
}
else {
slidesStore.removeElementProps({
id: handleElementId.value,
propName: 'imageType',
})
}
}
if (handleElement.value.type === 'text') {
if (type) {
slidesStore.updateElement({ id: handleElementId.value, props: { textType: type as TextType } })
}
else {
slidesStore.removeElementProps({
id: handleElementId.value,
propName: 'textType',
})
}
}
if (handleElement.value.type === 'shape') {
const text = handleElement.value.text
if (!text) return
if (type) {
slidesStore.updateElement({
id: handleElementId.value,
props: { text: { ...text, type: type as TextType } },
})
}
else {
delete text.type
slidesStore.updateElement({
id: handleElementId.value,
props: { text },
})
}
}
}
const close = () => {
mainStore.setMarkupPanelState(false)
}
</script>
<style lang="scss" scoped>
.notes-panel {
height: 100%;
font-size: 12px;
user-select: none;
}
.container {
height: 100%;
display: flex;
flex-direction: column;
}
.row {
width: 100%;
display: flex;
align-items: center;
& + .row {
margin-top: 5px;
}
}
.placeholder {
height: 30px;
line-height: 30px;
text-align: center;
color: #999;
font-style: italic;
border: 1px dashed #ccc;
border-radius: $borderRadius;
margin-top: 5px;
}
</style>