feat: 添加缩略图多选(待补充批量操作功能)

This commit is contained in:
pipipi-pikachu 2021-03-08 22:35:32 +08:00
parent b5866359cc
commit 5421f82801
4 changed files with 74 additions and 4 deletions

View File

@ -21,6 +21,7 @@ export const enum MutationTypes {
UPDATE_SLIDE = 'updateSlide', UPDATE_SLIDE = 'updateSlide',
DELETE_SLIDE = 'deleteSlide', DELETE_SLIDE = 'deleteSlide',
UPDATE_SLIDE_INDEX = 'updateSlideIndex', UPDATE_SLIDE_INDEX = 'updateSlideIndex',
UPDATE_SELECTED_SLIDES_INDEX = 'updateSelectedSlidesIndex',
ADD_ELEMENT = 'addElement', ADD_ELEMENT = 'addElement',
UPDATE_ELEMENT = 'updateElement', UPDATE_ELEMENT = 'updateElement',
REMOVE_ELEMENT_PROPS = 'removeElementProps', REMOVE_ELEMENT_PROPS = 'removeElementProps',

View File

@ -106,6 +106,10 @@ export const mutations: MutationTree<State> = {
state.slideIndex = index state.slideIndex = index
}, },
[MutationTypes.UPDATE_SELECTED_SLIDES_INDEX](state, selectedSlidesIndex: number[]) {
state.selectedSlidesIndex = selectedSlidesIndex
},
[MutationTypes.ADD_ELEMENT](state, element: PPTElement | PPTElement[]) { [MutationTypes.ADD_ELEMENT](state, element: PPTElement | PPTElement[]) {
const elements = Array.isArray(element) ? element : [element] const elements = Array.isArray(element) ? element : [element]
const currentSlideEls = state.slides[state.slideIndex].elements const currentSlideEls = state.slides[state.slideIndex].elements

View File

@ -19,6 +19,7 @@ export interface State {
theme: SlideTheme; theme: SlideTheme;
slides: Slide[]; slides: Slide[];
slideIndex: number; slideIndex: number;
selectedSlidesIndex: number[];
snapshotCursor: number; snapshotCursor: number;
snapshotLength: number; snapshotLength: number;
ctrlKeyState: boolean; ctrlKeyState: boolean;
@ -47,6 +48,7 @@ export const state: State = {
}, },
slides: slides, slides: slides,
slideIndex: 0, slideIndex: 0,
selectedSlidesIndex: [],
snapshotCursor: -1, snapshotCursor: -1,
snapshotLength: 0, snapshotLength: 0,
ctrlKeyState: false, ctrlKeyState: false,

View File

@ -18,8 +18,11 @@
<template #item="{ element, index }"> <template #item="{ element, index }">
<div <div
class="thumbnail-item" class="thumbnail-item"
:class="{ 'selected': slideIndex === index }" :class="{
@mousedown="changSlideIndex(index)" 'active': slideIndex === index,
'selected': selectedSlidesIndex.includes(index),
}"
@mousedown="handleClickSlideThumbnail(index)"
v-contextmenu="contextmenusThumbnailItem" v-contextmenu="contextmenusThumbnailItem"
> >
<div class="label">{{ fillDigit(index + 1, 2) }}</div> <div class="label">{{ fillDigit(index + 1, 2) }}</div>
@ -51,6 +54,9 @@ export default defineComponent({
const store = useStore() const store = useStore()
const slides = computed(() => store.state.slides) const slides = computed(() => store.state.slides)
const slideIndex = computed(() => store.state.slideIndex) const slideIndex = computed(() => store.state.slideIndex)
const ctrlKeyState = computed(() => store.state.ctrlKeyState)
const shiftKeyState = computed(() => store.state.shiftKeyState)
const selectedSlidesIndex = computed(() => [...store.state.selectedSlidesIndex, slideIndex.value])
const { const {
copySlide, copySlide,
@ -69,12 +75,63 @@ export default defineComponent({
store.commit(MutationTypes.UPDATE_SLIDE_INDEX, index) store.commit(MutationTypes.UPDATE_SLIDE_INDEX, index)
} }
//
const handleClickSlideThumbnail = (index: number) => {
const isMultiSelected = selectedSlidesIndex.value.length > 1
// Ctrl
if (ctrlKeyState.value) {
if (slideIndex.value === index) {
if (!isMultiSelected) return
const newSelectedSlidesIndex = selectedSlidesIndex.value.filter(item => item !== index)
store.commit(MutationTypes.UPDATE_SELECTED_SLIDES_INDEX, newSelectedSlidesIndex)
changSlideIndex(selectedSlidesIndex.value[0])
}
else {
if (selectedSlidesIndex.value.includes(index)) {
const newSelectedSlidesIndex = selectedSlidesIndex.value.filter(item => item !== index)
store.commit(MutationTypes.UPDATE_SELECTED_SLIDES_INDEX, newSelectedSlidesIndex)
}
else {
const newSelectedSlidesIndex = [...selectedSlidesIndex.value, index]
store.commit(MutationTypes.UPDATE_SELECTED_SLIDES_INDEX, newSelectedSlidesIndex)
changSlideIndex(index)
}
}
}
// Shift
else if (shiftKeyState.value) {
if (slideIndex.value === index && !isMultiSelected) return
let minIndex = Math.min(...selectedSlidesIndex.value)
let maxIndex = index
if (index < minIndex) {
maxIndex = Math.max(...selectedSlidesIndex.value)
minIndex = index
}
const newSelectedSlidesIndex = []
for (let i = minIndex; i <= maxIndex; i++) newSelectedSlidesIndex.push(i)
store.commit(MutationTypes.UPDATE_SELECTED_SLIDES_INDEX, newSelectedSlidesIndex)
changSlideIndex(index)
}
//
else {
store.commit(MutationTypes.UPDATE_SELECTED_SLIDES_INDEX, [])
changSlideIndex(index)
}
}
const thumbnailsFocus = computed(() => store.state.thumbnailsFocus) const thumbnailsFocus = computed(() => store.state.thumbnailsFocus)
// //
const setThumbnailsFocus = (focus: boolean) => { const setThumbnailsFocus = (focus: boolean) => {
if (thumbnailsFocus.value === focus) return if (thumbnailsFocus.value === focus) return
store.commit(MutationTypes.SET_THUMBNAILS_FOCUS, focus) store.commit(MutationTypes.SET_THUMBNAILS_FOCUS, focus)
if (!focus) store.commit(MutationTypes.UPDATE_SELECTED_SLIDES_INDEX, [])
} }
// //
@ -158,8 +215,9 @@ export default defineComponent({
setThumbnailsFocus, setThumbnailsFocus,
slides, slides,
slideIndex, slideIndex,
selectedSlidesIndex,
createSlide, createSlide,
changSlideIndex, handleClickSlideThumbnail,
contextmenusThumbnails, contextmenusThumbnails,
contextmenusThumbnailItem, contextmenusThumbnailItem,
fillDigit, fillDigit,
@ -202,7 +260,7 @@ export default defineComponent({
outline: 1px solid rgba($color: $themeColor, $alpha: .15); outline: 1px solid rgba($color: $themeColor, $alpha: .15);
} }
&.selected { &.active {
.label { .label {
color: $themeColor; color: $themeColor;
} }
@ -210,6 +268,11 @@ export default defineComponent({
outline-color: $themeColor; outline-color: $themeColor;
} }
} }
&.selected {
.thumbnail {
outline-color: $themeColor;
}
}
} }
.label { .label {
font-size: 12px; font-size: 12px;