幻灯片放映组件拆分
This commit is contained in:
parent
f042d56f20
commit
ec15ac8895
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
Loading…
Reference in New Issue