useCreateElement.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import { useStore } from 'vuex'
  2. import { MutationTypes } from '@/store'
  3. import { createRandomCode } from '@/utils/common'
  4. import { getImageSize } from '@/utils/image'
  5. import { VIEWPORT_SIZE, VIEWPORT_ASPECT_RATIO } from '@/configs/canvas'
  6. import { PPTElement, TableElementCell } from '@/types/slides'
  7. import {
  8. DEFAULT_IMAGE,
  9. DEFAULT_TEXT,
  10. DEFAULT_SHAPE,
  11. DEFAULT_LINE,
  12. DEFAULT_CHART,
  13. DEFAULT_TABLE,
  14. } from '@/configs/element'
  15. import useHistorySnapshot from '@/hooks/useHistorySnapshot'
  16. interface CommonElementPosition {
  17. top: number;
  18. left: number;
  19. width: number;
  20. height: number;
  21. }
  22. interface LineElementPosition {
  23. top: number;
  24. left: number;
  25. start: [number, number];
  26. end: [number, number];
  27. }
  28. export default () => {
  29. const store = useStore()
  30. const { addHistorySnapshot } = useHistorySnapshot()
  31. const createElement = (element: PPTElement) => {
  32. store.commit(MutationTypes.ADD_ELEMENT, element)
  33. store.commit(MutationTypes.SET_ACTIVE_ELEMENT_ID_LIST, [element.id])
  34. addHistorySnapshot()
  35. }
  36. const createImageElement = (src: string) => {
  37. getImageSize(src).then(({ width, height }) => {
  38. const scale = width / height
  39. if(scale < VIEWPORT_ASPECT_RATIO && width > VIEWPORT_SIZE) {
  40. width = VIEWPORT_SIZE
  41. height = width * scale
  42. }
  43. else if(height > VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO) {
  44. height = VIEWPORT_SIZE * VIEWPORT_ASPECT_RATIO
  45. width = height / scale
  46. }
  47. createElement({
  48. ...DEFAULT_IMAGE,
  49. type: 'image',
  50. id: createRandomCode(),
  51. src,
  52. width,
  53. height,
  54. })
  55. })
  56. }
  57. const createChartElement = (chartType: string, data: string) => {
  58. createElement({
  59. ...DEFAULT_CHART,
  60. type: 'chart',
  61. id: createRandomCode(),
  62. chartType,
  63. data,
  64. })
  65. }
  66. const createTableElement = (rowCount: number, colCount: number) => {
  67. const row: TableElementCell[] = new Array(colCount).fill({ colspan: 1, rowspan: 1, content: '' })
  68. const data: TableElementCell[][] = new Array(rowCount).fill(row)
  69. const DEFAULT_CELL_WIDTH = 80
  70. const DEFAULT_CELL_HEIGHT = 35
  71. const DEFAULT_BORDER_WIDTH = 2
  72. const colSizes: number[] = new Array(colCount).fill(DEFAULT_CELL_WIDTH)
  73. const rowSizes: number[] = new Array(rowCount).fill(DEFAULT_CELL_HEIGHT)
  74. createElement({
  75. ...DEFAULT_TABLE,
  76. type: 'table',
  77. id: createRandomCode(),
  78. width: colCount * DEFAULT_CELL_WIDTH + DEFAULT_BORDER_WIDTH,
  79. height: rowCount * DEFAULT_CELL_HEIGHT + DEFAULT_BORDER_WIDTH,
  80. colSizes,
  81. rowSizes,
  82. data,
  83. })
  84. }
  85. const createTextElement = (position: CommonElementPosition) => {
  86. const { left, top, width, height } = position
  87. createElement({
  88. ...DEFAULT_TEXT,
  89. type: 'text',
  90. id: createRandomCode(),
  91. left,
  92. top,
  93. width,
  94. height,
  95. })
  96. }
  97. const createShapeElement = (position: CommonElementPosition, path: string, viewBox: number) => {
  98. const { left, top, width, height } = position
  99. createElement({
  100. ...DEFAULT_SHAPE,
  101. type: 'shape',
  102. id: createRandomCode(),
  103. left,
  104. top,
  105. width,
  106. height,
  107. viewBox,
  108. path,
  109. })
  110. }
  111. const createLineElement = (position: LineElementPosition, points: [string, string]) => {
  112. const { left, top, start, end } = position
  113. createElement({
  114. ...DEFAULT_LINE,
  115. type: 'line',
  116. id: createRandomCode(),
  117. left,
  118. top,
  119. start,
  120. end,
  121. points,
  122. })
  123. }
  124. return {
  125. createImageElement,
  126. createChartElement,
  127. createTableElement,
  128. createTextElement,
  129. createShapeElement,
  130. createLineElement,
  131. }
  132. }