feat: 添加导出配置弹窗、添加导出配置(#104 #105)

This commit is contained in:
pipipi-pikachu 2022-05-22 16:54:07 +08:00
parent 4de6d5234e
commit 4bbc938fcf
10 changed files with 465 additions and 97 deletions

View File

@ -6,7 +6,7 @@ import pptxgen from 'pptxgenjs'
import tinycolor from 'tinycolor2' import tinycolor from 'tinycolor2'
import { toPng, toJpeg } from 'html-to-image' import { toPng, toJpeg } from 'html-to-image'
import { useSlidesStore } from '@/store' import { useSlidesStore } from '@/store'
import { PPTElementOutline, PPTElementShadow, PPTElementLink } from '@/types/slides' import { PPTElementOutline, PPTElementShadow, PPTElementLink, Slide } from '@/types/slides'
import { getElementRange, getLineElementPath, getTableSubThemeColor } from '@/utils/element' import { getElementRange, getLineElementPath, getTableSubThemeColor } from '@/utils/element'
import { AST, toAST } from '@/utils/htmlParser' import { AST, toAST } from '@/utils/htmlParser'
import { SvgPoints, toPoints } from '@/utils/svgPathParser' import { SvgPoints, toPoints } from '@/utils/svgPathParser'
@ -331,7 +331,7 @@ export default () => {
} }
// 导出PPTX文件 // 导出PPTX文件
const exportPPTX = () => { const exportPPTX = (_slides: Slide[] = slides.value) => {
exporting.value = true exporting.value = true
const pptx = new pptxgen() const pptx = new pptxgen()
@ -341,7 +341,7 @@ export default () => {
background: { color: bgColor, transparency: (1 - bgAlpha) * 100 }, background: { color: bgColor, transparency: (1 - bgAlpha) * 100 },
}) })
for (const slide of slides.value) { for (const slide of _slides) {
const pptxSlide = pptx.addSlide() const pptxSlide = pptx.addSlide()
if (slide.background) { if (slide.background) {

View File

@ -1,12 +1,15 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { CreatingElement } from '@/types/edit' import { CreatingElement } from '@/types/edit'
import { ToolbarStates } from '@/types/toolbar' import { ToolbarStates } from '@/types/toolbar'
import { DialogForExportTypes } from '@/types/export'
import { SYS_FONTS } from '@/configs/font' import { SYS_FONTS } from '@/configs/font'
import { TextAttrs, defaultRichTextAttrs } from '@/utils/prosemirror/utils' import { TextAttrs, defaultRichTextAttrs } from '@/utils/prosemirror/utils'
import { isSupportFont } from '@/utils/font' import { isSupportFont } from '@/utils/font'
import { useSlidesStore } from './slides' import { useSlidesStore } from './slides'
export interface MainState { export interface MainState {
activeElementIdList: string[]; activeElementIdList: string[];
handleElementId: string; handleElementId: string;
@ -27,6 +30,7 @@ export interface MainState {
richTextAttrs: TextAttrs; richTextAttrs: TextAttrs;
selectedTableCells: string[]; selectedTableCells: string[];
selectedSlidesIndex: number[]; selectedSlidesIndex: number[];
dialogForExport: DialogForExportTypes;
} }
export const useMainStore = defineStore('main', { export const useMainStore = defineStore('main', {
@ -50,6 +54,7 @@ export const useMainStore = defineStore('main', {
selectedTableCells: [], // 选中的表格单元格 selectedTableCells: [], // 选中的表格单元格
isScaling: false, // 正在进行元素缩放 isScaling: false, // 正在进行元素缩放
selectedSlidesIndex: [], // 当前被选中的页面索引集合 selectedSlidesIndex: [], // 当前被选中的页面索引集合
dialogForExport: '', // 导出面板
}), }),
getters: { getters: {
@ -147,5 +152,9 @@ export const useMainStore = defineStore('main', {
updateSelectedSlidesIndex(selectedSlidesIndex: number[]) { updateSelectedSlidesIndex(selectedSlidesIndex: number[]) {
this.selectedSlidesIndex = selectedSlidesIndex this.selectedSlidesIndex = selectedSlidesIndex
}, },
setDialogForExport(type: DialogForExportTypes) {
this.dialogForExport = type
},
}, },
}) })

1
src/types/export.ts Normal file
View File

@ -0,0 +1 @@
export type DialogForExportTypes = 'image' | 'pdf' | 'json' | 'pptx' | ''

View File

@ -5,10 +5,10 @@
<div class="menu-item"><IconFolderClose /> <span class="text">文件</span></div> <div class="menu-item"><IconFolderClose /> <span class="text">文件</span></div>
<template #overlay> <template #overlay>
<Menu> <Menu>
<MenuItem @click="exportJSON()">导出 JSON</MenuItem> <MenuItem @click="setDialogForExport('json')">导出 JSON</MenuItem>
<MenuItem @click="exportPPTX()">导出 PPTX</MenuItem> <MenuItem @click="setDialogForExport('pptx')">导出 PPTX</MenuItem>
<MenuItem @click="exportImgDialogVisible = true">导出图片</MenuItem> <MenuItem @click="setDialogForExport('image')">导出图片</MenuItem>
<MenuItem @click="exportPDFDialogVisible = true">打印 / 导出 PDF</MenuItem> <MenuItem @click="setDialogForExport('pdf')">打印 / 导出 PDF</MenuItem>
</Menu> </Menu>
</template> </template>
</Dropdown> </Dropdown>
@ -65,30 +65,6 @@
> >
<HotkeyDoc /> <HotkeyDoc />
</Drawer> </Drawer>
<Modal
v-model:visible="exportImgDialogVisible"
:footer="null"
centered
:closable="false"
:width="680"
destroyOnClose
>
<ExportImgDialog @close="exportImgDialogVisible = false"/>
</Modal>
<Modal
v-model:visible="exportPDFDialogVisible"
:footer="null"
centered
:closable="false"
:width="680"
destroyOnClose
>
<ExportPDFDialog @close="exportPDFDialogVisible = false"/>
</Modal>
<FullscreenSpin :loading="exporting" tip="正在导出..." />
</div> </div>
</template> </template>
@ -102,15 +78,11 @@ import useHistorySnapshot from '@/hooks/useHistorySnapshot'
import useExport from '@/hooks/useExport' import useExport from '@/hooks/useExport'
import HotkeyDoc from './HotkeyDoc.vue' import HotkeyDoc from './HotkeyDoc.vue'
import ExportImgDialog from './ExportImgDialog.vue'
import ExportPDFDialog from './ExportPDFDialog.vue'
export default defineComponent({ export default defineComponent({
name: 'editor-header', name: 'editor-header',
components: { components: {
HotkeyDoc, HotkeyDoc,
ExportImgDialog,
ExportPDFDialog,
}, },
setup() { setup() {
const mainStore = useMainStore() const mainStore = useMainStore()
@ -121,6 +93,8 @@ export default defineComponent({
const { redo, undo } = useHistorySnapshot() const { redo, undo } = useHistorySnapshot()
const { exporting, exportJSON, exportPPTX } = useExport() const { exporting, exportJSON, exportPPTX } = useExport()
const setDialogForExport = mainStore.setDialogForExport
const toggleGridLines = () => { const toggleGridLines = () => {
mainStore.setGridLinesState(!showGridLines.value) mainStore.setGridLinesState(!showGridLines.value)
} }
@ -130,8 +104,6 @@ export default defineComponent({
} }
const hotkeyDrawerVisible = ref(false) const hotkeyDrawerVisible = ref(false)
const exportImgDialogVisible = ref(false)
const exportPDFDialogVisible = ref(false)
const goIssues = () => { const goIssues = () => {
window.open('https://github.com/pipipi-pikachu/PPTist/issues') window.open('https://github.com/pipipi-pikachu/PPTist/issues')
@ -143,9 +115,8 @@ export default defineComponent({
showGridLines, showGridLines,
showRuler, showRuler,
hotkeyDrawerVisible, hotkeyDrawerVisible,
exportImgDialogVisible,
exportPDFDialogVisible,
exporting, exporting,
setDialogForExport,
enterScreening, enterScreening,
enterScreeningFromStart, enterScreeningFromStart,
createSlide, createSlide,

View File

@ -4,7 +4,7 @@
<div class="thumbnails" ref="imageThumbnailsRef"> <div class="thumbnails" ref="imageThumbnailsRef">
<ThumbnailSlide <ThumbnailSlide
class="thumbnail" class="thumbnail"
v-for="slide in slides" v-for="slide in renderSlides"
:key="slide.id" :key="slide.id"
:slide="slide" :slide="slide"
:size="1600" :size="1600"
@ -18,10 +18,32 @@
class="config-item" class="config-item"
v-model:value="format" v-model:value="format"
> >
<RadioButton value="jpeg">JPEG</RadioButton> <RadioButton style="width: 50%;" value="jpeg">JPEG</RadioButton>
<RadioButton value="png">PNG</RadioButton> <RadioButton style="width: 50%;" value="png">PNG</RadioButton>
</RadioGroup> </RadioGroup>
</div> </div>
<div class="row">
<div class="title">导出范围</div>
<RadioGroup
class="config-item"
v-model:value="rangeType"
>
<RadioButton style="width: 33.33%;" value="all">全部</RadioButton>
<RadioButton style="width: 33.33%;" value="current">当前页</RadioButton>
<RadioButton style="width: 33.33%;" value="custom">自定义</RadioButton>
</RadioGroup>
</div>
<div class="row" v-if="rangeType === 'custom'">
<div class="title" :data-range="`${range[0]} ~ ${range[1]}`">自定义范围</div>
<Slider
class="config-item"
range
:min="1"
:max="slides.length"
:step="1"
v-model:value="range"
/>
</div>
<div class="row"> <div class="row">
<div class="title">图片质量</div> <div class="title">图片质量</div>
@ -37,26 +59,24 @@
<div class="row"> <div class="row">
<div class="title">忽略在线字体</div> <div class="title">忽略在线字体</div>
<div class="config-item"> <div class="config-item">
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="导出时默认忽略在线字体,若您在幻灯片中使用了在线字体,且希望导出后保留相关样式,可选择关闭【忽略在线字体】选项,但要注意这将会增加导出用时。">
<Switch v-model:checked="ignoreWebfont" /> <Switch v-model:checked="ignoreWebfont" />
</Tooltip>
</div> </div>
</div> </div>
<div class="tip">
提示导出时默认会忽略在线字体若您在幻灯片中使用了在线字体且不希望导出图片中丢失相关样式可以选择关闭忽略在线字体选项但要注意这将会导致导出用时大幅度增加
</div> </div>
<div class="btns"> <div class="btns">
<Button class="btn export" type="primary" @click="expImage()">导出图片</Button> <Button class="btn export" type="primary" @click="expImage()">导出图片</Button>
<Button class="btn close" @click="close()">关闭</Button> <Button class="btn close" @click="close()">关闭</Button>
</div> </div>
</div>
<FullscreenSpin :loading="exporting" tip="正在导出..." /> <FullscreenSpin :loading="exporting" tip="正在导出..." />
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, ref } from 'vue' import { computed, defineComponent, ref } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store' import { useSlidesStore } from '@/store'
import useExport from '@/hooks/useExport' import useExport from '@/hooks/useExport'
@ -69,13 +89,24 @@ export default defineComponent({
ThumbnailSlide, ThumbnailSlide,
}, },
setup(props, { emit }) { setup(props, { emit }) {
const { slides } = storeToRefs(useSlidesStore()) const { slides, currentSlide } = storeToRefs(useSlidesStore())
const imageThumbnailsRef = ref<HTMLElement>() const imageThumbnailsRef = ref<HTMLElement>()
const rangeType = ref<'all' | 'current' | 'custom'>('all')
const range = ref<[number, number]>([1, slides.value.length])
const format = ref<'jpeg' | 'png'>('jpeg') const format = ref<'jpeg' | 'png'>('jpeg')
const quality = ref(1) const quality = ref(1)
const ignoreWebfont = ref(true) const ignoreWebfont = ref(true)
const renderSlides = computed(() => {
if (rangeType.value === 'all') return slides.value
if (rangeType.value === 'current') return [currentSlide.value]
return slides.value.filter((item, index) => {
const [min, max] = range.value
return index >= min - 1 && index <= max - 1
})
})
const close = () => emit('close') const close = () => emit('close')
const { exportImage, exporting } = useExport() const { exportImage, exporting } = useExport()
@ -88,9 +119,12 @@ export default defineComponent({
return { return {
imageThumbnailsRef, imageThumbnailsRef,
slides, slides,
rangeType,
range,
format, format,
quality, quality,
ignoreWebfont, ignoreWebfont,
renderSlides,
exporting, exporting,
expImage, expImage,
close, close,
@ -101,9 +135,11 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
.export-img-dialog { .export-img-dialog {
height: 500px; height: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center;
flex-direction: column;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
@ -117,7 +153,8 @@ export default defineComponent({
} }
} }
.configs { .configs {
width: 300px; width: 350px;
height: calc(100% - 100px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
@ -132,22 +169,25 @@ export default defineComponent({
.title { .title {
width: 100px; width: 100px;
position: relative;
&::after {
content: attr(data-range);
position: absolute;
top: 20px;
left: 0;
}
} }
.config-item { .config-item {
flex: 1; flex: 1;
} }
.tip {
font-size: 12px;
color: #aaa;
line-height: 1.8;
} }
.btns { .btns {
width: 300px;
height: 100px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin-top: 40px;
.export { .export {
flex: 1; flex: 1;
@ -157,5 +197,4 @@ export default defineComponent({
margin-left: 10px; margin-left: 10px;
} }
} }
}
</style> </style>

View File

@ -0,0 +1,80 @@
<template>
<div class="export-json-dialog">
<div class="preview">
<pre>{{slides}}</pre>
</div>
<div class="btns">
<Button class="btn export" type="primary" @click="exportJSON()">导出 JSON</Button>
<Button class="btn close" @click="close()">关闭</Button>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
import useExport from '@/hooks/useExport'
export default defineComponent({
name: 'export-json-dialog',
setup(props, { emit }) {
const close = () => emit('close')
const { slides } = storeToRefs(useSlidesStore())
const { exportJSON } = useExport()
return {
slides,
exportJSON,
close,
}
},
})
</script>
<style lang="scss" scoped>
.export-json-dialog {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: relative;
overflow: hidden;
}
.preview {
width: calc(100% - 20px);
height: calc(100% - 100px);
display: flex;
flex-direction: column;
justify-content: center;
background-color: #2d2d30;
color: #fff;
}
.btns {
width: 300px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
.export {
flex: 1;
}
.close {
width: 100px;
margin-left: 10px;
}
}
::-webkit-scrollbar {
width: 10px;
height: 10px;
background-color: #2d2d30;
}
::-webkit-scrollbar-thumb {
background-color: #777;
}
</style>

View File

@ -6,7 +6,7 @@
class="thumbnail" class="thumbnail"
:slide="currentSlide" :slide="currentSlide"
:size="1600" :size="1600"
v-if="range === 'current'" v-if="rangeType === 'current'"
/> />
<template v-else> <template v-else>
<ThumbnailSlide <ThumbnailSlide
@ -25,7 +25,7 @@
<div class="title">导出范围</div> <div class="title">导出范围</div>
<RadioGroup <RadioGroup
class="config-item" class="config-item"
v-model:value="range" v-model:value="rangeType"
> >
<RadioButton style="width: 50%;" value="all">全部幻灯片</RadioButton> <RadioButton style="width: 50%;" value="all">全部幻灯片</RadioButton>
<RadioButton style="width: 50%;" value="current">当前幻灯片</RadioButton> <RadioButton style="width: 50%;" value="current">当前幻灯片</RadioButton>
@ -48,13 +48,13 @@
<Switch v-model:checked="padding" /> <Switch v-model:checked="padding" />
</div> </div>
</div> </div>
</div>
<div class="btns"> <div class="btns">
<Button class="btn export" type="primary" @click="expPDF()">打印 / 导出 PDF</Button> <Button class="btn export" type="primary" @click="expPDF()">打印 / 导出 PDF</Button>
<Button class="btn close" @click="close()">关闭</Button> <Button class="btn close" @click="close()">关闭</Button>
</div> </div>
</div> </div>
</div>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -74,7 +74,7 @@ export default defineComponent({
const { slides, currentSlide } = storeToRefs(useSlidesStore()) const { slides, currentSlide } = storeToRefs(useSlidesStore())
const pdfThumbnailsRef = ref<HTMLElement>() const pdfThumbnailsRef = ref<HTMLElement>()
const range = ref<'all' | 'current'>('all') const rangeType = ref<'all' | 'current'>('all')
const count = ref(1) const count = ref(1)
const padding = ref(true) const padding = ref(true)
@ -84,7 +84,7 @@ export default defineComponent({
if (!pdfThumbnailsRef.value) return if (!pdfThumbnailsRef.value) return
const pageSize = { const pageSize = {
width: 1600, width: 1600,
height: range.value === 'all' ? 900 * count.value : 900, height: rangeType.value === 'all' ? 900 * count.value : 900,
margin: padding.value ? 50 : 0, margin: padding.value ? 50 : 0,
} }
print(pdfThumbnailsRef.value, pageSize) print(pdfThumbnailsRef.value, pageSize)
@ -94,7 +94,7 @@ export default defineComponent({
pdfThumbnailsRef, pdfThumbnailsRef,
slides, slides,
currentSlide, currentSlide,
range, rangeType,
count, count,
padding, padding,
expPDF, expPDF,
@ -106,9 +106,11 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
.export-pdf-dialog { .export-pdf-dialog {
height: 400px; height: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center;
flex-direction: column;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
@ -128,6 +130,7 @@ export default defineComponent({
} }
.configs { .configs {
width: 300px; width: 300px;
height: calc(100% - 100px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
@ -146,12 +149,13 @@ export default defineComponent({
.config-item { .config-item {
flex: 1; flex: 1;
} }
}
.btns { .btns {
width: 300px;
height: 100px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin-top: 40px;
.export { .export {
flex: 1; flex: 1;
@ -161,5 +165,4 @@ export default defineComponent({
margin-left: 10px; margin-left: 10px;
} }
} }
}
</style> </style>

View File

@ -0,0 +1,136 @@
<template>
<div class="export-pptx-dialog">
<div class="configs">
<div class="row">
<div class="title">导出范围</div>
<RadioGroup
class="config-item"
v-model:value="rangeType"
>
<RadioButton style="width: 33.33%;" value="all">全部</RadioButton>
<RadioButton style="width: 33.33%;" value="current">当前页</RadioButton>
<RadioButton style="width: 33.33%;" value="custom">自定义</RadioButton>
</RadioGroup>
</div>
<div class="row" v-if="rangeType === 'custom'">
<div class="title" :data-range="`${range[0]} ~ ${range[1]}`">自定义范围</div>
<Slider
class="config-item"
range
:min="1"
:max="slides.length"
:step="1"
v-model:value="range"
/>
</div>
</div>
<div class="btns">
<Button class="btn export" type="primary" @click="exportPPTX(selectedSlides)">导出 PPTX</Button>
<Button class="btn close" @click="close()">关闭</Button>
</div>
<FullscreenSpin :loading="exporting" tip="正在导出..." />
</div>
</template>
<script lang="ts">
import { computed, defineComponent, ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
import useExport from '@/hooks/useExport'
export default defineComponent({
name: 'export-pptx-dialog',
setup(props, { emit }) {
const { slides, currentSlide } = storeToRefs(useSlidesStore())
const rangeType = ref<'all' | 'current' | 'custom'>('all')
const range = ref<[number, number]>([1, slides.value.length])
const selectedSlides = computed(() => {
if (rangeType.value === 'all') return slides.value
if (rangeType.value === 'current') return [currentSlide.value]
return slides.value.filter((item, index) => {
const [min, max] = range.value
return index >= min - 1 && index <= max - 1
})
})
const close = () => emit('close')
const { exportPPTX, exporting } = useExport()
return {
slides,
rangeType,
range,
exporting,
selectedSlides,
exportPPTX,
close,
}
},
})
</script>
<style lang="scss" scoped>
.export-pptx-dialog {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: relative;
overflow: hidden;
}
.configs {
width: 350px;
height: calc(100% - 100px);
display: flex;
flex-direction: column;
justify-content: center;
.row {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 25px;
}
.title {
width: 100px;
position: relative;
&::after {
content: attr(data-range);
position: absolute;
top: 20px;
left: 0;
}
}
.config-item {
flex: 1;
}
.tip {
font-size: 12px;
color: #aaa;
line-height: 1.8;
}
}
.btns {
width: 300px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
.export {
flex: 1;
}
.close {
width: 100px;
margin-left: 10px;
}
}
</style>

View File

@ -0,0 +1,108 @@
<template>
<div class="export-dialog">
<div class="tabs">
<div
class="tab"
:class="{ 'active': tab.key === dialogForExport }"
v-for="tab in tabs"
:key="tab.key"
@click="setDialogForExport(tab.key)"
>{{tab.label}}</div>
</div>
<div class="content">
<component :is="currentDialogComponent" @close="setDialogForExport('')"></component>
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent } from 'vue'
import { storeToRefs } from 'pinia'
import { useMainStore } from '@/store'
import { DialogForExportTypes } from '@/types/export'
import ExportImage from './ExportImage.vue'
import ExportJSON from './ExportJSON.vue'
import ExportPDF from './ExportPDF.vue'
import ExportPPTX from './ExportPPTX.vue'
interface TabItem {
key: DialogForExportTypes;
label: string;
}
export default defineComponent({
name: 'export-dialog',
setup() {
const mainStore = useMainStore()
const { dialogForExport } = storeToRefs(mainStore)
const setDialogForExport = mainStore.setDialogForExport
const tabs: TabItem[] = [
{ key: 'pptx', label: '导出 PPTX' },
{ key: 'image', label: '导出图片' },
{ key: 'json', label: '导出 JSON' },
{ key: 'pdf', label: '打印 / 导出 PDF' },
]
const currentDialogComponent = computed(() => {
const dialogMap = {
'image': ExportImage,
'json': ExportJSON,
'pdf': ExportPDF,
'pptx': ExportPPTX,
}
return dialogMap[dialogForExport.value] || null
})
return {
currentDialogComponent,
tabs,
dialogForExport,
setDialogForExport,
}
},
})
</script>
<style lang="scss" scoped>
.export-dialog {
margin: -24px;
}
.tabs {
height: 50px;
font-size: 12px;
flex-shrink: 0;
display: flex;
user-select: none;
border-top-left-radius: $borderRadius;
border-top-right-radius: $borderRadius;
overflow: hidden;
}
.tab {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
background-color: $lightGray;
border-bottom: 1px solid $borderColor;
cursor: pointer;
&.active {
background-color: #fff;
border-bottom-color: #fff;
}
& + .tab {
border-left: 1px solid $borderColor;
}
}
.content {
height: 500px;
padding: 12px;
font-size: 13px;
@include overflow-overlay();
}
</style>

View File

@ -15,11 +15,24 @@
<Toolbar class="layout-content-right" /> <Toolbar class="layout-content-right" />
</div> </div>
</div> </div>
<Modal
:visible="!!dialogForExport"
:footer="null"
centered
:closable="false"
:width="680"
destroyOnClose
@cancel="closeExportDialog()"
>
<ExportDialog />
</Modal>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, ref } from 'vue' import { defineComponent, ref } from 'vue'
import { storeToRefs } from 'pinia'
import { useMainStore } from '@/store'
import useGlobalHotkey from '@/hooks/useGlobalHotkey' import useGlobalHotkey from '@/hooks/useGlobalHotkey'
import usePasteEvent from '@/hooks/usePasteEvent' import usePasteEvent from '@/hooks/usePasteEvent'
@ -29,6 +42,7 @@ import CanvasTool from './CanvasTool/index.vue'
import Thumbnails from './Thumbnails/index.vue' import Thumbnails from './Thumbnails/index.vue'
import Toolbar from './Toolbar/index.vue' import Toolbar from './Toolbar/index.vue'
import Remark from './Remark/index.vue' import Remark from './Remark/index.vue'
import ExportDialog from './ExportDialog/index.vue'
export default defineComponent({ export default defineComponent({
name: 'editor', name: 'editor',
@ -39,8 +53,13 @@ export default defineComponent({
Thumbnails, Thumbnails,
Toolbar, Toolbar,
Remark, Remark,
ExportDialog,
}, },
setup() { setup() {
const mainStore = useMainStore()
const { dialogForExport } = storeToRefs(mainStore)
const closeExportDialog = () => mainStore.setDialogForExport('')
const remarkHeight = ref(40) const remarkHeight = ref(40)
useGlobalHotkey() useGlobalHotkey()
@ -48,6 +67,8 @@ export default defineComponent({
return { return {
remarkHeight, remarkHeight,
dialogForExport,
closeExportDialog,
} }
}, },
}) })