chartEditStore.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. import { defineStore } from 'pinia'
  2. import debounce from 'lodash/debounce'
  3. import { loadingStart, loadingFinish, loadingError } from '@/utils'
  4. import {
  5. chartEditStoreType,
  6. EditCanvasType,
  7. MousePositionType,
  8. TargetChartType
  9. } from './chartEditStore.d'
  10. // 编辑区域内容
  11. export const useChartEditStoreStore = defineStore({
  12. id: 'useChartEditStoreStore',
  13. state: (): chartEditStoreType => ({
  14. // 编辑画布属性
  15. editCanvas: {
  16. // 编辑区域 Dom
  17. editLayoutDom: null,
  18. editContentDom: null,
  19. // 默认宽度
  20. width: 1920,
  21. // 默认高度
  22. height: 1080,
  23. // 偏移量
  24. offset: 20,
  25. // 系统控制缩放
  26. scale: 1,
  27. // 用户控制的缩放
  28. userScale: 1,
  29. // 锁定缩放
  30. lockScale: false,
  31. // 默认背景色
  32. background: undefined
  33. },
  34. // 右键菜单
  35. rightMenuShow: false,
  36. // 鼠标定位
  37. mousePosition: {
  38. x: 0,
  39. y: 0
  40. },
  41. // 目标图表
  42. targetChart: {
  43. hoverIndex: undefined,
  44. selectIndex: undefined
  45. },
  46. // 图表数组
  47. componentList: []
  48. }),
  49. getters: {
  50. getMousePosition(): MousePositionType {
  51. return this.mousePosition
  52. },
  53. getRightMenuShow(): boolean {
  54. return this.rightMenuShow
  55. },
  56. getEditCanvas(): EditCanvasType {
  57. return this.editCanvas
  58. },
  59. getTargetChart():TargetChartType {
  60. return this.targetChart
  61. },
  62. getComponentList(): any[] {
  63. return this.componentList
  64. }
  65. },
  66. actions: {
  67. // * 设置 editCanvas 数据项
  68. setEditCanvasItem< T extends keyof EditCanvasType, K extends EditCanvasType[T] >(key: T, value: K) {
  69. this.editCanvas[key] = value
  70. },
  71. // * 设置右键菜单
  72. setRightMenuShow(value: boolean) {
  73. this.rightMenuShow = value
  74. },
  75. // * 设置目标数据 hover
  76. setTargetHoverChart(hoverIndex?:TargetChartType["hoverIndex"]) {
  77. this.targetChart.hoverIndex = hoverIndex
  78. },
  79. // * 设置目标数据 select
  80. setTargetSelectChart(selectIndex?:TargetChartType["selectIndex"]) {
  81. this.targetChart.selectIndex = selectIndex
  82. },
  83. // * 新增组件列表
  84. addComponentList<T>(chartData: T): void {
  85. this.componentList.push(chartData)
  86. },
  87. // * 删除组件列表
  88. removeComponentList<T extends { key: string }>(chartData: T | number): void {
  89. loadingStart()
  90. try {
  91. if(typeof chartData === 'number') {
  92. this.componentList.splice(chartData, 1)
  93. loadingFinish()
  94. return
  95. }
  96. const i = this.componentList.findIndex(e => e.key === chartData.key)
  97. if (i !== -1) {
  98. this.componentList.splice(i, 1)
  99. loadingFinish()
  100. return
  101. }
  102. window['$message'].success(`图表删除失败,无法找到此元素`)
  103. } catch(value) {
  104. loadingError()
  105. }
  106. },
  107. // * 设置页面样式属性
  108. setPageStyle<T extends keyof CSSStyleDeclaration>(
  109. key: T,
  110. value: any
  111. ): void {
  112. const dom = this.getEditCanvas.editContentDom
  113. if (dom) {
  114. dom.style[key] = value
  115. }
  116. },
  117. // * 设置页面变换时候的 Class
  118. setPageSizeClass(): void {
  119. const dom = this.getEditCanvas.editContentDom
  120. if (dom) {
  121. dom.classList.add('content-resize')
  122. setTimeout(() => {
  123. dom.classList.remove('content-resize')
  124. }, 600)
  125. }
  126. },
  127. // * 设置页面大小
  128. setPageSize(): void {
  129. this.setPageStyle('height', `${this.getEditCanvas.height}px`)
  130. this.setPageStyle('width', `${this.getEditCanvas.width}px`)
  131. },
  132. // * 设置鼠标位置
  133. setMousePosition(x: number, y: number): void {
  134. this.mousePosition.x = x
  135. this.mousePosition.y = y
  136. },
  137. // * 计算缩放
  138. computedScale() {
  139. if (this.getEditCanvas.editLayoutDom) {
  140. // 现有展示区域
  141. const width =
  142. this.getEditCanvas.editLayoutDom.clientWidth - this.getEditCanvas.offset * 2 - 5
  143. const height =
  144. this.getEditCanvas.editLayoutDom.clientHeight - this.getEditCanvas.offset * 4
  145. // 用户设定大小
  146. const editCanvasWidth = this.getEditCanvas.width
  147. const editCanvasHeight = this.getEditCanvas.height
  148. // 需保持的比例
  149. const baseProportion = parseFloat(
  150. (editCanvasWidth / editCanvasHeight).toFixed(5)
  151. )
  152. const currentRate = parseFloat((width / height).toFixed(5))
  153. if (currentRate > baseProportion) {
  154. // 表示更宽
  155. const scaleWidth = parseFloat(
  156. ((height * baseProportion) / editCanvasWidth).toFixed(5)
  157. )
  158. this.setScale( scaleWidth > 1 ? 1 : scaleWidth)
  159. } else {
  160. // 表示更高
  161. const scaleHeight = parseFloat(
  162. (width / baseProportion / editCanvasHeight).toFixed(5)
  163. )
  164. this.setScale(scaleHeight > 1 ? 1 : scaleHeight)
  165. }
  166. } else {
  167. window['$message'].warning('请先创建画布,再进行缩放')
  168. }
  169. },
  170. // * 监听缩放
  171. listenerScale(): Function {
  172. const resize = debounce(this.computedScale, 200)
  173. // 默认执行一次
  174. resize()
  175. // 开始监听
  176. window.addEventListener('resize', resize)
  177. // 销毁函数
  178. const remove = () => {
  179. window.removeEventListener('resize', resize)
  180. }
  181. return remove
  182. },
  183. // * 设置缩放
  184. setScale(scale: number, sys = true): void {
  185. if (!this.getEditCanvas.lockScale) {
  186. this.setPageSizeClass()
  187. this.setPageStyle('transform', `scale(${scale})`)
  188. this.getEditCanvas.userScale = scale
  189. if (sys) {
  190. this.getEditCanvas.scale = scale
  191. }
  192. }
  193. }
  194. }
  195. })