This commit is contained in:
pipipi-pikachu 2020-12-13 20:43:24 +08:00
parent 5b333c4dab
commit f135829a99
8 changed files with 103 additions and 9 deletions

View File

@ -19,4 +19,10 @@ const router = createRouter({
routes, routes,
}) })
router.beforeEach((to, from) => {
if(to.name === 'Player' && from.name !== 'Editor') {
return router.push({ path: '/' })
}
})
export default router export default router

View File

@ -5,9 +5,9 @@ export enum MutationTypes {
SET_HANDLE_ELEMENT_ID = 'setHandleElementId', SET_HANDLE_ELEMENT_ID = 'setHandleElementId',
SET_EDITOR_AREA_SHOW_SCALE = 'setEditorAreaShowScale', SET_EDITOR_AREA_SHOW_SCALE = 'setEditorAreaShowScale',
SET_CANVAS_SCALE = 'setCanvasScale', SET_CANVAS_SCALE = 'setCanvasScale',
TOGGLE_SHOW_GRID_LINES = 'toggleShowGridLines',
SET_THUMBNAILS_FOCUS = 'setThumbnailsFocus', SET_THUMBNAILS_FOCUS = 'setThumbnailsFocus',
SET_EDITORAREA_FOCUS = 'setEditorAreaFocus', SET_EDITORAREA_FOCUS = 'setEditorAreaFocus',
SET_DISABLE_HOTKEYS_STATE = 'setDisableHotkeysState',
SET_AVAILABLE_FONTS = 'setAvailableFonts', SET_AVAILABLE_FONTS = 'setAvailableFonts',
SET_SAVE_STATE = 'setSaveState', SET_SAVE_STATE = 'setSaveState',

View File

@ -1,7 +1,9 @@
import { PPTElement } from '@/types/slides' import { PPTElement, Slide, PPTAnimation } from '@/types/slides'
import { State } from './state' import { State } from './state'
export type Getters = { export type Getters = {
currentSlide(state: State): Slide | null;
currentSlideAnimations(state: State): PPTAnimation[] | null;
activeElementList(state: State): PPTElement[]; activeElementList(state: State): PPTElement[];
handleElement(state: State): PPTElement | null; handleElement(state: State): PPTElement | null;
canUndo(state: State): boolean; canUndo(state: State): boolean;
@ -9,6 +11,21 @@ export type Getters = {
} }
export const getters: Getters = { export const getters: Getters = {
currentSlide(state) {
return state.slides[state.slideIndex] || null
},
currentSlideAnimations(state) {
const currentSlide = state.slides[state.slideIndex]
if(!currentSlide) return null
const animations = currentSlide.animations
if(!animations) return null
const els = currentSlide.elements
const elIds = els.map(el => el.elId)
return animations.filter(animation => elIds.includes(animation.elId))
},
activeElementList(state) { activeElementList(state) {
const currentSlide = state.slides[state.slideIndex] const currentSlide = state.slides[state.slideIndex]
if(!currentSlide || !currentSlide.elements) return [] if(!currentSlide || !currentSlide.elements) return []

View File

@ -32,9 +32,9 @@ export type Mutations = {
[MutationTypes.SET_HANDLE_ELEMENT_ID](state: State, handleElementId: string): void; [MutationTypes.SET_HANDLE_ELEMENT_ID](state: State, handleElementId: string): void;
[MutationTypes.SET_EDITOR_AREA_SHOW_SCALE](state: State, scale: number): void; [MutationTypes.SET_EDITOR_AREA_SHOW_SCALE](state: State, scale: number): void;
[MutationTypes.SET_CANVAS_SCALE](state: State, scale: number): void; [MutationTypes.SET_CANVAS_SCALE](state: State, scale: number): void;
[MutationTypes.TOGGLE_SHOW_GRID_LINES](state: State): void;
[MutationTypes.SET_THUMBNAILS_FOCUS](state: State, isFocus: boolean): void; [MutationTypes.SET_THUMBNAILS_FOCUS](state: State, isFocus: boolean): void;
[MutationTypes.SET_EDITORAREA_FOCUS](state: State, isFocus: boolean): void; [MutationTypes.SET_EDITORAREA_FOCUS](state: State, isFocus: boolean): void;
[MutationTypes.SET_DISABLE_HOTKEYS_STATE](state: State, disable: boolean): void;
[MutationTypes.SET_AVAILABLE_FONTS](state: State): void; [MutationTypes.SET_AVAILABLE_FONTS](state: State): void;
[MutationTypes.SET_SAVE_STATE](state: State, saveState: SaveState ): void; [MutationTypes.SET_SAVE_STATE](state: State, saveState: SaveState ): void;
[MutationTypes.SET_SLIDES](state: State, slides: Slide[]): void; [MutationTypes.SET_SLIDES](state: State, slides: Slide[]): void;
@ -75,10 +75,6 @@ export const mutations: Mutations = {
state.canvasScale = scale state.canvasScale = scale
}, },
[MutationTypes.TOGGLE_SHOW_GRID_LINES](state) {
state.isShowGridLines = !state.isShowGridLines
},
[MutationTypes.SET_THUMBNAILS_FOCUS](state, isFocus) { [MutationTypes.SET_THUMBNAILS_FOCUS](state, isFocus) {
state.thumbnailsFocus = isFocus state.thumbnailsFocus = isFocus
}, },
@ -87,6 +83,10 @@ export const mutations: Mutations = {
state.editorAreaFocus = isFocus state.editorAreaFocus = isFocus
}, },
[MutationTypes.SET_DISABLE_HOTKEYS_STATE](state, disable) {
state.disableHotkeys = disable
},
[MutationTypes.SET_AVAILABLE_FONTS](state) { [MutationTypes.SET_AVAILABLE_FONTS](state) {
state.availableFonts = FONT_NAMES.filter(font => isSupportFontFamily(font.en)) state.availableFonts = FONT_NAMES.filter(font => isSupportFontFamily(font.en))
}, },

View File

@ -7,11 +7,11 @@ export type SaveState = 'complete' | 'pending'
export type State = { export type State = {
activeElementIdList: string[]; activeElementIdList: string[];
handleElementId: string; handleElementId: string;
isShowGridLines: boolean;
editorAreaShowScale: number; editorAreaShowScale: number;
canvasScale: number; canvasScale: number;
thumbnailsFocus: boolean; thumbnailsFocus: boolean;
editorAreaFocus: boolean; editorAreaFocus: boolean;
disableHotkeys: boolean;
availableFonts: FontName[]; availableFonts: FontName[];
saveState: SaveState; saveState: SaveState;
slides: Slide[]; slides: Slide[];
@ -23,11 +23,11 @@ export type State = {
export const state: State = { export const state: State = {
activeElementIdList: [], activeElementIdList: [],
handleElementId: '', handleElementId: '',
isShowGridLines: false,
editorAreaShowScale: 85, editorAreaShowScale: 85,
canvasScale: 1, canvasScale: 1,
thumbnailsFocus: false, thumbnailsFocus: false,
editorAreaFocus: false, editorAreaFocus: false,
disableHotkeys: false,
availableFonts: [], availableFonts: [],
saveState: 'complete', saveState: 'complete',
slides: slides, slides: slides,

View File

@ -23,6 +23,12 @@ interface Axis {
y: number; y: number;
} }
export interface AlignmentLineProps {
type: AlignmentLineType;
axis: Axis;
length: number;
}
export default { export default {
name: 'alignment-line', name: 'alignment-line',
props: { props: {

View File

@ -25,6 +25,16 @@
:height="mouseSelectionState.height" :height="mouseSelectionState.height"
:quadrant="mouseSelectionState.quadrant" :quadrant="mouseSelectionState.quadrant"
/> />
<SlideBackground
:background="currentSlide?.background"
:isShowGridLines="isShowGridLines"
/>
<AlignmentLine
v-for="(line, index) in alignmentLines" :key="index"
:type="line.type" :axis="line.axis" :length="line.length"
/>
</div> </div>
</div> </div>
</template> </template>
@ -38,13 +48,20 @@ import { ContextmenuItem } from '@/components/Contextmenu/types'
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas' import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
import MouseSelection from './MouseSelection.vue' import MouseSelection from './MouseSelection.vue'
import SlideBackground from './SlideBackground.vue'
import AlignmentLine, { AlignmentLineProps } from './AlignmentLine.vue'
export default defineComponent({ export default defineComponent({
name: 'v-canvas', name: 'v-canvas',
components: { components: {
MouseSelection, MouseSelection,
SlideBackground,
AlignmentLine,
}, },
setup() { setup() {
const isShowGridLines = ref(false)
const alignmentLines = ref<AlignmentLineProps[]>([])
const viewportStyles = reactive({ const viewportStyles = reactive({
width: VIEWPORT_SIZE, width: VIEWPORT_SIZE,
height: VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO, height: VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO,
@ -57,6 +74,8 @@ export default defineComponent({
const canvasScale = ref(1) const canvasScale = ref(1)
const store = useStore<State>() const store = useStore<State>()
const currentSlide = computed(() => store.getters.currentSlide)
const editorAreaShowScale = computed(() => store.state.editorAreaShowScale) const editorAreaShowScale = computed(() => store.state.editorAreaShowScale)
const setViewportSize = () => { const setViewportSize = () => {
if(!canvasRef.value) return if(!canvasRef.value) return
@ -179,9 +198,17 @@ export default defineComponent({
children: [ children: [
{ {
text: '打开', text: '打开',
disable: isShowGridLines.value,
icon: isShowGridLines.value ? 'icon-check' : '',
iconPlacehoder: true,
action: () => isShowGridLines.value = true,
}, },
{ {
text: '关闭', text: '关闭',
disable: !isShowGridLines.value,
icon: !isShowGridLines.value ? 'icon-check' : '',
iconPlacehoder: true,
action: () => isShowGridLines.value = false,
}, },
], ],
}, },
@ -202,6 +229,9 @@ export default defineComponent({
mouseSelectionState, mouseSelectionState,
handleClickBlankArea, handleClickBlankArea,
removeEditorAreaFocus, removeEditorAreaFocus,
currentSlide,
isShowGridLines,
alignmentLines,
contextmenus, contextmenus,
} }
}, },

View File

@ -42,6 +42,7 @@ export default defineComponent({
const store = useStore<State>() const store = useStore<State>()
const editorAreaFocus = computed(() => store.state.editorAreaFocus) const editorAreaFocus = computed(() => store.state.editorAreaFocus)
const thumbnailsFocus = computed(() => store.state.thumbnailsFocus) const thumbnailsFocus = computed(() => store.state.thumbnailsFocus)
const disableHotkeys = computed(() => store.state.disableHotkeys)
const save = () => { const save = () => {
message.success('save') message.success('save')
@ -112,15 +113,49 @@ export default defineComponent({
if(shiftKeyDown.value) shiftKeyDown.value = false if(shiftKeyDown.value) shiftKeyDown.value = false
} }
const pasteImageFile = (imageFile: File) => {
console.log(imageFile)
}
const pasteText = (text: string) => {
console.log(text)
}
const pasteListener = (e: ClipboardEvent) => {
if(!editorAreaFocus.value && !thumbnailsFocus.value) return
if(disableHotkeys.value) return
if(!e.clipboardData) return
const clipboardDataItems = e.clipboardData.items
const clipboardDataFirstItem = clipboardDataItems[0]
if(!clipboardDataFirstItem) return
for(const item of clipboardDataItems) {
if(item.kind === 'file' && item.type.indexOf('image') !== -1) {
const imageFile = item.getAsFile()
if(imageFile) pasteImageFile(imageFile)
return
}
}
if( clipboardDataFirstItem.kind === 'string' && clipboardDataFirstItem.type === 'text/plain' ) {
clipboardDataFirstItem.getAsString(text => pasteText(text))
}
}
onMounted(() => { onMounted(() => {
document.addEventListener('keydown', keydownListener) document.addEventListener('keydown', keydownListener)
document.addEventListener('keyup', keyupListener) document.addEventListener('keyup', keyupListener)
window.addEventListener('blur', keyupListener) window.addEventListener('blur', keyupListener)
document.addEventListener('paste', pasteListener)
}) })
onUnmounted(() => { onUnmounted(() => {
document.removeEventListener('keydown', keydownListener) document.removeEventListener('keydown', keydownListener)
document.removeEventListener('keyup', keyupListener) document.removeEventListener('keyup', keyupListener)
window.removeEventListener('blur', keyupListener) window.removeEventListener('blur', keyupListener)
document.removeEventListener('paste', pasteListener)
}) })
}, },
}) })