useBoard.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import boardFactory, { BoardShape, MetaShapeType } from "./";
  2. import { getCaseInfo } from "@/store/case";
  3. import { BoardData, getCaseFileImageInfo } from "@/store/caseFile";
  4. import { Board } from "./";
  5. import { Ref, ref, watch, watchEffect } from "vue";
  6. import { BoardType } from "@/store/caseFile";
  7. import { BoardTypeDesc } from "@/constant/caseFile";
  8. const defaultStore = {
  9. id: -1,
  10. version: "v4.0",
  11. floors: [
  12. {
  13. points: {},
  14. walls: {},
  15. tags: {},
  16. rectangles: {},
  17. circles: {},
  18. arrows: {},
  19. icons: {},
  20. signs: {},
  21. title: {
  22. len: null,
  23. value: "某某案发现场",
  24. height: 50,
  25. floor: 0,
  26. geoType: "Title",
  27. vectorId: "Title6",
  28. },
  29. image: {
  30. len: null,
  31. image: null,
  32. floor: 0,
  33. geoType: "BgImage",
  34. vectorId: "BgImage8",
  35. },
  36. compass: {
  37. len: null,
  38. angle: 0,
  39. floor: 0,
  40. center: {
  41. x: 800,
  42. y: 70,
  43. },
  44. radius: 52,
  45. geoType: "Compass",
  46. vectorId: "Compass7",
  47. },
  48. },
  49. ],
  50. currentId: 20,
  51. shapes: [],
  52. };
  53. const getStore = async (caseId: number, fileId: number, type: BoardType) => {
  54. let data: BoardData;
  55. if (fileId === -1) {
  56. const info = await getCaseInfo(caseId);
  57. defaultStore.floors[0].title.value =
  58. info.caseTitle + "案发" + BoardTypeDesc[type];
  59. data = { ...defaultStore };
  60. } else {
  61. const fileInfo = await getCaseFileImageInfo(fileId);
  62. data = {
  63. ...fileInfo.content,
  64. id: fileInfo.filesId,
  65. };
  66. }
  67. return data;
  68. };
  69. export type BoardProps = {
  70. caseId: number;
  71. fileId: number;
  72. type: BoardType;
  73. dom: HTMLCanvasElement;
  74. };
  75. export type BoardState = {
  76. backDisabled: boolean;
  77. forwardDisabled: boolean;
  78. selectShape: BoardShape | null;
  79. addShape: MetaShapeType | null;
  80. };
  81. export const useBoard = (props: Ref<BoardProps | null>) => {
  82. const board = ref<Board>();
  83. const state = ref<BoardState>({
  84. backDisabled: true,
  85. forwardDisabled: true,
  86. selectShape: null,
  87. addShape: null,
  88. });
  89. watchEffect(async (onCleanup) => {
  90. if (!props.value) {
  91. board.value = undefined;
  92. return;
  93. }
  94. onCleanup(() => {
  95. boardRaw && boardRaw.destroy();
  96. });
  97. const store = await getStore(
  98. props.value.caseId,
  99. props.value.fileId,
  100. props.value.type
  101. );
  102. const boardRaw = (board.value = await boardFactory(store, props.value.dom));
  103. });
  104. watchEffect(
  105. () => {
  106. if (!props.value || !board.value) {
  107. return;
  108. }
  109. if (props.value.fileId === -1) {
  110. board.value
  111. .calcTableShape([
  112. ["案发时间", ""],
  113. ["案发地点", ""],
  114. ["绘图单位", ""],
  115. ["绘图人", ""],
  116. ["绘图时间", ""],
  117. ])
  118. .then((data) => {
  119. board.value!.setDefaultTable(data.content, null);
  120. board.value!.initHistory();
  121. });
  122. } else {
  123. board.value.initHistory();
  124. }
  125. },
  126. { flush: "post" }
  127. );
  128. watchEffect((onCleanup) => {
  129. if (!board.value) {
  130. return;
  131. }
  132. const boardRaw = board.value;
  133. console.log("开启监听");
  134. boardRaw.bus.on("backDisabled", (dis) => (state.value.backDisabled = dis));
  135. boardRaw.bus.on(
  136. "forwardDisabled",
  137. (dis) => (state.value.forwardDisabled = dis)
  138. );
  139. boardRaw.bus.on("selectShape", (val) => {
  140. if (!val) {
  141. state.value.selectShape = null;
  142. return;
  143. }
  144. state.value.selectShape = val;
  145. });
  146. onCleanup(() => {
  147. boardRaw.bus.off("*" as any);
  148. });
  149. });
  150. watchEffect((onCleanup) => {
  151. if (board.value && state.value.addShape) {
  152. const cleaup = board.value.readyAddShape(
  153. state.value.addShape,
  154. () => (state.value.addShape = null)
  155. );
  156. const keyupHandler = (ev: KeyboardEvent) => {
  157. if (ev.key === "Escape") {
  158. state.value.addShape = null;
  159. cleaup();
  160. }
  161. };
  162. document.documentElement.addEventListener("keyup", keyupHandler);
  163. onCleanup(() => {
  164. document.documentElement.removeEventListener("keyup", keyupHandler);
  165. });
  166. }
  167. });
  168. return {
  169. board,
  170. state,
  171. };
  172. };
  173. export * from "./";