幻灯片放映组件拆分

This commit is contained in:
pipipi-pikachu 2021-01-13 22:36:01 +08:00
parent f042d56f20
commit ec15ac8895
3 changed files with 195 additions and 110 deletions

View File

@ -0,0 +1,68 @@
<template>
<div class="slide-thumbnails">
<div
class="thumbnail"
:class="{ 'active': index === slideIndex }"
v-for="(slide, index) in slides"
:key="slide.id"
@click="turnSlideToIndex(index)"
>
<ThumbnailSlide :slide="slide" :size="150" />
</div>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, PropType } from 'vue'
import { useStore } from 'vuex'
import { State } from '@/store'
import ThumbnailSlide from '@/views/components/ThumbnailSlide/index.vue'
export default defineComponent({
name: 'slide-thumbnails',
components: {
ThumbnailSlide,
},
props: {
turnSlideToIndex: {
type: Function as PropType<(index: number) => void>,
},
},
setup() {
const store = useStore<State>()
const slides = computed(() => store.state.slides)
const slideIndex = computed(() => store.state.slideIndex)
return {
slides,
slideIndex,
}
},
})
</script>
<style lang="scss" scoped>
.slide-thumbnails {
height: 600px;
padding: 5px 10px;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
overflow: overlay;
.thumbnail {
width: 150px;
margin-bottom: 12px;
outline: 1px solid rgba($color: $themeColor, $alpha: .1);
&.active {
outline-color: $themeColor;
}
&:not(:nth-child(6n)) {
margin-right: 12px;
}
}
}
</style>

View File

@ -0,0 +1,109 @@
<template>
<teleport to="body">
<WritingBoard
ref="writingBoardRef"
:color="writingBoardColor"
:model="writingBoardModel"
v-if="visible"
/>
</teleport>
<div class="writing-board-tool">
<div class="btn" @click="writingBoardModel = 'pen'; close()">画笔</div>
<div class="btn" @click="writingBoardModel = 'eraser'; close()">橡皮擦</div>
<div class="btn" @click="writingBoardRef.clearCanvas(); close()">擦除所有墨迹</div>
<div class="btn" @click="closeWritingBoard()">关闭画笔</div>
<div class="colors">
<div
class="color"
:class="{ 'active': color === writingBoardColor }"
v-for="color in writingBoardColors"
:key="color"
:style="{ backgroundColor: color }"
@click="writingBoardColor = color; close()"
></div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
import WritingBoard from '@/components/WritingBoard.vue'
const writingBoardColors = ['#000000', '#ffffff', '#1e497b', '#4e81bb', '#e2534d', '#9aba60', '#8165a0', '#47acc5', '#f9974c']
export default defineComponent({
name: 'writing-board-tool',
emits: ['close', 'update:visible'],
components: {
WritingBoard,
},
props: {
visible: {
type: Boolean,
default: false,
},
},
setup(props, { emit }) {
const writingBoardRef = ref()
const writingBoardColor = ref('#e2534d')
const writingBoardModel = ref('pen')
const close = () => {
emit('close')
}
const closeWritingBoard = () => {
emit('update:visible', false)
emit('close')
}
return {
writingBoardRef,
writingBoardColors,
writingBoardColor,
writingBoardModel,
closeWritingBoard,
close,
}
},
})
</script>
<style lang="scss" scoped>
.writing-board-tool {
font-size: 12px;
.btn {
padding: 3px 10px;
margin: 0 -10px;
margin-bottom: 3px;
cursor: pointer;
&:hover {
background-color: #ccc;
}
}
.colors {
display: flex;
margin-top: 8px;
}
.color {
width: 15px;
height: 15px;
outline: 1px solid #ccc;
cursor: pointer;
&:hover {
transform: scale(1.1);
}
&.active {
outline: 2px solid $themeColor;
}
& + .color {
margin-left: 5px;
}
}
}
</style>

View File

