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,
})
router.beforeEach((to, from) => {
if(to.name === 'Player' && from.name !== 'Editor') {
return router.push({ path: '/' })
}
})
export default router

View File

@ -5,9 +5,9 @@ export enum MutationTypes {
SET_HANDLE_ELEMENT_ID = 'setHandleElementId',
SET_EDITOR_AREA_SHOW_SCALE = 'setEditorAreaShowScale',
SET_CANVAS_SCALE = 'setCanvasScale',
TOGGLE_SHOW_GRID_LINES = 'toggleShowGridLines',
SET_THUMBNAILS_FOCUS = 'setThumbnailsFocus',
SET_EDITORAREA_FOCUS = 'setEditorAreaFocus',
SET_DISABLE_HOTKEYS_STATE = 'setDisableHotkeysState',
SET_AVAILABLE_FONTS = 'setAvailableFonts',
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'
export type Getters = {
currentSlide(state: State): Slide | null;
currentSlideAnimations(state: State): PPTAnimation[] | null;
activeElementList(state: State): PPTElement[];
handleElement(state: State): PPTElement | null;
canUndo(state: State): boolean;
@ -9,6 +11,21 @@ export type 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) {
const currentSlide = state.slides[state.slideIndex]
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_EDITOR_AREA_SHOW_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_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_SAVE_STATE](state: State, saveState: SaveState ): void;
[MutationTypes.SET_SLIDES](state: State, slides: Slide[]): void;
@ -75,10 +75,6 @@ export const mutations: Mutations = {
state.canvasScale = scale
},
[MutationTypes.TOGGLE_SHOW_GRID_LINES](state) {
state.isShowGridLines = !state.isShowGridLines
},
[MutationTypes.SET_THUMBNAILS_FOCUS](state, isFocus) {
state.thumbnailsFocus = isFocus
},
@ -87,6 +83,10 @@ export const mutations: Mutations = {
state.editorAreaFocus = isFocus
},
[MutationTypes.SET_DISABLE_HOTKEYS_STATE](state, disable) {
state.disableHotkeys = disable
},
[MutationTypes.SET_AVAILABLE_FONTS](state) {
state.availableFonts = FONT_NAMES.filter(font => isSupportFontFamily(font.en))
},

View File

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

View File

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

View File

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

View File

@ -42,6 +42,7 @@ export default defineComponent({
const store = useStore<State>()
const editorAreaFocus = computed(() => store.state.editorAreaFocus)
const thumbnailsFocus = computed(() => store.state.thumbnailsFocus)
const disableHotkeys = computed(() => store.state.disableHotkeys)
const save = () => {
message.success('save')
@ -112,15 +113,49 @@ export default defineComponent({
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(() => {
document.addEventListener('keydown', keydownListener)
document.addEventListener('keyup', keyupListener)
window.addEventListener('blur', keyupListener)
document.addEventListener('paste', pasteListener)
})
onUnmounted(() => {
document.removeEventListener('keydown', keydownListener)
document.removeEventListener('keyup', keyupListener)
window.removeEventListener('blur', keyupListener)
document.removeEventListener('paste', pasteListener)
})
},
})