|
|
@@ -1,303 +0,0 @@
|
|
|
-import { defineStore } from 'pinia'
|
|
|
-import { AlignEnum } from '@/enum/alignEnum'
|
|
|
-import { LayerEnum } from '@/enum/layerEnum'
|
|
|
-import { useProjectStore } from '@/store/modules/project'
|
|
|
-import { cloneDeep } from 'lodash'
|
|
|
-import { CustomElement } from '#/project'
|
|
|
-import { uuid } from '@/utils'
|
|
|
-
|
|
|
-type ActionState = {
|
|
|
- // 操作记录--最大记录10条
|
|
|
- records: string[]
|
|
|
- // 当前操作索引
|
|
|
- activeIndex: number
|
|
|
- appKey: number
|
|
|
- copyCache: any
|
|
|
-}
|
|
|
-export const useAcionStore = defineStore('action', {
|
|
|
- state(): ActionState {
|
|
|
- return {
|
|
|
- records: [],
|
|
|
- activeIndex: -1,
|
|
|
- appKey: 0,
|
|
|
- copyCache: null
|
|
|
- }
|
|
|
- },
|
|
|
- getters: {
|
|
|
- projectStore: () => useProjectStore(),
|
|
|
- undoDisabled: (state) => state.activeIndex <= 0,
|
|
|
- redoDisabled: (state) => state.activeIndex === state.records.length - 1
|
|
|
- },
|
|
|
- actions: {
|
|
|
- initRecord() {
|
|
|
- this.records = [JSON.stringify(this.projectStore.projectInfo)]
|
|
|
- this.activeIndex = 0
|
|
|
- },
|
|
|
- // addRecord({type, info }: RecordItem & { snapshot?: ProjectInfo}) {
|
|
|
- addRecord() {
|
|
|
- // 新增如果当前索引不是最后一条, 覆盖后面的记录
|
|
|
- if (this.activeIndex < this.records.length - 1) {
|
|
|
- this.records.splice(this.activeIndex + 1, this.records.length)
|
|
|
- }
|
|
|
-
|
|
|
- this.records.push(JSON.stringify(this.projectStore.projectInfo))
|
|
|
-
|
|
|
- // 新增如果超过10条记录,删除最早的一条
|
|
|
- if (this.records.length > 10) {
|
|
|
- this.records.shift()
|
|
|
- this.activeIndex--
|
|
|
- }
|
|
|
-
|
|
|
- this.activeIndex = this.records.length - 1
|
|
|
- },
|
|
|
- /* 撤销 */
|
|
|
- actionUndo() {
|
|
|
- if (this.activeIndex <= 0) return
|
|
|
- --this.activeIndex
|
|
|
- const projectInfo = JSON.parse(this.records[this.activeIndex])
|
|
|
- this.projectStore.updateProjectInfo(projectInfo)
|
|
|
- this.appKey++
|
|
|
- },
|
|
|
- /* 重做 */
|
|
|
- actionRedo() {
|
|
|
- ++this.activeIndex
|
|
|
- const projectInfo = JSON.parse(this.records[this.activeIndex])
|
|
|
- this.projectStore.updateProjectInfo(projectInfo)
|
|
|
- this.appKey++
|
|
|
- },
|
|
|
- actionClear() {},
|
|
|
- /* 对齐 */
|
|
|
- actionAlign(type: AlignEnum) {
|
|
|
- const activeElements = this.projectStore.currentSelectedElements
|
|
|
- switch (type) {
|
|
|
- case AlignEnum.Bottom: {
|
|
|
- const maxY = Math.max(
|
|
|
- ...activeElements.map((item) => item.container.props.y + item.container.props.height)
|
|
|
- )
|
|
|
- activeElements.forEach((item) => {
|
|
|
- this.projectStore.updateElement(
|
|
|
- item.key,
|
|
|
- 'container.props.y',
|
|
|
- maxY - item.container.props.height
|
|
|
- )
|
|
|
- })
|
|
|
- break
|
|
|
- }
|
|
|
- case AlignEnum.HorizontalCenter: {
|
|
|
- const maxX = Math.max(
|
|
|
- ...activeElements.map((item) => item.container.props.x + item.container.props.width)
|
|
|
- )
|
|
|
- const minX = Math.min(...activeElements.map((item) => item.container.props.x))
|
|
|
- const centerX = minX + (maxX - minX) / 2
|
|
|
- activeElements.forEach((item) => {
|
|
|
- this.projectStore.updateElement(
|
|
|
- item.key,
|
|
|
- 'container.props.x',
|
|
|
- centerX - item.container.props.width / 2
|
|
|
- )
|
|
|
- })
|
|
|
- break
|
|
|
- }
|
|
|
- case AlignEnum.VerticalCenter: {
|
|
|
- const maxY = Math.max(
|
|
|
- ...activeElements.map((item) => item.container.props.y + item.container.props.height)
|
|
|
- )
|
|
|
- const minY = Math.min(...activeElements.map((item) => item.container.props.y))
|
|
|
- const centerY = minY + (maxY - minY) / 2
|
|
|
- activeElements.forEach((item) => {
|
|
|
- this.projectStore.updateElement(
|
|
|
- item.key,
|
|
|
- 'container.props.y',
|
|
|
- centerY - item.container.props.height / 2
|
|
|
- )
|
|
|
- })
|
|
|
- break
|
|
|
- }
|
|
|
- case AlignEnum.Left: {
|
|
|
- const minX = Math.min(...activeElements.map((item) => item.container.props.x))
|
|
|
- activeElements.forEach((item) => {
|
|
|
- this.projectStore.updateElement(item.key, 'container.props.x', minX)
|
|
|
- })
|
|
|
- break
|
|
|
- }
|
|
|
- case AlignEnum.Right: {
|
|
|
- const maxX = Math.max(
|
|
|
- ...activeElements.map((item) => item.container.props.x + item.container.props.width)
|
|
|
- )
|
|
|
- activeElements.forEach((item) => {
|
|
|
- this.projectStore.updateElement(
|
|
|
- item.key,
|
|
|
- 'container.props.x',
|
|
|
- maxX - item.container.props.width
|
|
|
- )
|
|
|
- })
|
|
|
- break
|
|
|
- }
|
|
|
- case AlignEnum.Top: {
|
|
|
- const minY = Math.min(...activeElements.map((item) => item.container.props.y))
|
|
|
- activeElements.forEach((item) => {
|
|
|
- this.projectStore.updateElement(item.key, 'container.props.y', minY)
|
|
|
- })
|
|
|
- break
|
|
|
- }
|
|
|
- default:
|
|
|
- }
|
|
|
- this.addRecord()
|
|
|
- },
|
|
|
- /* 图层调整 */
|
|
|
- actionLayer(type: LayerEnum) {
|
|
|
- const activeElements = this.projectStore.currentSelectedElements
|
|
|
- const elements = cloneDeep(
|
|
|
- this.projectStore.elements.sort((a, b) => a.zIndex - b.zIndex)
|
|
|
- ) as CustomElement[]
|
|
|
-
|
|
|
- switch (type) {
|
|
|
- case LayerEnum.UP: {
|
|
|
- activeElements.forEach((item) => {
|
|
|
- const index = elements.findIndex((element) => element.key === item.key)
|
|
|
- if (item.zIndex === elements.length) return
|
|
|
- elements.splice(index, 1)
|
|
|
- elements.splice(index + 1, 0, { ...item })
|
|
|
- })
|
|
|
- elements.forEach((item, index) => {
|
|
|
- item.zIndex = index + 1
|
|
|
- })
|
|
|
- elements.forEach((item) => {
|
|
|
- this.projectStore.updateElement(item.key, 'zIndex', item.zIndex)
|
|
|
- })
|
|
|
- break
|
|
|
- }
|
|
|
- case LayerEnum.DOWN: {
|
|
|
- activeElements.forEach((item) => {
|
|
|
- const index = elements.findIndex((element) => element.key === item.key)
|
|
|
- if (item.zIndex === 1) return
|
|
|
- elements.splice(index, 1)
|
|
|
- elements.splice(index - 1, 0, { ...item })
|
|
|
- })
|
|
|
- elements.forEach((item, index) => {
|
|
|
- item.zIndex = index + 1
|
|
|
- })
|
|
|
- elements.forEach((item) => {
|
|
|
- this.projectStore.updateElement(item.key, 'zIndex', item.zIndex)
|
|
|
- })
|
|
|
- break
|
|
|
- }
|
|
|
- case LayerEnum.TOP: {
|
|
|
- activeElements.forEach((item) => {
|
|
|
- const index = elements.findIndex((element) => element.key === item.key)
|
|
|
- if (item.zIndex === elements.length) return
|
|
|
- elements.splice(index, 1)
|
|
|
- elements.push({ ...item })
|
|
|
- })
|
|
|
- elements.forEach((item, index) => {
|
|
|
- item.zIndex = index + 1
|
|
|
- })
|
|
|
- elements.forEach((item) => {
|
|
|
- this.projectStore.updateElement(item.key, 'zIndex', item.zIndex)
|
|
|
- })
|
|
|
- break
|
|
|
- }
|
|
|
- case LayerEnum.BOTTOM: {
|
|
|
- activeElements.forEach((item) => {
|
|
|
- const index = elements.findIndex((element) => element.key === item.key)
|
|
|
- if (item.zIndex === 1) return
|
|
|
- elements.splice(index, 1)
|
|
|
- elements.unshift({ ...item })
|
|
|
- })
|
|
|
- elements.forEach((item, index) => {
|
|
|
- item.zIndex = index + 1
|
|
|
- })
|
|
|
- elements.forEach((item) => {
|
|
|
- this.projectStore.updateElement(item.key, 'zIndex', item.zIndex)
|
|
|
- })
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- this.addRecord()
|
|
|
- },
|
|
|
- /* 添加组合 */
|
|
|
- actionGroup() {
|
|
|
- const elements = this.projectStore.currentSelectedElements
|
|
|
- const key = uuid()
|
|
|
- // 1、移除元素
|
|
|
- elements.forEach((element) => {
|
|
|
- this.projectStore.removeElement(element.key)
|
|
|
- })
|
|
|
- const { minX, minY, maxX, maxY, maxZIndex } = calcComboInfo(elements)
|
|
|
- const groupIndex =
|
|
|
- this.projectStore.elements.filter((item) => item.componentType === 'group').length + 1
|
|
|
- // 重新计算子元素位置
|
|
|
- elements.forEach((item) => {
|
|
|
- item.container.props.x -= minX
|
|
|
- item.container.props.y -= minY
|
|
|
- item.parentKey = key
|
|
|
- })
|
|
|
- const group: CustomElement = {
|
|
|
- key,
|
|
|
- name: '组合' + groupIndex,
|
|
|
- componentType: 'group',
|
|
|
- visible: true,
|
|
|
- locked: false,
|
|
|
- zIndex: maxZIndex,
|
|
|
- container: {
|
|
|
- style: {},
|
|
|
- props: {
|
|
|
- width: maxX - minX,
|
|
|
- height: maxY - minY,
|
|
|
- x: minX,
|
|
|
- y: minY
|
|
|
- }
|
|
|
- },
|
|
|
- children: elements,
|
|
|
- collapsed: false,
|
|
|
- events: [],
|
|
|
- animations: [],
|
|
|
- props: {}
|
|
|
- }
|
|
|
- // 2、添加组合元素
|
|
|
- this.projectStore.addElement(group)
|
|
|
- },
|
|
|
- /* 拆分组合元素 */
|
|
|
- actionUngroup() {
|
|
|
- const group = this.projectStore.currentSelectedElements[0]
|
|
|
- // 1、取出子元素
|
|
|
- const elements = group.children?.map((item) => {
|
|
|
- // 2、计算子元素位置
|
|
|
- item.container.props.x += group.container.props.x
|
|
|
- item.container.props.y += group.container.props.y
|
|
|
- delete item.parentKey
|
|
|
- return item
|
|
|
- })
|
|
|
-
|
|
|
- // 3、移除组
|
|
|
- this.projectStore.removeElement(group.key)
|
|
|
- // 4、添加子元素
|
|
|
- elements?.forEach((item) => {
|
|
|
- this.projectStore.addElement(item, undefined, true)
|
|
|
- })
|
|
|
- },
|
|
|
- /* 复制 */
|
|
|
- actionCopy() {
|
|
|
- const elements = this.projectStore.currentSelectedElements
|
|
|
- this.copyCache = JSON.stringify(elements)
|
|
|
- },
|
|
|
- /* 粘贴 */
|
|
|
- actionPaste() {
|
|
|
- if (!this.copyCache) return
|
|
|
-
|
|
|
- try {
|
|
|
- const elements = JSON.parse(this.copyCache)
|
|
|
- const offsetX = 10
|
|
|
- const offsetY = 10
|
|
|
- elements.forEach((element: CustomElement) => {
|
|
|
- element.key = uuid()
|
|
|
- element.container.props.x += offsetX
|
|
|
- element.container.props.y += offsetY
|
|
|
- this.projectStore.addElement(element)
|
|
|
- })
|
|
|
- } catch (error) {
|
|
|
- console.log(error)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-})
|