@idraw/core 0.4.0-alpha.3 → 0.4.0-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,12 +2,14 @@ import { calcElementsViewInfo, calcElementVertexesInGroup, calcElementQueueVerte
2
2
  import { drawHoverVertexesWrapper, drawArea, drawListArea, drawGroupQueueVertexesWrappers, drawSelectedElementControllersVertexes } from './draw-wrapper';
3
3
  import { getPointTarget, resizeElement, getSelectedListArea, calcSelectedElementsArea, isElementInGroup, isPointInViewActiveGroup, calcMoveInGroup } from './util';
4
4
  import { key, keyActionType, keyResizeType, keyAreaStart, keyAreaEnd, keyGroupQueue, keyGroupQueueVertexesList, keyHoverElement, keyHoverElementVertexes, keySelectedElementList, keySelectedElementListVertexes, keySelectedElementController } from './config';
5
+ import { middlewareEventTextEdit } from '../text-editor';
6
+ export const middlewareEventSelect = '@middleware/select';
5
7
  export const MiddlewareSelector = (opts) => {
6
8
  const { viewer, sharer, viewContent, calculator, eventHub } = opts;
7
9
  const { helperContext } = viewContent;
8
10
  let prevPoint = null;
9
11
  let inBusyMode = null;
10
- eventHub.on('select', ({ uuids }) => {
12
+ eventHub.on(middlewareEventSelect, ({ uuids }) => {
11
13
  const actionType = sharer.getSharedStorage(keyActionType);
12
14
  const data = sharer.getActiveStorage('data');
13
15
  const elements = findElementsFromList(uuids, (data === null || data === void 0 ? void 0 : data.elements) || []);
@@ -76,7 +78,7 @@ export const MiddlewareSelector = (opts) => {
76
78
  sharer.setSharedStorage(keySelectedElementController, null);
77
79
  }
78
80
  if ((opts === null || opts === void 0 ? void 0 : opts.triggerEvent) === true) {
79
- eventHub.trigger('select', { uuids: list.map((elem) => elem.uuid) });
81
+ eventHub.trigger(middlewareEventSelect, { uuids: list.map((elem) => elem.uuid) });
80
82
  }
81
83
  };
82
84
  const pointTargetBaseOptions = () => {
@@ -384,7 +386,7 @@ export const MiddlewareSelector = (opts) => {
384
386
  viewer.drawFrame();
385
387
  },
386
388
  doubleClick(e) {
387
- var _a;
389
+ var _a, _b;
388
390
  const target = getPointTarget(e.point, pointTargetBaseOptions());
389
391
  if (target.elements.length === 1 && ((_a = target.elements[0]) === null || _a === void 0 ? void 0 : _a.type) === 'group') {
390
392
  const pushResult = pushGroupQueue(target.elements[0]);
@@ -394,6 +396,13 @@ export const MiddlewareSelector = (opts) => {
394
396
  return;
395
397
  }
396
398
  }
399
+ else if (target.elements.length === 1 && ((_b = target.elements[0]) === null || _b === void 0 ? void 0 : _b.type) === 'text') {
400
+ eventHub.trigger(middlewareEventTextEdit, {
401
+ element: target.elements[0],
402
+ groupQueue: sharer.getSharedStorage(keyGroupQueue) || [],
403
+ viewScaleInfo: sharer.getActiveViewScaleInfo()
404
+ });
405
+ }
397
406
  sharer.setSharedStorage(keyActionType, null);
398
407
  },
399
408
  beforeDrawFrame({ snapshot }) {
@@ -0,0 +1,3 @@
1
+ import type { BoardMiddleware, CoreEvent } from '@idraw/types';
2
+ export declare const middlewareEventTextEdit = "@middleware/text-edit";
3
+ export declare const MiddlewareTextEditor: BoardMiddleware<Record<string, any>, CoreEvent>;
@@ -0,0 +1,132 @@
1
+ import { limitAngle, getDefaultElementDetailConfig } from '@idraw/util';
2
+ export const middlewareEventTextEdit = '@middleware/text-edit';
3
+ const defaultElementDetail = getDefaultElementDetailConfig();
4
+ export const MiddlewareTextEditor = (opts) => {
5
+ const key = 'SELECT';
6
+ const { eventHub, viewContent, viewer } = opts;
7
+ const canvas = viewContent.boardContext.canvas;
8
+ const textarea = document.createElement('textarea');
9
+ const canvasWrapper = document.createElement('div');
10
+ const container = opts.container || document.body;
11
+ const mask = document.createElement('div');
12
+ let activeElem = null;
13
+ canvasWrapper.appendChild(textarea);
14
+ canvasWrapper.style.position = 'absolute';
15
+ mask.appendChild(canvasWrapper);
16
+ mask.style.position = 'fixed';
17
+ mask.style.top = '0';
18
+ mask.style.bottom = '0';
19
+ mask.style.left = '0';
20
+ mask.style.right = '0';
21
+ mask.style.display = 'none';
22
+ container.appendChild(mask);
23
+ const showTextArea = (e) => {
24
+ resetCanvasWrapper();
25
+ resetTextArea(e);
26
+ mask.style.display = 'block';
27
+ };
28
+ const hideTextArea = () => {
29
+ mask.style.display = 'none';
30
+ activeElem = null;
31
+ };
32
+ const getCanvasRect = () => {
33
+ const clientRect = canvas.getBoundingClientRect();
34
+ const { left, top, width, height } = clientRect;
35
+ return { left, top, width, height };
36
+ };
37
+ const createBox = (opts) => {
38
+ const { size, parent } = opts;
39
+ const div = document.createElement('div');
40
+ const { x, y, w, h } = size;
41
+ const angle = limitAngle(size.angle || 0);
42
+ div.style.position = 'absolute';
43
+ div.style.left = `${x}px`;
44
+ div.style.top = `${y}px`;
45
+ div.style.width = `${w}px`;
46
+ div.style.height = `${h}px`;
47
+ div.style.transform = `rotate(${angle}deg)`;
48
+ parent.appendChild(div);
49
+ return div;
50
+ };
51
+ const resetTextArea = (e) => {
52
+ const { viewScaleInfo, element, groupQueue } = e;
53
+ const { scale, offsetTop, offsetLeft } = viewScaleInfo;
54
+ if (canvasWrapper.children) {
55
+ Array.from(canvasWrapper.children).forEach((child) => {
56
+ child.remove();
57
+ });
58
+ }
59
+ let parent = canvasWrapper;
60
+ for (let i = 0; i < groupQueue.length; i++) {
61
+ const group = groupQueue[i];
62
+ const { x, y, w, h } = group;
63
+ const angle = limitAngle(group.angle || 0);
64
+ const size = {
65
+ x: x * scale,
66
+ y: y * scale,
67
+ w: w * scale,
68
+ h: h * scale,
69
+ angle
70
+ };
71
+ if (i === 0) {
72
+ size.x += offsetLeft;
73
+ size.y += offsetTop;
74
+ }
75
+ parent = createBox({ size, parent });
76
+ }
77
+ const detail = Object.assign(Object.assign({}, defaultElementDetail), element.detail);
78
+ textarea.style.position = 'absolute';
79
+ textarea.style.left = `${element.x * scale}px`;
80
+ textarea.style.top = `${element.y * scale}px`;
81
+ textarea.style.width = `${element.w * scale}px`;
82
+ textarea.style.height = `${element.h * scale}px`;
83
+ textarea.style.transform = `rotate(${limitAngle(element.angle || 0)}deg)`;
84
+ textarea.style.border = 'none';
85
+ textarea.style.resize = 'none';
86
+ textarea.style.overflow = 'hidden';
87
+ textarea.style.wordBreak = 'break-all';
88
+ textarea.style.background = '#FFFFFF';
89
+ textarea.style.color = '#333333';
90
+ textarea.style.fontSize = `${detail.fontSize * scale}px`;
91
+ textarea.style.lineHeight = `${detail.lineHeight * scale}px`;
92
+ textarea.style.fontFamily = detail.fontFamily;
93
+ textarea.style.fontWeight = `${detail.fontWeight}`;
94
+ textarea.value = detail.text || '';
95
+ parent.appendChild(textarea);
96
+ };
97
+ const resetCanvasWrapper = () => {
98
+ const { left, top, width, height } = getCanvasRect();
99
+ canvasWrapper.style.position = 'absolute';
100
+ canvasWrapper.style.overflow = 'hidden';
101
+ canvasWrapper.style.top = `${top}px`;
102
+ canvasWrapper.style.left = `${left}px`;
103
+ canvasWrapper.style.width = `${width}px`;
104
+ canvasWrapper.style.height = `${height}px`;
105
+ };
106
+ mask.addEventListener('click', () => {
107
+ hideTextArea();
108
+ });
109
+ textarea.addEventListener('click', (e) => {
110
+ e.stopPropagation();
111
+ });
112
+ textarea.addEventListener('input', (e) => {
113
+ if (activeElem) {
114
+ activeElem.detail.text = e.target.value || '';
115
+ viewer.drawFrame();
116
+ }
117
+ });
118
+ textarea.addEventListener('blur', () => {
119
+ hideTextArea();
120
+ });
121
+ eventHub.on(middlewareEventTextEdit, (e) => {
122
+ var _a;
123
+ if ((e === null || e === void 0 ? void 0 : e.element) && ((_a = e === null || e === void 0 ? void 0 : e.element) === null || _a === void 0 ? void 0 : _a.type) === 'text') {
124
+ activeElem = e.element;
125
+ }
126
+ showTextArea(e);
127
+ });
128
+ return {
129
+ mode: key,
130
+ isDefault: true
131
+ };
132
+ };