mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
update
This commit is contained in:
parent
f37c7d7a62
commit
5b333c4dab
16
src/App.vue
16
src/App.vue
@ -2,6 +2,22 @@
|
|||||||
<router-view/>
|
<router-view/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineComponent, onMounted } from 'vue'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
import { MutationTypes } from '@/store/constants'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'app',
|
||||||
|
setup() {
|
||||||
|
const store = useStore()
|
||||||
|
onMounted(() => {
|
||||||
|
store.commit(MutationTypes.SET_AVAILABLE_FONTS)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
#app {
|
#app {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -19,24 +19,24 @@ export const ELEMENT_TYPE_TABS = {
|
|||||||
table: { key: 'element-table', label: '表格属性' },
|
table: { key: 'element-table', label: '表格属性' },
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ELEMENTS = {
|
export enum ELEMENTS {
|
||||||
text: '文本',
|
text = '文本',
|
||||||
image: '图片',
|
image = '图片',
|
||||||
shape: '形状',
|
shape = '形状',
|
||||||
icon: '图标',
|
icon = '图标',
|
||||||
line: '线条',
|
line = '线条',
|
||||||
chart: '图表',
|
chart = '图表',
|
||||||
iframe: 'Iframe',
|
iframe = 'Iframe',
|
||||||
table: '表格',
|
table = '表格',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OPERATE_KEYS = {
|
export enum OPERATE_KEYS {
|
||||||
LEFT_TOP: 1,
|
LEFT_TOP = 1,
|
||||||
TOP: 2,
|
TOP = 2,
|
||||||
RIGHT_TOP: 3,
|
RIGHT_TOP = 3,
|
||||||
LEFT: 4,
|
LEFT = 4,
|
||||||
RIGHT: 5,
|
RIGHT = 5,
|
||||||
LEFT_BOTTOM: 6,
|
LEFT_BOTTOM = 6,
|
||||||
BOTTOM: 7,
|
BOTTOM = 7,
|
||||||
RIGHT_BOTTOM: 8,
|
RIGHT_BOTTOM = 8,
|
||||||
}
|
}
|
@ -1,4 +1,10 @@
|
|||||||
export const FONT_FAMILYS = [
|
export interface FontName {
|
||||||
|
source: string;
|
||||||
|
zh: string;
|
||||||
|
en: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FONT_NAMES = [
|
||||||
{ source: 'windows', zh: '微软雅黑', en: 'Microsoft Yahei' },
|
{ source: 'windows', zh: '微软雅黑', en: 'Microsoft Yahei' },
|
||||||
{ source: 'windows', zh: '宋体', en: 'SimSun' },
|
{ source: 'windows', zh: '宋体', en: 'SimSun' },
|
||||||
{ source: 'windows', zh: '黑体', en: 'SimHei' },
|
{ source: 'windows', zh: '黑体', en: 'SimHei' },
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
export const KEYCODE = {
|
export enum KEYCODE {
|
||||||
S: 83,
|
S = 83,
|
||||||
C: 67,
|
C = 67,
|
||||||
X: 88,
|
X = 88,
|
||||||
Z: 90,
|
Z = 90,
|
||||||
Y: 89,
|
Y = 89,
|
||||||
A: 65,
|
A = 65,
|
||||||
G: 71,
|
G = 71,
|
||||||
L: 76,
|
L = 76,
|
||||||
DELETE: 46,
|
DELETE = 46,
|
||||||
UP: 38,
|
UP = 38,
|
||||||
DOWN: 40,
|
DOWN = 40,
|
||||||
LEFT: 37,
|
LEFT = 37,
|
||||||
RIGHT: 39,
|
RIGHT = 39,
|
||||||
ENTER: 13,
|
ENTER = 13,
|
||||||
SPACE: 32,
|
SPACE = 32,
|
||||||
TAB: 9,
|
TAB = 9,
|
||||||
}
|
}
|
@ -1,6 +1,8 @@
|
|||||||
import { MutationTypes } from './constants'
|
import { MutationTypes } from './constants'
|
||||||
import { State, SaveState } from './state'
|
import { State, SaveState } from './state'
|
||||||
import { Slide, PPTElement } from '@/types/slides'
|
import { Slide, PPTElement } from '@/types/slides'
|
||||||
|
import { FONT_NAMES } from '@/configs/fontName'
|
||||||
|
import { isSupportFontFamily } from '@/utils/index'
|
||||||
|
|
||||||
interface AddSlidesData {
|
interface AddSlidesData {
|
||||||
index?: number;
|
index?: number;
|
||||||
@ -33,7 +35,7 @@ export type Mutations = {
|
|||||||
[MutationTypes.TOGGLE_SHOW_GRID_LINES](state: State): 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_AVAILABLE_FONTS](state: State, fonts: string[]): 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;
|
||||||
[MutationTypes.ADD_SLIDES](state: State, data: AddSlidesData): void;
|
[MutationTypes.ADD_SLIDES](state: State, data: AddSlidesData): void;
|
||||||
@ -44,6 +46,10 @@ export type Mutations = {
|
|||||||
[MutationTypes.UPDATE_SLIDE_INDEX](state: State, index: number): void;
|
[MutationTypes.UPDATE_SLIDE_INDEX](state: State, index: number): void;
|
||||||
[MutationTypes.ADD_ELEMENTS](state: State, elements: PPTElement[]): void;
|
[MutationTypes.ADD_ELEMENTS](state: State, elements: PPTElement[]): void;
|
||||||
[MutationTypes.UPDATE_ELEMENT](state: State, data: UpdateElementData): void;
|
[MutationTypes.UPDATE_ELEMENT](state: State, data: UpdateElementData): void;
|
||||||
|
[MutationTypes.SET_CURSOR](state: State, cursor: number): void;
|
||||||
|
[MutationTypes.UNDO](state: State): void;
|
||||||
|
[MutationTypes.REDO](state: State): void;
|
||||||
|
[MutationTypes.SET_HISTORY_RECORD_LENGTH](state: State, length: number): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mutations: Mutations = {
|
export const mutations: Mutations = {
|
||||||
@ -81,8 +87,8 @@ export const mutations: Mutations = {
|
|||||||
state.editorAreaFocus = isFocus
|
state.editorAreaFocus = isFocus
|
||||||
},
|
},
|
||||||
|
|
||||||
[MutationTypes.SET_AVAILABLE_FONTS](state, fonts) {
|
[MutationTypes.SET_AVAILABLE_FONTS](state) {
|
||||||
state.availableFonts = fonts
|
state.availableFonts = FONT_NAMES.filter(font => isSupportFontFamily(font.en))
|
||||||
},
|
},
|
||||||
|
|
||||||
[MutationTypes.SET_SAVE_STATE](state, saveState) {
|
[MutationTypes.SET_SAVE_STATE](state, saveState) {
|
||||||
@ -146,4 +152,22 @@ export const mutations: Mutations = {
|
|||||||
})
|
})
|
||||||
state.slides[slideIndex].elements = (elements as PPTElement[])
|
state.slides[slideIndex].elements = (elements as PPTElement[])
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// history
|
||||||
|
|
||||||
|
[MutationTypes.SET_CURSOR](state, cursor) {
|
||||||
|
state.cursor = cursor
|
||||||
|
},
|
||||||
|
|
||||||
|
[MutationTypes.UNDO](state) {
|
||||||
|
state.cursor -= 1
|
||||||
|
},
|
||||||
|
|
||||||
|
[MutationTypes.REDO](state) {
|
||||||
|
state.cursor += 1
|
||||||
|
},
|
||||||
|
|
||||||
|
[MutationTypes.SET_HISTORY_RECORD_LENGTH](state, length) {
|
||||||
|
state.historyRecordLength = length
|
||||||
|
},
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import { Slide } from '@/types/slides'
|
import { Slide } from '@/types/slides'
|
||||||
import { slides } from '@/mocks/index'
|
import { slides } from '@/mocks/index'
|
||||||
|
import { FontName } from '@/configs/fontName'
|
||||||
|
|
||||||
export type SaveState = 'complete' | 'pending'
|
export type SaveState = 'complete' | 'pending'
|
||||||
|
|
||||||
@ -11,7 +12,7 @@ export type State = {
|
|||||||
canvasScale: number;
|
canvasScale: number;
|
||||||
thumbnailsFocus: boolean;
|
thumbnailsFocus: boolean;
|
||||||
editorAreaFocus: boolean;
|
editorAreaFocus: boolean;
|
||||||
availableFonts: string[];
|
availableFonts: FontName[];
|
||||||
saveState: SaveState;
|
saveState: SaveState;
|
||||||
slides: Slide[];
|
slides: Slide[];
|
||||||
slideIndex: number;
|
slideIndex: number;
|
||||||
|
@ -10,7 +10,7 @@ export const createRandomNumber = (min: number, max: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 生成随机码
|
// 生成随机码
|
||||||
export const createRandomCode = (len: number = 6) => {
|
export const createRandomCode = (len = 6) => {
|
||||||
const charset = `_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`
|
const charset = `_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`
|
||||||
const maxLen = charset.length
|
const maxLen = charset.length
|
||||||
let ret = ''
|
let ret = ''
|
||||||
@ -30,7 +30,7 @@ export const createUUID = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前日期字符串
|
// 获取当前日期字符串
|
||||||
export const getDateTime = (format: string = 'yyyy-MM-dd hh:mm:ss') => {
|
export const getDateTime = (format = 'yyyy-MM-dd hh:mm:ss') => {
|
||||||
const date = new Date()
|
const date = new Date()
|
||||||
|
|
||||||
const formatMap = {
|
const formatMap = {
|
||||||
@ -176,7 +176,7 @@ export const encrypt = (msg: string) => {
|
|||||||
|
|
||||||
// 解密函数
|
// 解密函数
|
||||||
export const decrypt = (ciphertext: string) => {
|
export const decrypt = (ciphertext: string) => {
|
||||||
const bytes = CryptoJS.AES.decrypt(ciphertext, CRYPTO_KEY)
|
const bytes = CryptoJS.AES.decrypt(ciphertext, CRYPTO_KEY)
|
||||||
return bytes.toString(CryptoJS.enc.Utf8)
|
return bytes.toString(CryptoJS.enc.Utf8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
ref="canvasRef"
|
ref="canvasRef"
|
||||||
@mousedown="$event => handleClickBlankArea($event)"
|
@mousedown="$event => handleClickBlankArea($event)"
|
||||||
v-contextmenu="contextmenus"
|
v-contextmenu="contextmenus"
|
||||||
|
v-click-outside="removeEditorAreaFocus"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="viewport"
|
class="viewport"
|
||||||
@ -32,6 +33,7 @@
|
|||||||
import { computed, defineComponent, onMounted, onUnmounted, reactive, ref } from 'vue'
|
import { computed, defineComponent, onMounted, onUnmounted, reactive, ref } from 'vue'
|
||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import { State } from '@/store/state'
|
import { State } from '@/store/state'
|
||||||
|
import { MutationTypes } from '@/store/constants'
|
||||||
import { ContextmenuItem } from '@/components/Contextmenu/types'
|
import { ContextmenuItem } from '@/components/Contextmenu/types'
|
||||||
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
|
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
|
||||||
|
|
||||||
@ -149,8 +151,16 @@ export default defineComponent({
|
|||||||
mouseSelectionState.isShow = false
|
mouseSelectionState.isShow = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const editorAreaFocus = computed(() => store.state.editorAreaFocus)
|
||||||
|
|
||||||
const handleClickBlankArea = (e: MouseEvent) => {
|
const handleClickBlankArea = (e: MouseEvent) => {
|
||||||
updateMouseSelection(e)
|
updateMouseSelection(e)
|
||||||
|
if(!editorAreaFocus.value) store.commit(MutationTypes.SET_EDITORAREA_FOCUS, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeEditorAreaFocus = () => {
|
||||||
|
if(editorAreaFocus.value) store.commit(MutationTypes.SET_EDITORAREA_FOCUS, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const contextmenus = (): ContextmenuItem[] => {
|
const contextmenus = (): ContextmenuItem[] => {
|
||||||
@ -191,6 +201,7 @@ export default defineComponent({
|
|||||||
viewportStyles,
|
viewportStyles,
|
||||||
mouseSelectionState,
|
mouseSelectionState,
|
||||||
handleClickBlankArea,
|
handleClickBlankArea,
|
||||||
|
removeEditorAreaFocus,
|
||||||
contextmenus,
|
contextmenus,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -13,7 +13,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue'
|
import { computed, defineComponent, onMounted, onUnmounted, ref } from 'vue'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
import { State } from '@/store/state'
|
||||||
|
import { KEYCODE } from '@/configs/keyCode'
|
||||||
|
|
||||||
|
import { message } from 'ant-design-vue'
|
||||||
|
|
||||||
import EditorHeader from './EditorHeader/index.vue'
|
import EditorHeader from './EditorHeader/index.vue'
|
||||||
import Canvas from './Canvas/index.vue'
|
import Canvas from './Canvas/index.vue'
|
||||||
@ -30,6 +35,94 @@ export default defineComponent({
|
|||||||
Thumbnails,
|
Thumbnails,
|
||||||
Toolbar,
|
Toolbar,
|
||||||
},
|
},
|
||||||
|
setup() {
|
||||||
|
const ctrlKeyDown = ref(false)
|
||||||
|
const shiftKeyDown = ref(false)
|
||||||
|
|
||||||
|
const store = useStore<State>()
|
||||||
|
const editorAreaFocus = computed(() => store.state.editorAreaFocus)
|
||||||
|
const thumbnailsFocus = computed(() => store.state.thumbnailsFocus)
|
||||||
|
|
||||||
|
const save = () => {
|
||||||
|
message.success('save')
|
||||||
|
}
|
||||||
|
const copy = () => {
|
||||||
|
message.success('copy')
|
||||||
|
}
|
||||||
|
const cut = () => {
|
||||||
|
message.success('cut')
|
||||||
|
}
|
||||||
|
const undo = () => {
|
||||||
|
message.success('undo')
|
||||||
|
}
|
||||||
|
const redo = () => {
|
||||||
|
message.success('redo')
|
||||||
|
}
|
||||||
|
const selectAll = () => {
|
||||||
|
message.success('selectAll')
|
||||||
|
}
|
||||||
|
const lock = () => {
|
||||||
|
message.success('lock')
|
||||||
|
}
|
||||||
|
const combine = () => {
|
||||||
|
message.success('combine')
|
||||||
|
}
|
||||||
|
const uncombine = () => {
|
||||||
|
message.success('uncombine')
|
||||||
|
}
|
||||||
|
const remove = () => {
|
||||||
|
message.success('remove')
|
||||||
|
}
|
||||||
|
const move = (key: number) => {
|
||||||
|
message.success(`move: ${key}`)
|
||||||
|
}
|
||||||
|
const create = () => {
|
||||||
|
message.success('create')
|
||||||
|
}
|
||||||
|
|
||||||
|
const keydownListener = (e: KeyboardEvent) => {
|
||||||
|
const { keyCode, ctrlKey, shiftKey } = e
|
||||||
|
|
||||||
|
if(ctrlKey && !ctrlKeyDown.value) ctrlKeyDown.value = true
|
||||||
|
if(shiftKey && !shiftKeyDown.value) shiftKeyDown.value = true
|
||||||
|
|
||||||
|
if(!editorAreaFocus.value && !thumbnailsFocus.value) return
|
||||||
|
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
if(ctrlKey && keyCode === KEYCODE.S) save()
|
||||||
|
if(ctrlKey && keyCode === KEYCODE.C) copy()
|
||||||
|
if(ctrlKey && keyCode === KEYCODE.X) cut()
|
||||||
|
if(ctrlKey && keyCode === KEYCODE.Z) undo()
|
||||||
|
if(ctrlKey && keyCode === KEYCODE.Y) redo()
|
||||||
|
if(ctrlKey && keyCode === KEYCODE.A) selectAll()
|
||||||
|
if(ctrlKey && keyCode === KEYCODE.L) lock()
|
||||||
|
if(!shiftKey && ctrlKey && keyCode === KEYCODE.G) combine()
|
||||||
|
if(shiftKey && ctrlKey && keyCode === KEYCODE.G) uncombine()
|
||||||
|
if(keyCode === KEYCODE.DELETE) remove()
|
||||||
|
if(keyCode === KEYCODE.UP) move(KEYCODE.UP)
|
||||||
|
if(keyCode === KEYCODE.DOWN) move(KEYCODE.DOWN)
|
||||||
|
if(keyCode === KEYCODE.LEFT) move(KEYCODE.LEFT)
|
||||||
|
if(keyCode === KEYCODE.RIGHT) move(KEYCODE.RIGHT)
|
||||||
|
if(keyCode === KEYCODE.ENTER) create()
|
||||||
|
}
|
||||||
|
|
||||||
|
const keyupListener = () => {
|
||||||
|
if(ctrlKeyDown.value) ctrlKeyDown.value = false
|
||||||
|
if(shiftKeyDown.value) shiftKeyDown.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
document.addEventListener('keydown', keydownListener)
|
||||||
|
document.addEventListener('keyup', keyupListener)
|
||||||
|
window.addEventListener('blur', keyupListener)
|
||||||
|
})
|
||||||
|
onUnmounted(() => {
|
||||||
|
document.removeEventListener('keydown', keydownListener)
|
||||||
|
document.removeEventListener('keyup', keyupListener)
|
||||||
|
window.removeEventListener('blur', keyupListener)
|
||||||
|
})
|
||||||
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user