531 lines
16 KiB
TypeScript
Raw Normal View History

2022-01-19 21:29:04 +08:00
import { defineStore } from 'pinia'
2022-02-03 22:54:31 +08:00
import { getUUID, loadingStart, loadingFinish, loadingError } from '@/utils'
2022-02-01 01:20:00 +08:00
import { CreateComponentType } from '@/packages/index.d'
2022-02-03 22:54:31 +08:00
import debounce from 'lodash/debounce'
import cloneDeep from 'lodash/cloneDeep'
2022-02-21 19:45:11 +08:00
import { defaultTheme, globalThemeJson } from '@/settings/chartThemes/index'
2022-02-06 01:04:05 +08:00
// 记录记录
import { useChartHistoryStoreStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
import { HistoryActionTypeEnum, HistoryItemType, HistoryTargetTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
2022-01-20 21:25:35 +08:00
import {
chartEditStoreType,
EditCanvasType,
2022-01-29 21:44:22 +08:00
MousePositionType,
2022-02-04 12:17:50 +08:00
TargetChartType,
2022-02-06 01:04:05 +08:00
RecordChartType,
EditCanvasConfigType
2022-01-20 21:25:35 +08:00
} from './chartEditStore.d'
2022-01-19 21:29:04 +08:00
2022-02-03 22:54:31 +08:00
const chartHistoryStoreStore = useChartHistoryStoreStore()
2022-01-20 21:25:35 +08:00
// 编辑区域内容
2022-01-19 21:29:04 +08:00
export const useChartEditStoreStore = defineStore({
id: 'useChartEditStoreStore',
2022-01-20 21:25:35 +08:00
state: (): chartEditStoreType => ({
2022-02-06 01:04:05 +08:00
// 画布属性
2022-01-20 21:25:35 +08:00
editCanvas: {
// 编辑区域 Dom
2022-01-24 14:28:31 +08:00
editLayoutDom: null,
editContentDom: null,
2022-01-20 21:25:35 +08:00
// 偏移量
offset: 20,
2022-02-04 12:19:02 +08:00
// 系统控制缩放
2022-01-20 21:25:35 +08:00
scale: 1,
2022-01-20 22:13:51 +08:00
// 用户控制的缩放
userScale: 1,
2022-01-20 21:25:35 +08:00
// 锁定缩放
lockScale: false,
// 拖拽中
isDrag: false
2022-02-06 01:04:05 +08:00
},
2022-02-21 19:45:11 +08:00
// 右键菜单
rightMenuShow: false,
// 鼠标定位
mousePosition: {
x: 0,
y: 0
},
// 目标图表
targetChart: {
hoverId: undefined,
selectId: undefined
},
// 记录临时数据(复制等)
recordChart: undefined,
2022-02-06 01:04:05 +08:00
// 画布属性(需存储给后端)
editCanvasConfig: {
// 默认宽度
width: 1920,
// 默认高度
height: 1080,
// 色相
hueRotate: 0,
// 饱和度
saturate: 0,
// 亮度
brightness: 100,
// 对比度
contrast: 100,
// 不透明度
unOpacity: 100,
2022-01-20 21:25:35 +08:00
// 默认背景色
2022-02-06 01:04:05 +08:00
background: undefined,
2022-02-06 21:35:38 +08:00
backgroundImage: undefined,
// 是否使用纯颜色
selectColor: true,
2022-02-06 01:04:05 +08:00
// chart 主题色
2022-02-21 19:45:11 +08:00
chartThemeColor: defaultTheme || 'dark',
// 全局配置
chartThemeSetting: globalThemeJson
2022-01-20 21:25:35 +08:00
},
2022-02-06 01:04:05 +08:00
// 图表数组(需存储给后端)
2022-01-24 21:12:18 +08:00
componentList: []
2022-01-20 21:25:35 +08:00
}),
getters: {
getMousePosition(): MousePositionType {
return this.mousePosition
},
getRightMenuShow(): boolean {
return this.rightMenuShow
},
2022-01-20 21:25:35 +08:00
getEditCanvas(): EditCanvasType {
return this.editCanvas
},
2022-02-06 01:04:05 +08:00
getEditCanvasConfig(): EditCanvasConfigType {
return this.editCanvasConfig
},
2022-01-29 21:44:22 +08:00
getTargetChart():TargetChartType {
return this.targetChart
},
2022-02-04 12:17:50 +08:00
getRecordChart(): RecordChartType | undefined {
return this.recordChart
2022-02-03 22:54:31 +08:00
},
2022-02-01 20:57:54 +08:00
getComponentList(): CreateComponentType[] {
2022-01-24 21:12:18 +08:00
return this.componentList
2022-01-25 18:19:44 +08:00
}
2022-01-20 21:25:35 +08:00
},
actions: {
2022-01-29 21:44:22 +08:00
// * 设置 editCanvas 数据项
setEditCanvas<T extends keyof EditCanvasType, K extends EditCanvasType[T]>(key: T, value: K) {
2022-01-29 21:44:22 +08:00
this.editCanvas[key] = value
},
setEditCanvasConfig<T extends keyof EditCanvasConfigType, K extends EditCanvasConfigType[T]>(key: T, value: K) {
2022-02-06 01:04:05 +08:00
this.editCanvasConfig[key] = value
},
// * 设置右键菜单
setRightMenuShow(value: boolean) {
this.rightMenuShow = value
},
2022-01-29 23:58:56 +08:00
// * 设置目标数据 hover
2022-02-01 01:20:00 +08:00
setTargetHoverChart(hoverId?:TargetChartType["hoverId"]) {
this.targetChart.hoverId = hoverId
2022-01-29 21:44:22 +08:00
},
2022-01-29 23:58:56 +08:00
// * 设置目标数据 select
2022-02-01 01:20:00 +08:00
setTargetSelectChart(selectId?:TargetChartType["selectId"]) {
this.targetChart.selectId = selectId
2022-01-29 21:44:22 +08:00
},
2022-02-03 22:54:31 +08:00
// * 设置记录数据
2022-02-04 12:17:50 +08:00
setRecordChart(item: RecordChartType | undefined) {
this.recordChart = cloneDeep(item)
2022-02-03 22:54:31 +08:00
},
2022-02-01 17:12:16 +08:00
// * 找到目标 id 数据下标位置
fetchTargetIndex(): number {
const index = this.componentList.findIndex(e => e.id === this.getTargetChart.selectId)
if (index === -1) {
loadingError()
}
return index
},
2022-02-03 22:54:31 +08:00
/**
* *
* @param chartData
* @param isEnd
* @param isHistory
2022-02-04 12:19:02 +08:00
* @returns
2022-02-03 22:54:31 +08:00
*/
addComponentList(chartData: CreateComponentType, isEnd = false, isHistory = false): void {
2022-02-04 18:28:02 +08:00
if (isHistory) {
2022-02-03 22:54:31 +08:00
chartHistoryStoreStore.createAddHistory(chartData)
}
2022-02-04 18:28:02 +08:00
if (isEnd) {
2022-02-01 17:12:16 +08:00
this.componentList.unshift(chartData)
return
}
2022-01-24 21:12:18 +08:00
this.componentList.push(chartData)
},
2022-01-25 18:19:44 +08:00
// * 删除组件列表
2022-02-04 18:28:02 +08:00
removeComponentList(isHistory = true): void {
2022-01-27 23:16:51 +08:00
try {
2022-02-01 17:12:16 +08:00
loadingStart()
const index = this.fetchTargetIndex()
if (index !== -1) {
2022-02-04 18:28:02 +08:00
isHistory ? chartHistoryStoreStore.createDeleteHistory(this.getComponentList[index]) : undefined
2022-02-01 17:12:16 +08:00
this.componentList.splice(index, 1)
loadingFinish()
return
}
} catch(value) {
loadingError()
}
},
2022-02-01 20:57:54 +08:00
// * 更新组件列表某一项的值
updateComponentList(index: number, newData: CreateComponentType) {
2022-02-04 18:28:02 +08:00
if (index < 1 && index > this.getComponentList.length) return
2022-02-01 20:57:54 +08:00
this.componentList[index] = newData
},
2022-02-03 22:54:31 +08:00
// * 设置页面样式属性
setPageStyle<T extends keyof CSSStyleDeclaration>(
key: T,
value: any
): void {
const dom = this.getEditCanvas.editContentDom
if (dom) {
dom.style[key] = value
}
},
2022-02-01 20:57:54 +08:00
// * 移动组件列表位置到两端
2022-02-04 18:28:02 +08:00
setBothEnds(isEnd = false, isHistory = true): void {
2022-02-01 17:12:16 +08:00
try {
loadingStart()
const length = this.getComponentList.length
2022-02-04 18:28:02 +08:00
if (length < 2) {
2022-02-01 20:57:54 +08:00
loadingFinish()
return
}
2022-02-01 17:12:16 +08:00
const index = this.fetchTargetIndex()
2022-02-04 18:28:02 +08:00
const targetData = this.getComponentList[index]
2022-02-01 17:12:16 +08:00
if (index !== -1) {
// 置底排除最底层, 置顶排除最顶层
2022-02-04 12:19:02 +08:00
if ((isEnd && index === 0) || (!isEnd && index === length - 1 )) {
2022-02-01 17:12:16 +08:00
loadingFinish()
return
}
2022-02-04 18:28:02 +08:00
// 记录原有位置
const setIndex = (t:CreateComponentType, i:number) => {
const temp = cloneDeep(t)
temp.attr.zIndex = i
return temp
}
// 历史记录
if (isHistory) {
chartHistoryStoreStore.createLaryerHistory(
setIndex(targetData, index),
isEnd ? HistoryActionTypeEnum.BOTTOM : HistoryActionTypeEnum.TOP
)
}
2022-02-01 17:12:16 +08:00
// 插入两端
2022-02-04 18:28:02 +08:00
this.addComponentList(targetData, isEnd)
2022-02-01 17:12:16 +08:00
this.getComponentList.splice(isEnd ? index + 1: index, 1)
2022-01-27 23:16:51 +08:00
loadingFinish()
return
}
} catch(value) {
loadingError()
2022-01-27 22:30:35 +08:00
}
2022-01-25 18:19:44 +08:00
},
2022-02-01 17:12:16 +08:00
// * 置顶
2022-02-04 18:28:02 +08:00
setTop(isHistory = true): void {
this.setBothEnds(false, isHistory)
2022-02-01 17:12:16 +08:00
},
// * 置底
2022-02-04 18:28:02 +08:00
setBottom(isHistory = true): void {
this.setBothEnds(true, isHistory)
2022-02-01 17:12:16 +08:00
},
2022-02-01 20:57:54 +08:00
// * 互换图表位置
2022-02-04 18:28:02 +08:00
wrap(isDown = false, isHistory = true) {
2022-02-01 20:57:54 +08:00
try {
loadingStart()
const length = this.getComponentList.length
2022-02-04 12:19:02 +08:00
if (length < 2) {
2022-02-01 20:57:54 +08:00
loadingFinish()
return
}
const index:number = this.fetchTargetIndex()
if (index !== -1) {
// 下移排除最底层, 上移排除最顶层
if ((isDown && index === 0) || (!isDown && index === length - 1)) {
loadingFinish()
return
}
// 互换位置
const swapIndex = isDown ? index - 1 : index + 1
const targetItem = this.getComponentList[index]
const swapItem = this.getComponentList[swapIndex]
2022-02-04 12:19:02 +08:00
2022-02-04 18:28:02 +08:00
// 历史记录
if (isHistory) {
chartHistoryStoreStore.createLaryerHistory(
targetItem,
isDown ? HistoryActionTypeEnum.DOWN : HistoryActionTypeEnum.UP
)
}
2022-02-01 20:57:54 +08:00
this.updateComponentList(index, swapItem)
this.updateComponentList(swapIndex, targetItem)
loadingFinish()
return
}
} catch(value) {
loadingError()
}
},
// * 上移
2022-02-04 18:28:02 +08:00
setUp(isHistory = true) {
this.wrap(false, isHistory)
2022-02-01 20:57:54 +08:00
},
// * 下移
2022-02-04 18:28:02 +08:00
setDown(isHistory = true) {
this.wrap(true, isHistory)
2022-02-01 20:57:54 +08:00
},
2022-02-03 22:54:31 +08:00
// * 复制
2022-02-04 12:17:50 +08:00
setCopy(isCut = false) {
2022-02-03 22:54:31 +08:00
try {
loadingStart()
const index:number = this.fetchTargetIndex()
if (index !== -1) {
2022-02-04 12:17:50 +08:00
const copyData:RecordChartType = {
charts :this.getComponentList[index],
type: isCut ? HistoryActionTypeEnum.CUT : HistoryActionTypeEnum.COPY
}
this.setRecordChart(copyData)
window['$message'].success(isCut ? '剪切成功' : '复制成功!')
2022-02-03 22:54:31 +08:00
loadingFinish()
}
} catch(value) {
loadingError()
}
},
2022-02-04 12:17:50 +08:00
// * 剪切
setCut() {
this.setCopy(true)
},
2022-02-03 22:54:31 +08:00
// * 粘贴
setParse() {
try {
loadingStart()
2022-02-04 12:17:50 +08:00
const recordCharts = this.getRecordChart
2022-02-03 22:54:31 +08:00
if (recordCharts === undefined) {
loadingFinish()
return
}
const parseHandle = (e: CreateComponentType) => {
e = cloneDeep(e)
// 生成新 id
e.id = getUUID()
// 偏移位置
e.attr.x = e.attr.x + 30
e.attr.y = e.attr.y + 30
return e
}
2022-02-04 12:17:50 +08:00
const isCut = recordCharts.type === HistoryActionTypeEnum.CUT
// 多项
if (Array.isArray(recordCharts.charts)) {
recordCharts.charts.forEach((e: CreateComponentType) => {
2022-02-03 22:54:31 +08:00
this.addComponentList(parseHandle(e), undefined, true)
2022-02-04 12:17:50 +08:00
// 剪切需删除原数据
if (isCut) {
this.setTargetSelectChart(e.id)
2022-02-04 18:28:02 +08:00
this.removeComponentList(true)
2022-02-04 12:17:50 +08:00
}
2022-02-03 22:54:31 +08:00
})
2022-02-04 12:17:50 +08:00
if (isCut) this.setRecordChart(undefined)
2022-02-03 22:54:31 +08:00
loadingFinish()
return
}
2022-02-04 12:17:50 +08:00
// 单项
this.addComponentList(parseHandle(recordCharts.charts), undefined, true)
2022-02-04 18:28:02 +08:00
if (isCut) {
2022-02-04 12:17:50 +08:00
this.setTargetSelectChart(recordCharts.charts.id)
this.removeComponentList()
this.setRecordChart(undefined)
}
2022-02-03 22:54:31 +08:00
loadingFinish()
2022-02-04 12:19:02 +08:00
} catch(value) {
2022-02-03 22:54:31 +08:00
loadingError()
}
},
2022-02-04 18:28:02 +08:00
// * 撤回/前进 目标处理
2022-02-04 12:17:50 +08:00
setBackAndSetForwardHandle(item: HistoryItemType, isForward = false) {
2022-02-04 18:28:02 +08:00
// 处理画布
if (item.targetType === HistoryTargetTypeEnum.CANVAS) {
this.editCanvas = item.historyData as EditCanvasType
2022-02-04 12:17:50 +08:00
return
}
2022-02-04 18:28:02 +08:00
const historyData = item.historyData as CreateComponentType
// 处理新增类型
const isAdd = item.actionType === HistoryActionTypeEnum.ADD
const isDel = item.actionType === HistoryActionTypeEnum.DELETE
this.setTargetSelectChart(historyData.id)
if (isAdd || isDel) {
if ((isAdd && isForward) || (isDel && !isForward)) {
this.addComponentList(historyData)
return
}
this.removeComponentList(false)
return
}
// 处理层级
const isTop = item.actionType === HistoryActionTypeEnum.TOP
const isBottom = item.actionType === HistoryActionTypeEnum.BOTTOM
if (isTop || isBottom) {
if (!isForward) {
// 插入到原有位置
if (isTop) this.getComponentList.pop()
if (isBottom) this.getComponentList.shift()
this.getComponentList.splice(historyData.attr.zIndex, 0, historyData)
return
}
if (isTop) this.setTop(false)
if (isBottom) this.setBottom(false)
}
const isUp = item.actionType === HistoryActionTypeEnum.UP
const isDown = item.actionType === HistoryActionTypeEnum.DOWN
if (isUp || isDown) {
if ((isUp && isForward) || (isDown && !isForward)) {
this.setUp(false)
return
}
this.setDown(false)
return
}
// 处理内容修改
this.getComponentList[this.fetchTargetIndex()] = item.historyData as CreateComponentType
2022-02-04 12:17:50 +08:00
},
// * 撤回
setBack() {
try {
loadingStart()
const targetData = chartHistoryStoreStore.backAction()
if (!targetData) {
loadingFinish()
return
}
if (Array.isArray(targetData)) {
targetData.forEach((e: HistoryItemType) => {
this.setBackAndSetForwardHandle(e)
})
loadingFinish()
2022-02-04 12:19:02 +08:00
return
2022-02-04 12:17:50 +08:00
}
this.setBackAndSetForwardHandle(targetData)
loadingFinish()
2022-02-04 12:19:02 +08:00
} catch(value) {
2022-02-04 12:17:50 +08:00
loadingError()
}
},
// * 前进
setForward() {
try {
loadingStart()
const targetData = chartHistoryStoreStore.forwardAction()
if (!targetData) {
loadingFinish()
return
}
if (Array.isArray(targetData)) {
targetData.forEach((e: HistoryItemType) => {
this.setBackAndSetForwardHandle(e, true)
})
loadingFinish()
2022-02-04 12:19:02 +08:00
return
2022-02-04 12:17:50 +08:00
}
this.setBackAndSetForwardHandle(targetData, true)
loadingFinish()
2022-02-04 12:19:02 +08:00
} catch(value) {
2022-02-04 12:17:50 +08:00
loadingError()
}
},
// ----------------
2022-02-03 22:54:31 +08:00
// * 设置鼠标位置
setMousePosition(x: number, y: number): void {
this.mousePosition.x = x
this.mousePosition.y = y
},
// * 设置页面变换时候的 Class
setPageSizeClass(): void {
const dom = this.getEditCanvas.editContentDom
if (dom) {
dom.classList.add('content-resize')
setTimeout(() => {
dom.classList.remove('content-resize')
2022-01-25 18:19:44 +08:00
}, 600)
}
},
2022-01-20 21:25:35 +08:00
// * 设置页面大小
setPageSize(): void {
2022-02-06 01:04:05 +08:00
this.setPageStyle('height', `${this.editCanvasConfig.height}px`)
this.setPageStyle('width', `${this.editCanvasConfig.width}px`)
2022-01-20 21:25:35 +08:00
},
// * 计算缩放
computedScale() {
2022-01-20 22:13:51 +08:00
if (this.getEditCanvas.editLayoutDom) {
2022-01-20 21:25:35 +08:00
// 现有展示区域
2022-01-20 22:13:51 +08:00
const width =
this.getEditCanvas.editLayoutDom.clientWidth - this.getEditCanvas.offset * 2 - 5
const height =
this.getEditCanvas.editLayoutDom.clientHeight - this.getEditCanvas.offset * 4
2022-01-20 21:25:35 +08:00
// 用户设定大小
2022-02-06 01:04:05 +08:00
const editCanvasWidth = this.editCanvasConfig.width
const editCanvasHeight = this.editCanvasConfig.height
2022-01-20 21:25:35 +08:00
2022-01-20 22:13:51 +08:00
// 需保持的比例
const baseProportion = parseFloat(
(editCanvasWidth / editCanvasHeight).toFixed(5)
)
const currentRate = parseFloat((width / height).toFixed(5))
2022-01-20 21:25:35 +08:00
if (currentRate > baseProportion) {
// 表示更宽
2022-01-20 22:13:51 +08:00
const scaleWidth = parseFloat(
((height * baseProportion) / editCanvasWidth).toFixed(5)
)
2022-01-28 20:54:13 +08:00
this.setScale( scaleWidth > 1 ? 1 : scaleWidth)
2022-01-20 21:25:35 +08:00
} else {
// 表示更高
2022-01-20 22:13:51 +08:00
const scaleHeight = parseFloat(
(width / baseProportion / editCanvasHeight).toFixed(5)
)
2022-01-28 20:54:13 +08:00
this.setScale(scaleHeight > 1 ? 1 : scaleHeight)
2022-01-20 21:25:35 +08:00
}
} else {
2022-01-23 19:22:54 +08:00
window['$message'].warning('请先创建画布,再进行缩放')
2022-01-20 21:25:35 +08:00
}
},
// * 监听缩放
listenerScale(): Function {
const resize = debounce(this.computedScale, 200)
// 默认执行一次
resize()
// 开始监听
window.addEventListener('resize', resize)
// 销毁函数
const remove = () => {
window.removeEventListener('resize', resize)
}
return remove
},
// * 设置缩放
2022-01-20 22:13:51 +08:00
setScale(scale: number, sys = true): void {
if (!this.getEditCanvas.lockScale) {
this.setPageSizeClass()
this.setPageStyle('transform', `scale(${scale})`)
2022-01-21 17:55:35 +08:00
this.getEditCanvas.userScale = scale
if (sys) {
this.getEditCanvas.scale = scale
}
2022-01-20 22:13:51 +08:00
}
2022-01-20 21:25:35 +08:00
}
}
2022-01-23 19:22:54 +08:00
})