@ -35,49 +35,25 @@
</div> </div>
<Modal <Modal
v-model:visible="slideListModelVisible" v-model:visible="slideThumbnailModelVisible"
:footer="null" :footer="null"
centered centered
:width="1020" :width="1020"
:bodyStyle="{ padding: '50px 20px 20px 20px' }" :bodyStyle="{ padding: '50px 20px 20px 20px' }"
> >
<div class="slide-list-model"> <SlideThumbnails :turnSlideToIndex="turnSlideToIndex" />
<div
class="thumbnail"
:class="{ 'active': index === slideIndex }"
v-for="(slide, index) in slides"
:key="slide.id"
@click="turnSlideToIndex(index)"
>
<ThumbnailSlide :slide="slide" :size="150" />
</div>
</div>
</Modal> </Modal>
<WritingBoard ref="writingBoardRef" :color="writingBoardColor" :model="writingBoardModel" v-if="writingBoardVisible" />
<div class="tools"> <div class="tools">
<IconFont class="tool-btn" type="icon-left-circle" @click="execPrev()" /> <IconFont class="tool-btn" type="icon-left-circle" @click="execPrev()" />
<IconFont class="tool-btn" type="icon-right-circle" @click="execNext()" /> <IconFont class="tool-btn" type="icon-right-circle" @click="execNext()" />
<IconFont class="tool-btn" type="icon-appstore" @click="slideListModelVisible = true" /> <IconFont class="tool-btn" type="icon-appstore" @click="slideThumbnailModelVisible = true" />
<Popover trigger="click" v-model:visible="writingBoardConfigsVisible"> <Popover trigger="click" v-model:visible="writingBoardToolVisible">
<template #content> <template #content>
<div class="writing-board-configs"> <WritingBoardTool
<div class="btn" @click="writingBoardModel = 'pen'; writingBoardConfigsVisible = false">画笔</div> v-model:visible="writingBoardVisible"
<div class="btn" @click="writingBoardModel = 'eraser'; writingBoardConfigsVisible = false">橡皮擦</div> @close="writingBoardToolVisible = false"
<div class="btn" @click="writingBoardRef.clearCanvas(); writingBoardConfigsVisible = false">擦除所有墨迹</div> />
<div class="btn" @click="writingBoardVisible = false; writingBoardConfigsVisible = false">关闭画笔</div>
<div class="colors">
<div
class="color"
:class="{ 'active': color === writingBoardColor }"
v-for="color in writingBoardColors"
:key="color"
:style="{ backgroundColor: color }"
@click="writingBoardColor = color; writingBoardConfigsVisible = false"
></div>
</div>
</div>
</template> </template>
<IconFont class="tool-btn" type="icon-edit" @click="writingBoardVisible = true" /> <IconFont class="tool-btn" type="icon-edit" @click="writingBoardVisible = true" />
</Popover> </Popover>
@ -97,17 +73,15 @@ import { KEYS } from '@/configs/hotkey'
import { ContextmenuItem } from '@/components/Contextmenu/types' import { ContextmenuItem } from '@/components/Contextmenu/types'
import ScreenSlide from './ScreenSlide.vue' import ScreenSlide from './ScreenSlide.vue'
import ThumbnailSlide from '@/views/components/ThumbnailSlide/index.vue' import SlideThumbnails from './SlideThumbnails.vue'
import WritingBoard from '@/components/WritingBoard.vue' import WritingBoardTool from './WritingBoardTool.vue'
const writingBoardColors = ['#000000', '#ffffff', '#1e497b', '#4e81bb', '#e2534d', '#9aba60', '#8165a0', '#47acc5', '#f9974c']
export default defineComponent({ export default defineComponent({
name: 'screen', name: 'screen',
components: { components: {
ScreenSlide, ScreenSlide,
ThumbnailSlide, SlideThumbnails,
WritingBoard, WritingBoardTool,
}, },
setup() { setup() {
const store = useStore<State>() const store = useStore<State>()
@ -119,13 +93,10 @@ export default defineComponent({
const slideHeight = ref(0) const slideHeight = ref(0)
const scale = computed(() => slideWidth.value / VIEWPORT_SIZE) const scale = computed(() => slideWidth.value / VIEWPORT_SIZE)
const slideListModelVisible = ref(false) const slideThumbnailModelVisible = ref(false)
const writingBoardRef = ref()
const writingBoardVisible = ref(false) const writingBoardVisible = ref(false)
const writingBoardConfigsVisible = ref(false) const writingBoardToolVisible = ref(false)
const writingBoardColor = ref('#e2534d')
const writingBoardModel = ref('pen')
const setSlideContentSize = () => { const setSlideContentSize = () => {
const winWidth = document.body.clientWidth const winWidth = document.body.clientWidth
@ -223,7 +194,7 @@ export default defineComponent({
} }
const turnSlideToIndex = (index: number) => { const turnSlideToIndex = (index: number) => {
slideListModelVisible.value = false slideThumbnailModelVisible.value = false
store.commit(MutationTypes.UPDATE_SLIDE_INDEX, index) store.commit(MutationTypes.UPDATE_SLIDE_INDEX, index)
animationIndex.value = 0 animationIndex.value = 0
} }
@ -260,14 +231,10 @@ export default defineComponent({
contextmenus, contextmenus,
execPrev, execPrev,
execNext, execNext,
slideListModelVisible, slideThumbnailModelVisible,
writingBoardVisible,
writingBoardConfigsVisible,
turnSlideToIndex, turnSlideToIndex,
writingBoardRef, writingBoardVisible,
writingBoardColors, writingBoardToolVisible,
writingBoardColor,
writingBoardModel,
} }
}, },
}) })
@ -366,63 +333,4 @@ export default defineComponent({
margin-left: 8px; margin-left: 8px;
} }
} }
.slide-list-model {
height: 600px;
padding: 5px 10px;
display: flex;
flex-wrap: wrap;
align-content: flex-start;
overflow: overlay;
.thumbnail {
width: 150px;
margin-bottom: 12px;
outline: 1px solid rgba($color: $themeColor, $alpha: .1);
&.active {
outline-color: $themeColor;
}
&:not(:nth-child(6n)) {
margin-right: 12px;
}
}
}
.writing-board-configs {
font-size: 12px;
.btn {
padding: 3px 10px;
margin: 0 -10px;
margin-bottom: 3px;
cursor: pointer;
&:hover {
background-color: #ccc;
}
}
.colors {
display: flex;
margin-top: 8px;
}
.color {
width: 15px;
height: 15px;
outline: 1px solid #ccc;
cursor: pointer;
&:hover {
transform: scale(1.1);
}
&.active {
outline: 2px solid $themeColor;
}
& + .color {
margin-left: 5px;
}
}
}
</style> </style>