perf: 代码优化&注释

This commit is contained in:
pipipi-pikachu 2021-02-12 15:04:04 +08:00
parent d4a8d41394
commit 132c2a0afa
13 changed files with 168 additions and 149 deletions

View File

@ -4,17 +4,17 @@ import { ElementOrderCommand, ElementOrderCommands } from '@/types/edit'
import { PPTElement } from '@/types/slides'
import { KEYS } from '@/configs/hotkey'
import useSlideHandler from '@/hooks/useSlideHandler'
import useLockElement from '@/hooks/useLockElement'
import useDeleteElement from '@/hooks/useDeleteElement'
import useCombineElement from '@/hooks/useCombineElement'
import useCopyAndPasteElement from '@/hooks/useCopyAndPasteElement'
import useSelectAllElement from '@/hooks/useSelectAllElement'
import useMoveElement from '@/hooks/useMoveElement'
import useOrderElement from '@/hooks/useOrderElement'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
import useScreening from '@/hooks/useScreening'
import useScaleCanvas from '@/hooks/useScaleCanvas'
import useSlideHandler from './useSlideHandler'
import useLockElement from './useLockElement'
import useDeleteElement from './useDeleteElement'
import useCombineElement from './useCombineElement'
import useCopyAndPasteElement from './useCopyAndPasteElement'
import useSelectAllElement from './useSelectAllElement'
import useMoveElement from './useMoveElement'
import useOrderElement from './useOrderElement'
import useHistorySnapshot from './useHistorySnapshot'
import useScreening from './useScreening'
import useScaleCanvas from './useScaleCanvas'
export default () => {
const store = useStore()

View File

@ -1,8 +1,8 @@
import { computed, onMounted, onUnmounted } from 'vue'
import { useStore } from '@/store'
import { getImageDataURL } from '@/utils/image'
import usePasteTextClipboardData from '@/hooks/usePasteTextClipboardData'
import useCreateElement from '@/hooks/useCreateElement'
import usePasteTextClipboardData from './usePasteTextClipboardData'
import useCreateElement from './useCreateElement'
export default () => {
const store = useStore()
@ -13,10 +13,15 @@ export default () => {
const { pasteTextClipboardData } = usePasteTextClipboardData()
const { createImageElement } = useCreateElement()
// 粘贴图片到幻灯片元素
const pasteImageFile = (imageFile: File) => {
getImageDataURL(imageFile).then(dataURL => createImageElement(dataURL))
}
/**
*
* @param e ClipboardEvent
*/
const pasteListener = (e: ClipboardEvent) => {
if (!editorAreaFocus.value && !thumbnailsFocus.value) return
if (disableHotkeys.value) return
@ -28,6 +33,7 @@ export default () => {
if (!clipboardDataFirstItem) return
// 如果剪贴板内有图片,优先尝试读取图片
for (const item of clipboardDataItems) {
if (item.kind === 'file' && item.type.indexOf('image') !== -1) {
const imageFile = item.getAsFile()
@ -36,6 +42,7 @@ export default () => {
}
}
// 如果剪贴板内没有图片,但有文字内容,尝试解析文字内容
if (clipboardDataFirstItem.kind === 'string' && clipboardDataFirstItem.type === 'text/plain') {
clipboardDataFirstItem.getAsString(text => pasteTextClipboardData(text))
}

View File

@ -113,12 +113,15 @@ export default defineComponent({
const chartPoolVisible = ref(false)
const tableGeneratorVisible = ref(false)
//
const drawText = () => {
store.commit(MutationTypes.SET_CREATING_ELEMENT, {
type: 'text',
data: null,
})
}
//
const drawShape = (shape: ShapePoolItem) => {
store.commit(MutationTypes.SET_CREATING_ELEMENT, {
type: 'shape',
@ -126,6 +129,8 @@ export default defineComponent({
})
shapePoolVisible.value = false
}
// 线
const drawLine = (line: LinePoolItem) => {
store.commit(MutationTypes.SET_CREATING_ELEMENT, {
type: 'line',

View File

@ -63,6 +63,7 @@ export default defineComponent({
cutSlide,
} = useSlideHandler()
//
const changSlideIndex = (index: number) => {
store.commit(MutationTypes.SET_ACTIVE_ELEMENT_ID_LIST, [])
@ -72,11 +73,13 @@ export default defineComponent({
const thumbnailsFocus = computed(() => store.state.thumbnailsFocus)
//
const setThumbnailsFocus = (focus: boolean) => {
if (thumbnailsFocus.value === focus) return
store.commit(MutationTypes.SET_THUMBNAILS_FOCUS, focus)
}
//
const handleDragEnd = (eventData: { newIndex: number; oldIndex: number }) => {
const { newIndex, oldIndex } = eventData
if (oldIndex === newIndex) return

View File

@ -15,8 +15,8 @@
<script lang="ts">
import { defineComponent } from 'vue'
import useHotkey from './useHotkey'
import usePasteEvent from './usePasteEvent'
import useGlobalHotkey from '@/hooks/useGlobalHotkey'
import usePasteEvent from '@/hooks/usePasteEvent'
import EditorHeader from './EditorHeader/index.vue'
import Canvas from './Canvas/index.vue'
@ -34,7 +34,7 @@ export default defineComponent({
Toolbar,
},
setup() {
useHotkey()
useGlobalHotkey()
usePasteEvent()
},
})

View File

@ -60,6 +60,7 @@ export default defineComponent({
const theme = computed(() => store.state.theme)
const currentSlide = computed<Slide>(() => store.getters.currentSlide)
//
const needWaitAnimation = computed(() => {
const animations = currentSlide.value.animations || []
const elementIndexInAnimation = animations.findIndex(animation => animation.elId === props.elementInfo.id)

View File

@ -47,28 +47,33 @@ export default defineComponent({
const writingBoardColor = ref('#e2534d')
const writingBoardModel = ref('pen')
//
const changePen = () => {
if (!writingBoardVisible.value) writingBoardVisible.value = true
writingBoardModel.value = 'pen'
emit('close')
}
//
const changeEraser = () => {
writingBoardModel.value = 'eraser'
emit('close')
}
//
const clearCanvas = () => {
writingBoardRef.value.clearCanvas()
emit('close')
}
//
const changeColor = (color: string) => {
if (writingBoardModel.value !== 'pen') writingBoardModel.value = 'pen'
writingBoardColor.value = color
emit('close')
}
//
const closeWritingBoard = () => {
writingBoardVisible.value = false
emit('close')

View File

@ -92,6 +92,7 @@ export default defineComponent({
const writingBoardToolVisible = ref(false)
//
const setSlideContentSize = () => {
const winWidth = document.body.clientWidth
const winHeight = document.body.clientHeight
@ -113,6 +114,8 @@ export default defineComponent({
slideHeight.value = height
}
//
// 退
const { exitScreening } = useScreening()
const windowResizeListener = () => {
@ -120,9 +123,18 @@ export default defineComponent({
if (!isFullscreen()) exitScreening()
}
const animationIndex = ref(0)
const animations = computed(() => currentSlide.value.animations || [])
onMounted(() => {
window.addEventListener('resize', windowResizeListener)
})
onUnmounted(() => {
window.removeEventListener('resize', windowResizeListener)
})
//
const animations = computed(() => currentSlide.value.animations || [])
const animationIndex = ref(0)
//
const runAnimation = () => {
const prefix = 'animate__'
const animation = animations.value[animationIndex.value]
@ -140,6 +152,9 @@ export default defineComponent({
}
}
// /
//
//
const execPrev = () => {
if (animations.value.length && animationIndex.value > 0) {
animationIndex.value -= 1
@ -160,6 +175,13 @@ export default defineComponent({
}
}
//
const mousewheelListener = throttle(function(e: WheelEvent) {
if (e.deltaY < 0) execPrev()
else if (e.deltaY > 0) execNext()
}, 500, { leading: true, trailing: false })
//
const keydownListener = (e: KeyboardEvent) => {
const key = e.key.toUpperCase()
if (key === KEYS.UP || key === KEYS.LEFT) execPrev()
@ -171,20 +193,14 @@ export default defineComponent({
) execNext()
}
const mousewheelListener = throttle(function(e: WheelEvent) {
if (e.deltaY < 0) execPrev()
else if (e.deltaY > 0) execNext()
}, 500, { leading: true, trailing: false })
onMounted(() => {
window.addEventListener('resize', windowResizeListener)
document.addEventListener('keydown', keydownListener)
})
onUnmounted(() => {
window.removeEventListener('resize', windowResizeListener)
document.removeEventListener('keydown', keydownListener)
})
// /
const turnPrevSlide = () => {
store.commit(MutationTypes.UPDATE_SLIDE_INDEX, slideIndex.value - 1)
animationIndex.value = 0
@ -194,6 +210,7 @@ export default defineComponent({
animationIndex.value = 0
}
//
const turnSlideToIndex = (index: number) => {
slideThumbnailModelVisible.value = false
store.commit(MutationTypes.UPDATE_SLIDE_INDEX, index)

View File

@ -71,12 +71,14 @@
<script lang="ts">
import { computed, defineComponent, nextTick, onMounted, onUnmounted, PropType, ref, watch } from 'vue'
import debounce from 'lodash/debounce'
import tinycolor from 'tinycolor2'
import { useStore } from '@/store'
import { PPTElementOutline, TableCell, TableCellStyle, TableTheme } from '@/types/slides'
import { PPTElementOutline, TableCell, TableTheme } from '@/types/slides'
import { ContextmenuItem } from '@/components/Contextmenu/types'
import { KEYS } from '@/configs/hotkey'
import { createRandomCode } from '@/utils/common'
import { getTextStyle } from './utils'
import useHideCells from './useHideCells'
import useSubThemeColor from './useSubThemeColor'
import CustomTextarea from './CustomTextarea.vue'
@ -127,19 +129,9 @@ export default defineComponent({
},
})
//
const subThemeColor = ref(['', ''])
watch(() => props.theme, () => {
if (props.theme) {
const rgba = tinycolor(props.theme.color).toRgb()
const subRgba1 = { r: rgba.r, g: rgba.g, b: rgba.b, a: rgba.a * 0.3 }
const subRgba2 = { r: rgba.r, g: rgba.g, b: rgba.b, a: rgba.a * 0.1 }
subThemeColor.value = [
`rgba(${[subRgba1.r, subRgba1.g, subRgba1.b, subRgba1.a].join(',')})`,
`rgba(${[subRgba2.r, subRgba2.g, subRgba2.b, subRgba2.a].join(',')})`,
]
}
}, { immediate: true })
//
const theme = computed(() => props.theme)
const { subThemeColor } = useSubThemeColor(theme)
//
const colSizeList = ref<number[]>([])
@ -173,26 +165,8 @@ export default defineComponent({
})
//
const hideCells = computed(() => {
const hideCells = []
for (let i = 0; i < tableCells.value.length; i++) {
const rowCells = tableCells.value[i]
for (let j = 0; j < rowCells.length; j++) {
const cell = rowCells[j]
if (cell.colspan > 1 || cell.rowspan > 1) {
for (let row = i; row < i + cell.rowspan; row++) {
for (let col = row === i ? j + 1 : j; col < j + cell.colspan; col++) {
hideCells.push(`${row}_${col}`)
}
}
}
}
}
return hideCells
})
const cells = computed(() => props.data)
const { hideCells } = useHideCells(cells)
//
const selectedCells = computed(() => {
@ -526,33 +500,6 @@ export default defineComponent({
document.removeEventListener('keydown', keydownListener)
})
//
const getTextStyle = (style?: TableCellStyle) => {
if (!style) return {}
const {
bold,
em,
underline,
strikethrough,
color,
backcolor,
fontsize,
fontname,
align,
} = style
return {
fontWeight: bold ? 'bold' : 'normal',
fontStyle: em ? 'italic' : 'normal',
textDecoration: `${underline ? 'underline' : ''} ${strikethrough ? 'line-through' : ''}`,
color: color || '#000',
backgroundColor: backcolor || '',
fontSize: fontsize || '14px',
fontFamily: fontname || '微软雅黑',
textAlign: align || 'left',
}
}
//
const handleInput = debounce(function() {
emit('change', tableCells.value)

View File

@ -45,8 +45,10 @@
<script lang="ts">
import { computed, defineComponent, PropType, ref, watch } from 'vue'
import tinycolor from 'tinycolor2'
import { PPTElementOutline, TableCell, TableCellStyle, TableTheme } from '@/types/slides'
import { PPTElementOutline, TableCell, TableTheme } from '@/types/slides'
import { getTextStyle } from './utils'
import useHideCells from './useHideCells'
import useSubThemeColor from './useSubThemeColor'
export default defineComponent({
name: 'static-table',
@ -86,65 +88,11 @@ export default defineComponent({
colSizeList.value = props.colWidths.map(item => item * props.width)
}, { immediate: true })
const hideCells = computed(() => {
const hideCells = []
const cells = computed(() => props.data)
const { hideCells } = useHideCells(cells)
for (let i = 0; i < props.data.length; i++) {
const rowCells = props.data[i]
for (let j = 0; j < rowCells.length; j++) {
const cell = rowCells[j]
if (cell.colspan > 1 || cell.rowspan > 1) {
for (let row = i; row < i + cell.rowspan; row++) {
for (let col = row === i ? j + 1 : j; col < j + cell.colspan; col++) {
hideCells.push(`${row}_${col}`)
}
}
}
}
}
return hideCells
})
const subThemeColor = ref(['', ''])
watch(() => props.theme, () => {
if (props.theme) {
const rgba = tinycolor(props.theme.color).toRgb()
const subRgba1 = { r: rgba.r, g: rgba.g, b: rgba.b, a: rgba.a * 0.3 }
const subRgba2 = { r: rgba.r, g: rgba.g, b: rgba.b, a: rgba.a * 0.1 }
subThemeColor.value = [
`rgba(${[subRgba1.r, subRgba1.g, subRgba1.b, subRgba1.a].join(',')})`,
`rgba(${[subRgba2.r, subRgba2.g, subRgba2.b, subRgba2.a].join(',')})`,
]
}
}, { immediate: true })
const getTextStyle = (style?: TableCellStyle) => {
if (!style) return {}
const {
bold,
em,
underline,
strikethrough,
color,
backcolor,
fontsize,
fontname,
align,
} = style
return {
fontWeight: bold ? 'bold' : 'normal',
fontStyle: em ? 'italic' : 'normal',
textDecoration: `${underline ? 'underline' : ''} ${strikethrough ? 'line-through' : ''}`,
color: color || '#000',
backgroundColor: backcolor || '',
fontSize: fontsize || '14px',
fontFamily: fontname || '微软雅黑',
textAlign: align || 'left',
}
}
const theme = computed(() => props.theme)
const { subThemeColor } = useSubThemeColor(theme)
return {
colSizeList,

View File

@ -0,0 +1,31 @@
import { computed, Ref } from 'vue'
import { TableCell } from '@/types/slides'
// 计算无效的单元格位置(被合并的单元格位置)集合
export default (cells: Ref<TableCell[][]>) => {
const hideCells = computed(() => {
const hideCells = []
for (let i = 0; i < cells.value.length; i++) {
const rowCells = cells.value[i]
for (let j = 0; j < rowCells.length; j++) {
const cell = rowCells[j]
if (cell.colspan > 1 || cell.rowspan > 1) {
for (let row = i; row < i + cell.rowspan; row++) {
for (let col = row === i ? j + 1 : j; col < j + cell.colspan; col++) {
hideCells.push(`${row}_${col}`)
}
}
}
}
}
return hideCells
})
return {
hideCells,
}
}

View File

@ -0,0 +1,24 @@
import { ref, Ref, watch } from 'vue'
import tinycolor from 'tinycolor2'
import { TableTheme } from '@/types/slides'
// 通过表格的主题色计算辅助颜色
export default (theme: Ref<TableTheme | undefined>) => {
const subThemeColor = ref(['', ''])
watch(() => theme.value, () => {
if (theme.value) {
const rgba = tinycolor(theme.value.color).toRgb()
const subRgba1 = { r: rgba.r, g: rgba.g, b: rgba.b, a: rgba.a * 0.3 }
const subRgba2 = { r: rgba.r, g: rgba.g, b: rgba.b, a: rgba.a * 0.1 }
subThemeColor.value = [
`rgba(${[subRgba1.r, subRgba1.g, subRgba1.b, subRgba1.a].join(',')})`,
`rgba(${[subRgba2.r, subRgba2.g, subRgba2.b, subRgba2.a].join(',')})`,
]
}
}, { immediate: true })
return {
subThemeColor,
}
}

View File

@ -0,0 +1,31 @@
import { TableCellStyle } from '@/types/slides'
/**
*
* @param style
*/
export const getTextStyle = (style?: TableCellStyle) => {
if (!style) return {}
const {
bold,
em,
underline,
strikethrough,
color,
backcolor,
fontsize,
fontname,
align,
} = style
return {
fontWeight: bold ? 'bold' : 'normal',
fontStyle: em ? 'italic' : 'normal',
textDecoration: `${underline ? 'underline' : ''} ${strikethrough ? 'line-through' : ''}`,
color: color || '#000',
backgroundColor: backcolor || '',
fontSize: fontsize || '14px',
fontFamily: fontname || '微软雅黑',
textAlign: align || 'left',
}
}