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
2b49692319
commit
f575fa56b3
@ -1,160 +0,0 @@
|
||||
export const ANIMATIONS_TYPES = ['弹跳', '淡入', '翻转', '旋转', '滑入', '缩放']
|
||||
|
||||
export const ANIMATIONS = [
|
||||
{
|
||||
key: 'bounceIn',
|
||||
type: '弹跳',
|
||||
name: '弹跳',
|
||||
icon: 'icon-anime-bounce'
|
||||
},
|
||||
{
|
||||
key: 'bounceInDown',
|
||||
type: '弹跳',
|
||||
name: '向下弹跳',
|
||||
icon: 'icon-anime-bounce-down',
|
||||
},
|
||||
{
|
||||
key: 'bounceInLeft',
|
||||
type: '弹跳',
|
||||
name: '从左弹跳',
|
||||
icon: 'icon-anime-bounce-left',
|
||||
},
|
||||
{
|
||||
key: 'bounceInRight',
|
||||
type: '弹跳',
|
||||
name: '从右弹跳',
|
||||
icon: 'icon-anime-bounce-right',
|
||||
},
|
||||
{
|
||||
key: 'bounceInUp',
|
||||
type: '弹跳',
|
||||
name: '向上弹跳',
|
||||
icon: 'icon-anime-bounce-up',
|
||||
},
|
||||
{
|
||||
key: 'fadeIn',
|
||||
type: '淡入',
|
||||
name: '淡入',
|
||||
icon: 'icon-anime-fade',
|
||||
},
|
||||
{
|
||||
key: 'fadeInDown',
|
||||
type: '淡入',
|
||||
name: '向下淡入',
|
||||
icon: 'icon-anime-fade-down',
|
||||
},
|
||||
{
|
||||
key: 'fadeInLeft',
|
||||
type: '淡入',
|
||||
name: '从左淡入',
|
||||
icon: 'icon-anime-fade-left',
|
||||
},
|
||||
{
|
||||
key: 'fadeInRight',
|
||||
type: '淡入',
|
||||
name: '从右淡入',
|
||||
icon: 'icon-anime-fade-right',
|
||||
},
|
||||
{
|
||||
key: 'fadeInUp',
|
||||
type: '淡入',
|
||||
name: '向上淡入',
|
||||
icon: 'icon-anime-fade-up',
|
||||
},
|
||||
{
|
||||
key: 'flipInX',
|
||||
type: '翻转',
|
||||
name: '水平翻转',
|
||||
icon: 'icon-anime-flip-x',
|
||||
},
|
||||
{
|
||||
key: 'flipInY',
|
||||
type: '翻转',
|
||||
name: '垂直翻转',
|
||||
icon: 'icon-anime-flip-y',
|
||||
},
|
||||
{
|
||||
key: 'rotateIn',
|
||||
type: '旋转',
|
||||
name: '旋转',
|
||||
icon: 'icon-anime-rotate',
|
||||
},
|
||||
{
|
||||
key: 'rotateInDownLeft',
|
||||
type: '旋转',
|
||||
name: '从左下旋转',
|
||||
icon: 'icon-anime-rotate-up-right',
|
||||
},
|
||||
{
|
||||
key: 'rotateInDownRight',
|
||||
type: '旋转',
|
||||
name: '从右下旋转',
|
||||
icon: 'icon-anime-rotate-up-left',
|
||||
},
|
||||
{
|
||||
key: 'rotateInUpLeft',
|
||||
type: '旋转',
|
||||
name: '从左上旋转',
|
||||
icon: 'icon-anime-rotate-down-right',
|
||||
},
|
||||
{
|
||||
key: 'rotateInUpRight',
|
||||
type: '旋转',
|
||||
name: '从右上旋转',
|
||||
icon: 'icon-anime-rotate-down-left',
|
||||
},
|
||||
{
|
||||
key: 'slideInDown',
|
||||
type: '滑入',
|
||||
name: '向下滑入',
|
||||
icon: 'icon-anime-slide-down',
|
||||
},
|
||||
{
|
||||
key: 'slideInLeft',
|
||||
type: '滑入',
|
||||
name: '从左滑入',
|
||||
icon: 'icon-anime-slide-left',
|
||||
},
|
||||
{
|
||||
key: 'slideInRight',
|
||||
type: '滑入',
|
||||
name: '从右滑入',
|
||||
icon: 'icon-anime-slide-right',
|
||||
},
|
||||
{
|
||||
key: 'slideInUp',
|
||||
type: '滑入',
|
||||
name: '向上滑入',
|
||||
icon: 'icon-anime-slide-up',
|
||||
},
|
||||
{
|
||||
key: 'zoomIn',
|
||||
type: '缩放',
|
||||
name: '放大',
|
||||
icon: 'icon-anime-zoom',
|
||||
},
|
||||
{
|
||||
key: 'zoomInDown',
|
||||
type: '缩放',
|
||||
name: '向下放大',
|
||||
icon: 'icon-anime-zoom-down',
|
||||
},
|
||||
{
|
||||
key: 'zoomInLeft',
|
||||
type: '缩放',
|
||||
name: '从左放大',
|
||||
icon: 'icon-anime-zoom-left',
|
||||
},
|
||||
{
|
||||
key: 'zoomInRight',
|
||||
type: '缩放',
|
||||
name: '从右放大',
|
||||
icon: 'icon-anime-zoom-right',
|
||||
},
|
||||
{
|
||||
key: 'zoomInUp',
|
||||
type: '缩放',
|
||||
name: '向上放大',
|
||||
icon: 'icon-anime-zoom-up',
|
||||
},
|
||||
]
|
@ -1,15 +0,0 @@
|
||||
import { useStore } from 'vuex'
|
||||
import debounce from 'lodash/debounce'
|
||||
import { State, ActionTypes } from '@/store'
|
||||
|
||||
export default () => {
|
||||
const store = useStore<State>()
|
||||
|
||||
const addHistorySnapshot = debounce(function() {
|
||||
store.dispatch(ActionTypes.ADD_SNAPSHOT)
|
||||
}, 300, { trailing: true })
|
||||
|
||||
return {
|
||||
addHistorySnapshot,
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ import { useStore } from 'vuex'
|
||||
import { State, MutationTypes } from '@/store'
|
||||
import { PPTElement, Slide } from '@/types/slides'
|
||||
import { createRandomCode } from '@/utils/common'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
export default () => {
|
||||
const store = useStore<State>()
|
||||
@ -10,6 +11,8 @@ export default () => {
|
||||
const activeElementList: Ref<PPTElement[]> = computed(() => store.getters.activeElementList)
|
||||
const currentSlide: Ref<Slide> = computed(() => store.getters.currentSlide)
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
// 组合元素(为当前所有激活元素添加一个相同的groupId)
|
||||
const combineElements = () => {
|
||||
if(!activeElementList.value.length) return
|
||||
@ -34,6 +37,7 @@ export default () => {
|
||||
newElementList.splice(insertIndex, 0, ...combineElementList)
|
||||
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: newElementList })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
// 取消组合元素(移除所有被激活元素的groupId)
|
||||
@ -47,6 +51,7 @@ export default () => {
|
||||
if(activeElementIdList.value.includes(element.elId) && element.groupId) delete element.groupId
|
||||
}
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: newElementList })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
DEFAULT_CHART,
|
||||
DEFAULT_TABLE,
|
||||
} from '@/configs/element'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
interface CommonElementPosition {
|
||||
top: number;
|
||||
@ -30,9 +31,12 @@ interface LineElementPosition {
|
||||
export default () => {
|
||||
const store = useStore()
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
const createElement = (element: PPTElement) => {
|
||||
store.commit(MutationTypes.ADD_ELEMENT, element)
|
||||
store.commit(MutationTypes.SET_ACTIVE_ELEMENT_ID_LIST, [element.elId])
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
const createImageElement = (imgUrl: string) => {
|
||||
|
@ -2,23 +2,28 @@ import { Ref, computed } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
import { State, MutationTypes } from '@/store'
|
||||
import { Slide } from '@/types/slides'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
export default () => {
|
||||
const store = useStore<State>()
|
||||
const activeElementIdList = computed(() => store.state.activeElementIdList)
|
||||
const currentSlide: Ref<Slide> = computed(() => store.getters.currentSlide)
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
const deleteElement = () => {
|
||||
if(!activeElementIdList.value.length) return
|
||||
const newElementList = currentSlide.value.elements.filter(el => !activeElementIdList.value.includes(el.elId))
|
||||
store.commit(MutationTypes.SET_ACTIVE_ELEMENT_ID_LIST, [])
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: newElementList })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
const deleteAllElements = () => {
|
||||
if(!currentSlide.value.elements.length) return
|
||||
store.commit(MutationTypes.SET_ACTIVE_ELEMENT_ID_LIST, [])
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: [] })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -1,10 +1,15 @@
|
||||
import { useStore } from 'vuex'
|
||||
import debounce from 'lodash/debounce'
|
||||
import throttle from 'lodash/throttle'
|
||||
import { State, ActionTypes } from '@/store'
|
||||
|
||||
export default () => {
|
||||
const store = useStore<State>()
|
||||
|
||||
const addHistorySnapshot = debounce(function() {
|
||||
store.dispatch(ActionTypes.ADD_SNAPSHOT)
|
||||
}, 300, { trailing: true })
|
||||
|
||||
const redo = throttle(function() {
|
||||
store.dispatch(ActionTypes.RE_DO)
|
||||
}, 100, { leading: true, trailing: false })
|
||||
@ -14,6 +19,7 @@ export default () => {
|
||||
}, 100, { leading: true, trailing: false })
|
||||
|
||||
return {
|
||||
addHistorySnapshot,
|
||||
redo,
|
||||
undo,
|
||||
}
|
@ -2,12 +2,15 @@ import { useStore } from 'vuex'
|
||||
import { Ref, computed } from 'vue'
|
||||
import { State, MutationTypes } from '@/store'
|
||||
import { PPTElement, Slide } from '@/types/slides'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
export default () => {
|
||||
const store = useStore<State>()
|
||||
const activeElementIdList = computed(() => store.state.activeElementIdList)
|
||||
const currentSlide: Ref<Slide> = computed(() => store.getters.currentSlide)
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
const lockElement = () => {
|
||||
const newElementList: PPTElement[] = JSON.parse(JSON.stringify(currentSlide.value.elements))
|
||||
|
||||
@ -15,6 +18,7 @@ export default () => {
|
||||
if(activeElementIdList.value.includes(element.elId)) element.isLock = true
|
||||
}
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: newElementList })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
const unlockElement = (handleElement: PPTElement) => {
|
||||
@ -34,6 +38,7 @@ export default () => {
|
||||
}
|
||||
}
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: newElementList })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -3,12 +3,15 @@ import { useStore } from 'vuex'
|
||||
import { State, MutationTypes } from '@/store'
|
||||
import { Slide } from '@/types/slides'
|
||||
import { KEYS } from '@/configs/hotkey'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
export default () => {
|
||||
const store = useStore<State>()
|
||||
const activeElementIdList = computed(() => store.state.activeElementIdList)
|
||||
const currentSlide: Ref<Slide> = computed(() => store.getters.currentSlide)
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
const moveElement = (command: string) => {
|
||||
const newElementList = currentSlide.value.elements.map(el => {
|
||||
if(activeElementIdList.value.includes(el.elId)) {
|
||||
@ -33,6 +36,7 @@ export default () => {
|
||||
return el
|
||||
})
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: newElementList })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -3,11 +3,14 @@ import { useStore } from 'vuex'
|
||||
import { State, MutationTypes } from '@/store'
|
||||
import { PPTElement, Slide } from '@/types/slides'
|
||||
import { ElementOrderCommand, ElementOrderCommands } from '@/types/edit'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
export default () => {
|
||||
const store = useStore<State>()
|
||||
const currentSlide: Ref<Slide> = computed(() => store.getters.currentSlide)
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
// 获取组合元素层级范围(组合成员中的最大层级和最小层级)
|
||||
const getCombineElementIndexRange = (elementList: PPTElement[], combineElementList: PPTElement[]) => {
|
||||
const minIndex = elementList.findIndex(_element => _element.elId === combineElementList[0].elId)
|
||||
@ -174,6 +177,7 @@ export default () => {
|
||||
else if(command === ElementOrderCommands.BOTTOM) newElementList = moveBottomElement(currentSlide.value.elements, element)
|
||||
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: newElementList })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -4,6 +4,7 @@ import { MutationTypes, State } from '@/store'
|
||||
import { decrypt } from '@/utils/crypto'
|
||||
import { PPTElement, Slide } from '@/types/slides'
|
||||
import { createRandomCode } from '@/utils/common'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
interface PasteTextClipboardDataOptions {
|
||||
onlySlide?: boolean;
|
||||
@ -14,6 +15,8 @@ export default () => {
|
||||
const store = useStore<State>()
|
||||
const currentSlide: Ref<Slide> = computed(() => store.getters.currentSlide)
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
const pasteElement = (elements: PPTElement[]) => {
|
||||
const groupIdMap = {}
|
||||
const elIdMap = {}
|
||||
@ -40,10 +43,12 @@ export default () => {
|
||||
}
|
||||
store.commit(MutationTypes.ADD_ELEMENT, elements)
|
||||
store.commit(MutationTypes.SET_ACTIVE_ELEMENT_ID_LIST, Object.values(elIdMap))
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
const pasteSlide = (slide: Slide) => {
|
||||
store.commit(MutationTypes.ADD_SLIDE, slide)
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
const pasteText = (text: string) => {
|
||||
|
@ -8,6 +8,7 @@ import { encrypt } from '@/utils/crypto'
|
||||
import { KEYS } from '@/configs/hotkey'
|
||||
import { message } from 'ant-design-vue'
|
||||
import usePasteTextClipboardData from '@/hooks/usePasteTextClipboardData'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
export default () => {
|
||||
const store = useStore<State>()
|
||||
@ -16,6 +17,7 @@ export default () => {
|
||||
const currentSlide: Ref<Slide> = computed(() => store.getters.currentSlide)
|
||||
|
||||
const { pasteTextClipboardData } = usePasteTextClipboardData()
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
const updateSlideIndex = (command: string) => {
|
||||
let targetIndex = 0
|
||||
@ -51,14 +53,17 @@ export default () => {
|
||||
elements: [],
|
||||
}
|
||||
store.commit(MutationTypes.ADD_SLIDE, emptySlide)
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
const copyAndPasteSlide = () => {
|
||||
store.commit(MutationTypes.ADD_SLIDE, currentSlide.value)
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
const deleteSlide = () => {
|
||||
store.commit(MutationTypes.DELETE_SLIDE, currentSlide.value.id)
|
||||
addHistorySnapshot()
|
||||
}
|
||||
|
||||
const cutSlide = () => {
|
||||
|
@ -5,14 +5,22 @@ import { ActionTypes, MutationTypes } from './constants'
|
||||
import db, { Snapshot } from '@/utils/database'
|
||||
|
||||
export const actions: ActionTree<State, State> = {
|
||||
async [ActionTypes.INIT_SNAPSHOT_DATABASE]({ commit }) {
|
||||
async [ActionTypes.INIT_SNAPSHOT_DATABASE]({ commit, state }) {
|
||||
const snapshots: Snapshot[] = await db.snapshots.orderBy('id').toArray()
|
||||
const snapshot = snapshots.slice(-1)[0]
|
||||
const lastSnapshot = snapshots.slice(-1)[0]
|
||||
|
||||
if(snapshot) {
|
||||
if(lastSnapshot) {
|
||||
db.snapshots.clear()
|
||||
commit(MutationTypes.SET_SLIDES, snapshot.slides)
|
||||
// commit(MutationTypes.SET_SLIDES, lastSnapshot.slides)
|
||||
}
|
||||
|
||||
const newFirstSnapshot = {
|
||||
index: state.slideIndex,
|
||||
slides: state.slides,
|
||||
}
|
||||
await db.snapshots.add(newFirstSnapshot)
|
||||
commit(MutationTypes.SET_SNAPSHOT_CURSOR, 0)
|
||||
commit(MutationTypes.SET_SNAPSHOT_LENGTH, 1)
|
||||
},
|
||||
|
||||
async [ActionTypes.ADD_SNAPSHOT]({ state, commit }) {
|
||||
@ -44,7 +52,7 @@ export const actions: ActionTree<State, State> = {
|
||||
},
|
||||
|
||||
async [ActionTypes.UN_DO]({ state, commit }) {
|
||||
if(state.snapshotCursor > 0) return
|
||||
if(state.snapshotCursor <= 0) return
|
||||
|
||||
const snapshotCursor = state.snapshotCursor - 1
|
||||
const snapshots: Snapshot[] = await db.snapshots.orderBy('id').toArray()
|
||||
@ -58,7 +66,7 @@ export const actions: ActionTree<State, State> = {
|
||||
},
|
||||
|
||||
async [ActionTypes.RE_DO]({ state, commit }) {
|
||||
if(state.snapshotCursor < state.snapshotLength - 1) return
|
||||
if(state.snapshotCursor >= state.snapshotLength - 1) return
|
||||
|
||||
const snapshotCursor = state.snapshotCursor + 1
|
||||
const snapshots: Snapshot[] = await db.snapshots.orderBy('id').toArray()
|
||||
|
@ -5,6 +5,7 @@ import { ElementTypes, PPTElement } from '@/types/slides'
|
||||
import { AlignmentLineProps } from '@/types/edit'
|
||||
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
|
||||
import { getRectRotatedRange, AlignLine, uniqAlignLines } from '@/utils/element'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
export default (
|
||||
elementList: Ref<PPTElement[]>,
|
||||
@ -15,6 +16,8 @@ export default (
|
||||
const activeElementIdList = computed(() => store.state.activeElementIdList)
|
||||
const canvasScale = computed(() => store.state.canvasScale)
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
const dragElement = (e: MouseEvent, element: PPTElement) => {
|
||||
if(!activeElementIdList.value.includes(element.elId)) return
|
||||
let isMouseDown = true
|
||||
@ -305,6 +308,7 @@ export default (
|
||||
if(startPageX === currentPageX && startPageY === currentPageY) return
|
||||
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: elementList.value })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,12 @@ import { Ref, computed } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
import { State, MutationTypes } from '@/store'
|
||||
import { PPTElement, PPTTextElement, PPTImageElement, PPTShapeElement } from '@/types/slides'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
// 给定一个坐标,计算该坐标到(0, 0)点连线的弧度值
|
||||
// 注意,Math.atan2的一般用法是Math.atan2(y, x)返回的是原点(0,0)到(x,y)点的线段与X轴正方向之间的弧度值
|
||||
// 这里将使用时将x与y的传入顺序交换了,为的是获取原点(0,0)到(x,y)点的线段与Y轴正方向之间的弧度值
|
||||
export const getAngleFromCoordinate = (x: number, y: number) => {
|
||||
const getAngleFromCoordinate = (x: number, y: number) => {
|
||||
const radian = Math.atan2(x, y)
|
||||
const angle = 180 / Math.PI * radian
|
||||
return angle
|
||||
@ -16,6 +17,8 @@ export default (elementList: Ref<PPTElement[]>, viewportRef: Ref<HTMLElement | n
|
||||
const store = useStore<State>()
|
||||
const canvasScale = computed(() => store.state.canvasScale)
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
const rotateElement = (element: PPTTextElement | PPTImageElement | PPTShapeElement) => {
|
||||
let isMouseDown = true
|
||||
let angle = 0
|
||||
@ -67,6 +70,7 @@ export default (elementList: Ref<PPTElement[]>, viewportRef: Ref<HTMLElement | n
|
||||
if(elOriginRotate === angle) return
|
||||
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: elementList.value })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import { ElementTypes, PPTElement, PPTImageElement, PPTLineElement, PPTShapeElem
|
||||
import { OperatePoints, ElementScaleHandler, AlignmentLineProps, MultiSelectRange } from '@/types/edit'
|
||||
import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
|
||||
import { AlignLine, uniqAlignLines } from '@/utils/element'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
// 计算元素被旋转一定角度后,八个操作点的新坐标
|
||||
interface RotateElementData {
|
||||
@ -13,7 +14,7 @@ interface RotateElementData {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
export const getRotateElementPoints = (element: RotateElementData, angle: number) => {
|
||||
const getRotateElementPoints = (element: RotateElementData, angle: number) => {
|
||||
const { left, top, width, height } = element
|
||||
|
||||
const radius = Math.sqrt( Math.pow(width, 2) + Math.pow(height, 2) ) / 2
|
||||
@ -67,7 +68,7 @@ export const getRotateElementPoints = (element: RotateElementData, angle: number
|
||||
}
|
||||
|
||||
// 获取元素某个操作点对角线上另一端的操作点坐标(例如:左上 <-> 右下)
|
||||
export const getOppositePoint = (direction: number, points: ReturnType<typeof getRotateElementPoints>): { left: number; top: number } => {
|
||||
const getOppositePoint = (direction: number, points: ReturnType<typeof getRotateElementPoints>): { left: number; top: number } => {
|
||||
const oppositeMap = {
|
||||
[OperatePoints.RIGHT_BOTTOM]: points.leftTopPoint,
|
||||
[OperatePoints.LEFT_BOTTOM]: points.rightTopPoint,
|
||||
@ -91,6 +92,8 @@ export default (
|
||||
const ctrlOrShiftKeyActive: Ref<boolean> = computed(() => store.getters.ctrlOrShiftKeyActive)
|
||||
const canvasScale = computed(() => store.state.canvasScale)
|
||||
|
||||
const { addHistorySnapshot } = useHistorySnapshot()
|
||||
|
||||
const scaleElement = (e: MouseEvent, element: Exclude<PPTElement, PPTLineElement>, command: ElementScaleHandler) => {
|
||||
let isMouseDown = true
|
||||
|
||||
@ -383,6 +386,7 @@ export default (
|
||||
if(startPageX === e.pageX && startPageY === e.pageY) return
|
||||
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: elementList.value })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
}
|
||||
|
||||
@ -486,6 +490,7 @@ export default (
|
||||
if(startPageX === e.pageX && startPageY === e.pageY) return
|
||||
|
||||
store.commit(MutationTypes.UPDATE_SLIDE, { elements: elementList.value })
|
||||
addHistorySnapshot()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="canvas-tool">
|
||||
<div class="left-handler">
|
||||
<IconFont class="handler-item" type="icon-undo" />
|
||||
<IconFont class="handler-item" type="icon-redo" />
|
||||
<IconFont class="handler-item" :class="{ 'disable': !canUndo }" type="icon-undo" @click="undo()" />
|
||||
<IconFont class="handler-item" :class="{ 'disable': !canRedo }" type="icon-redo" @click="redo()" />
|
||||
</div>
|
||||
|
||||
<div class="add-element-handler">
|
||||
@ -28,6 +28,7 @@ import { defineComponent, computed } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
import { MutationTypes, State } from '@/store'
|
||||
import useScaleCanvas from '@/hooks/useScaleCanvas'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'canvas-tool',
|
||||
@ -35,10 +36,13 @@ export default defineComponent({
|
||||
const store = useStore<State>()
|
||||
const canvasScale = computed(() => store.state.canvasScale)
|
||||
const showGridLines = computed(() => store.state.showGridLines)
|
||||
const canUndo = computed(() => store.getters.canUndo)
|
||||
const canRedo = computed(() => store.getters.canRedo)
|
||||
|
||||
const canvasScalePercentage = computed(() => parseInt(canvasScale.value * 100 + '') + '%')
|
||||
|
||||
const { scaleCanvas } = useScaleCanvas()
|
||||
const { redo, undo } = useHistorySnapshot()
|
||||
|
||||
const toggleGridLines = () => {
|
||||
store.commit(MutationTypes.SET_GRID_LINES_STATE, !showGridLines.value)
|
||||
@ -48,6 +52,10 @@ export default defineComponent({
|
||||
scaleCanvas,
|
||||
canvasScalePercentage,
|
||||
toggleGridLines,
|
||||
canUndo,
|
||||
canRedo,
|
||||
redo,
|
||||
undo,
|
||||
}
|
||||
},
|
||||
})
|
||||
@ -77,6 +85,10 @@ export default defineComponent({
|
||||
.handler-item {
|
||||
margin: 0 10px;
|
||||
cursor: pointer;
|
||||
|
||||
&.disable {
|
||||
opacity: .5;
|
||||
}
|
||||
}
|
||||
.right-handler {
|
||||
display: flex;
|
||||
|
@ -2,7 +2,6 @@ import { computed, onMounted, onUnmounted } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
import { State, MutationTypes } from '@/store'
|
||||
import { KEYS } from '@/configs/hotkey'
|
||||
import { message } from 'ant-design-vue'
|
||||
|
||||
import useSlideHandler from '@/hooks/useSlideHandler'
|
||||
import useLockElement from '@/hooks/useLockElement'
|
||||
@ -11,6 +10,7 @@ import useCombineElement from '@/hooks/useCombineElement'
|
||||
import useCopyAndPasteElement from '@/hooks/useCopyAndPasteElement'
|
||||
import useSelectAllElement from '@/hooks/useSelectAllElement'
|
||||
import useMoveElement from '@/hooks/useMoveElement'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
|
||||
export default () => {
|
||||
const store = useStore<State>()
|
||||
@ -37,6 +37,7 @@ export default () => {
|
||||
const { copyElement, cutElement } = useCopyAndPasteElement()
|
||||
const { selectAllElement } = useSelectAllElement()
|
||||
const { moveElement } = useMoveElement()
|
||||
const { redo, undo } = useHistorySnapshot()
|
||||
|
||||
const copy = () => {
|
||||
if(disableHotkeys.value) return
|
||||
@ -50,14 +51,6 @@ export default () => {
|
||||
else if(activeElementIdList.value.length) cutElement()
|
||||
}
|
||||
|
||||
const undo = () => {
|
||||
message.success('undo')
|
||||
}
|
||||
|
||||
const redo = () => {
|
||||
message.success('redo')
|
||||
}
|
||||
|
||||
const selectAll = () => {
|
||||
if(!editorAreaFocus.value && disableHotkeys.value) return
|
||||
selectAllElement()
|
||||
|
Loading…
x
Reference in New Issue
Block a user