@idraw/core 0.4.3 → 1.0.0-alpha.1

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.
Files changed (149) hide show
  1. package/dist/esm/board/index.d.ts +2 -2
  2. package/dist/esm/board/index.js +23 -12
  3. package/dist/esm/board/sharer.d.ts +3 -3
  4. package/dist/esm/board/sharer.js +10 -10
  5. package/dist/esm/board/viewer.d.ts +3 -3
  6. package/dist/esm/board/viewer.js +14 -14
  7. package/dist/esm/board/watcher.d.ts +3 -3
  8. package/dist/esm/board/watcher.js +68 -43
  9. package/dist/esm/core.d.ts +52 -0
  10. package/dist/esm/core.js +393 -0
  11. package/dist/esm/cursor/cursor-image.d.ts +2 -0
  12. package/dist/esm/cursor/cursor-image.js +2 -0
  13. package/dist/esm/cursor/cursor.js +60 -24
  14. package/dist/esm/index.d.ts +12 -61
  15. package/dist/esm/index.js +11 -389
  16. package/dist/esm/middlewares/common.d.ts +4 -0
  17. package/dist/esm/middlewares/common.js +13 -0
  18. package/dist/esm/middlewares/creator/dom.d.ts +11 -0
  19. package/dist/esm/middlewares/creator/dom.js +52 -0
  20. package/dist/esm/middlewares/creator/index.d.ts +5 -0
  21. package/dist/esm/middlewares/creator/index.js +136 -0
  22. package/dist/esm/middlewares/creator/static.d.ts +14 -0
  23. package/dist/esm/middlewares/creator/static.js +19 -0
  24. package/dist/esm/middlewares/creator/styles.d.ts +4 -0
  25. package/dist/esm/middlewares/creator/styles.js +32 -0
  26. package/dist/esm/middlewares/creator/types.d.ts +7 -0
  27. package/dist/esm/middlewares/creator/types.js +1 -0
  28. package/dist/esm/middlewares/creator/util.d.ts +10 -0
  29. package/dist/esm/middlewares/creator/util.js +52 -0
  30. package/dist/esm/middlewares/dragger/index.js +5 -5
  31. package/dist/esm/middlewares/info/draw-info.d.ts +11 -11
  32. package/dist/esm/middlewares/info/draw-info.js +18 -18
  33. package/dist/esm/middlewares/info/index.d.ts +2 -1
  34. package/dist/esm/middlewares/info/index.js +48 -51
  35. package/dist/esm/middlewares/info/static.d.ts +6 -0
  36. package/dist/esm/middlewares/info/{config.js → static.js} +6 -1
  37. package/dist/esm/middlewares/info/types.d.ts +2 -2
  38. package/dist/esm/middlewares/layout-selector/dom.d.ts +10 -0
  39. package/dist/esm/middlewares/layout-selector/dom.js +108 -0
  40. package/dist/esm/middlewares/layout-selector/index.d.ts +1 -1
  41. package/dist/esm/middlewares/layout-selector/index.js +89 -141
  42. package/dist/esm/middlewares/layout-selector/static.d.ts +32 -0
  43. package/dist/esm/middlewares/layout-selector/static.js +39 -0
  44. package/dist/esm/middlewares/layout-selector/styles.d.ts +4 -0
  45. package/dist/esm/middlewares/layout-selector/styles.js +127 -0
  46. package/dist/esm/middlewares/layout-selector/types.d.ts +6 -6
  47. package/dist/esm/middlewares/layout-selector/types.js +2 -2
  48. package/dist/esm/middlewares/layout-selector/util.d.ts +4 -4
  49. package/dist/esm/middlewares/layout-selector/util.js +19 -19
  50. package/dist/esm/middlewares/path-creator/dom.d.ts +29 -0
  51. package/dist/esm/middlewares/path-creator/dom.js +145 -0
  52. package/dist/esm/middlewares/path-creator/index.d.ts +5 -0
  53. package/dist/esm/middlewares/path-creator/index.js +203 -0
  54. package/dist/esm/middlewares/path-creator/static.d.ts +23 -0
  55. package/dist/esm/middlewares/path-creator/static.js +49 -0
  56. package/dist/esm/middlewares/path-creator/types.d.ts +1 -0
  57. package/dist/esm/middlewares/path-editor/calc.d.ts +6 -0
  58. package/dist/esm/middlewares/path-editor/calc.js +51 -0
  59. package/dist/esm/middlewares/path-editor/dom.d.ts +32 -0
  60. package/dist/esm/middlewares/path-editor/dom.js +575 -0
  61. package/dist/esm/middlewares/path-editor/draw.d.ts +7 -0
  62. package/dist/esm/middlewares/path-editor/draw.js +113 -0
  63. package/dist/esm/middlewares/path-editor/index.d.ts +5 -0
  64. package/dist/esm/middlewares/path-editor/index.js +312 -0
  65. package/dist/esm/middlewares/path-editor/parse.d.ts +5 -0
  66. package/dist/esm/middlewares/path-editor/parse.js +37 -0
  67. package/dist/esm/middlewares/path-editor/static.d.ts +34 -0
  68. package/dist/esm/middlewares/path-editor/static.js +82 -0
  69. package/dist/esm/middlewares/path-editor/types.d.ts +26 -0
  70. package/dist/esm/middlewares/path-editor/types.js +1 -0
  71. package/dist/esm/middlewares/path-editor/util.d.ts +5 -0
  72. package/dist/esm/middlewares/path-editor/util.js +21 -0
  73. package/dist/esm/middlewares/pointer/index.js +5 -5
  74. package/dist/esm/middlewares/pointer/types.d.ts +2 -2
  75. package/dist/esm/middlewares/ruler/index.d.ts +2 -0
  76. package/dist/esm/middlewares/ruler/index.js +12 -19
  77. package/dist/esm/middlewares/ruler/static.d.ts +8 -0
  78. package/dist/esm/middlewares/ruler/{config.js → static.js} +16 -3
  79. package/dist/esm/middlewares/ruler/types.d.ts +2 -2
  80. package/dist/esm/middlewares/ruler/util.d.ts +6 -6
  81. package/dist/esm/middlewares/ruler/util.js +31 -31
  82. package/dist/esm/middlewares/scaler/index.js +2 -2
  83. package/dist/esm/middlewares/scroller/dom.d.ts +14 -0
  84. package/dist/esm/middlewares/scroller/dom.js +53 -0
  85. package/dist/esm/middlewares/scroller/index.d.ts +2 -0
  86. package/dist/esm/middlewares/scroller/index.js +111 -46
  87. package/dist/esm/middlewares/scroller/static.d.ts +21 -0
  88. package/dist/esm/middlewares/scroller/static.js +29 -0
  89. package/dist/esm/middlewares/scroller/styles.d.ts +4 -0
  90. package/dist/esm/middlewares/scroller/styles.js +73 -0
  91. package/dist/esm/middlewares/scroller/types.d.ts +8 -6
  92. package/dist/esm/middlewares/scroller/types.js +1 -1
  93. package/dist/esm/middlewares/scroller/util.d.ts +6 -13
  94. package/dist/esm/middlewares/scroller/util.js +15 -144
  95. package/dist/esm/middlewares/selector/dom.d.ts +21 -0
  96. package/dist/esm/middlewares/selector/dom.js +395 -0
  97. package/dist/esm/middlewares/selector/draw-base.d.ts +9 -21
  98. package/dist/esm/middlewares/selector/draw-base.js +19 -43
  99. package/dist/esm/middlewares/selector/draw-reference.d.ts +4 -5
  100. package/dist/esm/middlewares/selector/draw-reference.js +5 -5
  101. package/dist/esm/middlewares/selector/index.d.ts +4 -2
  102. package/dist/esm/middlewares/selector/index.js +315 -439
  103. package/dist/esm/middlewares/selector/reference.d.ts +5 -5
  104. package/dist/esm/middlewares/selector/reference.js +36 -30
  105. package/dist/esm/middlewares/selector/render-frame.d.ts +11 -0
  106. package/dist/esm/middlewares/selector/render-frame.js +107 -0
  107. package/dist/esm/middlewares/selector/resize.d.ts +7 -0
  108. package/dist/esm/middlewares/selector/resize.js +27 -0
  109. package/dist/esm/middlewares/selector/static.d.ts +67 -0
  110. package/dist/esm/middlewares/selector/static.js +92 -0
  111. package/dist/esm/middlewares/selector/styles.d.ts +4 -0
  112. package/dist/esm/middlewares/selector/styles.js +153 -0
  113. package/dist/esm/middlewares/selector/types.d.ts +27 -27
  114. package/dist/esm/middlewares/selector/types.js +1 -1
  115. package/dist/esm/middlewares/selector/util.d.ts +22 -32
  116. package/dist/esm/middlewares/selector/util.js +226 -243
  117. package/dist/esm/middlewares/text-editor/dom.d.ts +5 -0
  118. package/dist/esm/middlewares/text-editor/dom.js +135 -0
  119. package/dist/esm/middlewares/text-editor/index.d.ts +5 -20
  120. package/dist/esm/middlewares/text-editor/index.js +201 -208
  121. package/dist/esm/middlewares/text-editor/static.d.ts +10 -0
  122. package/dist/esm/middlewares/text-editor/static.js +17 -0
  123. package/dist/esm/middlewares/text-editor/types.d.ts +21 -0
  124. package/dist/esm/middlewares/text-editor/types.js +1 -0
  125. package/dist/esm/record.d.ts +5 -5
  126. package/dist/esm/record.js +14 -14
  127. package/dist/esm/{config.d.ts → static.d.ts} +16 -0
  128. package/dist/esm/{config.js → static.js} +18 -2
  129. package/dist/index.global.js +8934 -5647
  130. package/dist/index.global.min.js +1 -1
  131. package/package.json +4 -4
  132. package/dist/esm/middlewares/info/config.d.ts +0 -5
  133. package/dist/esm/middlewares/layout-selector/config.d.ts +0 -11
  134. package/dist/esm/middlewares/layout-selector/config.js +0 -12
  135. package/dist/esm/middlewares/ruler/config.d.ts +0 -7
  136. package/dist/esm/middlewares/scroller/config.d.ts +0 -10
  137. package/dist/esm/middlewares/scroller/config.js +0 -16
  138. package/dist/esm/middlewares/selector/config.d.ts +0 -30
  139. package/dist/esm/middlewares/selector/config.js +0 -38
  140. package/dist/esm/middlewares/selector/draw-auxiliary.js +0 -12
  141. package/dist/esm/middlewares/selector/draw-debug.d.ts +0 -5
  142. package/dist/esm/middlewares/selector/draw-debug.js +0 -30
  143. package/dist/esm/middlewares/selector/draw-wrapper.d.ts +0 -37
  144. package/dist/esm/middlewares/selector/draw-wrapper.js +0 -139
  145. package/dist/esm/middlewares/selector/pattern/icon-rotate.d.ts +0 -4
  146. package/dist/esm/middlewares/selector/pattern/icon-rotate.js +0 -88
  147. package/dist/esm/middlewares/selector/pattern/index.d.ts +0 -8
  148. package/dist/esm/middlewares/selector/pattern/index.js +0 -38
  149. /package/dist/esm/middlewares/{selector/draw-auxiliary.d.ts → path-creator/types.js} +0 -0
@@ -0,0 +1,575 @@
1
+ import { createHTMLElement, limitAngle, setHTMLCSSProps, scalePathCommands, injectStyles, removeStyles, removeClassName, parseHTMLStr, convertPathCommandsToStr, assembleHTMLElement, ATTR_VALID_WATCH, } from '@idraw/util';
2
+ import { ATTR_UUID, ATTR_X, ATTR_Y, ATTR_W, ATTR_H, ATTR_ANGLE, ATTR_TYPE, ATTR_AHCHOR_CMD_TYPE, ATTR_AHCHOR_INDEX, ATTR_AHCHOR_ID, ATTR_HELPER_TYPE, ATTR_DIRECTOR_FROM_AHCHOR_ID, ATTR_DIRECTOR_OPENED_BY_AHCHOR_ID, ATTR_DIRECTOR_CONTROL_TYPE, HELPER_ELEMENT, HELPER_GROUP, HELPER_ANCHOR, HELPER_DIRECTOR, HELPER_DIRECTOR_LINE, HELPER_PATH_PREVIEW, HELPER_PATH_DEFINITION, classNameMap, } from './static';
3
+ export function initStyles(rootClassName, styles) {
4
+ const stylesProps = {
5
+ display: 'flex',
6
+ position: 'absolute',
7
+ zIndex: styles.zIndex,
8
+ top: 0,
9
+ left: 0,
10
+ right: 0,
11
+ bottom: 0,
12
+ overflow: 'hidden',
13
+ justifyContent: 'center',
14
+ alignItems: 'center',
15
+ [`&.${classNameMap.hide}`]: {
16
+ display: 'none',
17
+ },
18
+ [`.${classNameMap.anchor}`]: {
19
+ position: 'absolute',
20
+ width: styles.anchorSize,
21
+ height: styles.anchorSize,
22
+ background: styles.anchorBackground,
23
+ border: `${styles.anchorBorderWidth}px solid ${styles.anchorBorderColor}`,
24
+ borderRadius: '50%',
25
+ overflow: 'hidden',
26
+ ['&:hover']: {
27
+ borderColor: styles.anchorHoverBorderColor,
28
+ background: styles.anchorHoverBackground,
29
+ },
30
+ ['&:active']: {
31
+ borderColor: styles.anchorActiveBorderColor,
32
+ background: styles.anchorActiveBackground,
33
+ },
34
+ [`&.${classNameMap.selected}`]: {
35
+ borderColor: styles.anchorActiveBorderColor,
36
+ background: styles.anchorActiveBackground,
37
+ },
38
+ },
39
+ [`.${classNameMap.director}`]: {
40
+ position: 'absolute',
41
+ width: styles.directorSize,
42
+ height: styles.directorSize,
43
+ background: styles.directorBackground,
44
+ border: `${styles.directorBorderWidth}px solid ${styles.directorBorderColor}`,
45
+ overflow: 'hidden',
46
+ ['&:hover']: {
47
+ borderColor: styles.directorHoverBorderColor,
48
+ background: styles.directorHoverBackground,
49
+ },
50
+ ['&:active']: {
51
+ borderColor: styles.directorActiveBorderColor,
52
+ background: styles.directorActiveBackground,
53
+ },
54
+ [`&.${classNameMap.selected}`]: {
55
+ borderColor: styles.directorActiveBorderColor,
56
+ background: styles.directorActiveBackground,
57
+ },
58
+ },
59
+ [`.${classNameMap.directorLines}`]: {
60
+ position: 'absolute',
61
+ left: 0,
62
+ right: 0,
63
+ top: 0,
64
+ bottom: 0,
65
+ },
66
+ };
67
+ injectStyles({ styles: stylesProps, rootClassName, type: 'element' });
68
+ }
69
+ export function destroyStyles(rootClassName) {
70
+ removeStyles({ rootClassName, type: 'element' });
71
+ }
72
+ export function initRoot(container, opts) {
73
+ const { id, rootClassName } = opts;
74
+ if (!container) {
75
+ return;
76
+ }
77
+ const root = createHTMLElement('div', {
78
+ id,
79
+ className: [classNameMap.hide, rootClassName].join(' '),
80
+ [ATTR_VALID_WATCH]: 'true',
81
+ });
82
+ if (!container.contains(root)) {
83
+ container.appendChild(root);
84
+ }
85
+ return root;
86
+ }
87
+ const createBox = (opts, props) => {
88
+ const { size, parent } = opts;
89
+ const { x, y, width, height } = size;
90
+ const angle = limitAngle(size.angle || 0);
91
+ const div = createHTMLElement('div', Object.assign({ [ATTR_VALID_WATCH]: 'true', style: {
92
+ position: 'absolute',
93
+ left: x,
94
+ top: y,
95
+ width,
96
+ height,
97
+ transform: `rotate(${angle}deg)`,
98
+ } }, props));
99
+ parent.appendChild(div);
100
+ return div;
101
+ };
102
+ const getBoxMaterialInfo = (box) => {
103
+ const id = box.getAttribute(ATTR_UUID) || '';
104
+ const type = box.getAttribute(ATTR_TYPE) || '';
105
+ const x = parseFloat(box.getAttribute(ATTR_X) || '0');
106
+ const y = parseFloat(box.getAttribute(ATTR_Y) || '0');
107
+ const w = parseFloat(box.getAttribute(ATTR_W) || '0');
108
+ const h = parseFloat(box.getAttribute(ATTR_H) || '0');
109
+ const angle = parseFloat(box.getAttribute(ATTR_ANGLE) || '0');
110
+ const info = { id, type, x, y, w, h, angle };
111
+ return info;
112
+ };
113
+ const getAnchorPosition = (opts) => {
114
+ const { x, y, size, borderWidth } = opts;
115
+ return {
116
+ left: x - size / 2 - borderWidth,
117
+ top: y - size / 2 - borderWidth,
118
+ };
119
+ };
120
+ const getDirectorPosition = (opts) => {
121
+ const { x, y, size, borderWidth } = opts;
122
+ return {
123
+ left: x - size / 2 - borderWidth,
124
+ top: y - size / 2 - borderWidth,
125
+ };
126
+ };
127
+ export const getAnchorHandlerInfo = (handler) => {
128
+ const id = handler.getAttribute(ATTR_AHCHOR_ID) || '';
129
+ const index = parseFloat(handler.getAttribute(ATTR_AHCHOR_INDEX) || '0');
130
+ const info = {
131
+ index,
132
+ id,
133
+ };
134
+ return info;
135
+ };
136
+ export const getDirectorHandlerInfo = (handler) => {
137
+ const type = handler.getAttribute(ATTR_DIRECTOR_CONTROL_TYPE);
138
+ const fromAnchorId = handler.getAttribute(ATTR_DIRECTOR_FROM_AHCHOR_ID) || '';
139
+ const openedAnchorId = handler.getAttribute(ATTR_DIRECTOR_OPENED_BY_AHCHOR_ID) || '';
140
+ const info = {
141
+ type,
142
+ fromAnchorId,
143
+ openedAnchorId,
144
+ };
145
+ return info;
146
+ };
147
+ export const resetRoot = (root, opts) => {
148
+ const { material, calculator, viewScaleInfo, groupQueue, styles } = opts;
149
+ if (!root || !material) {
150
+ return;
151
+ }
152
+ const { scale, offsetTop, offsetLeft } = viewScaleInfo;
153
+ if (root === null || root === void 0 ? void 0 : root.children) {
154
+ Array.from(root.children).forEach((child) => {
155
+ child.remove();
156
+ });
157
+ }
158
+ removeClassName(root, [classNameMap.hide]);
159
+ let parent = root;
160
+ for (let i = 0; i < groupQueue.length; i++) {
161
+ const group = groupQueue[i];
162
+ const { x, y, width, height } = group;
163
+ const angle = limitAngle(group.angle || 0);
164
+ const size = {
165
+ x: x * scale,
166
+ y: y * scale,
167
+ width: width * scale,
168
+ height: height * scale,
169
+ angle,
170
+ };
171
+ if (i === 0) {
172
+ size.x += offsetLeft;
173
+ size.y += offsetTop;
174
+ }
175
+ parent = createBox({ size, parent }, {
176
+ [ATTR_UUID]: group.id,
177
+ [ATTR_X]: group.x,
178
+ [ATTR_Y]: group.y,
179
+ [ATTR_W]: group.width,
180
+ [ATTR_H]: group.height,
181
+ [ATTR_ANGLE]: group.angle,
182
+ [ATTR_TYPE]: group.type,
183
+ [ATTR_HELPER_TYPE]: HELPER_GROUP,
184
+ });
185
+ }
186
+ let mtrlX = material.x * scale + offsetLeft;
187
+ let mtrlY = material.y * scale + offsetTop;
188
+ let mtrlW = material.width * scale;
189
+ let mtrlH = material.height * scale;
190
+ if (groupQueue.length > 0) {
191
+ mtrlX = material.x * scale;
192
+ mtrlY = material.y * scale;
193
+ mtrlW = material.width * scale;
194
+ mtrlH = material.height * scale;
195
+ }
196
+ const targetBox = createHTMLElement('div', {
197
+ [ATTR_UUID]: material.id,
198
+ [ATTR_X]: material.x,
199
+ [ATTR_Y]: material.y,
200
+ [ATTR_W]: material.width,
201
+ [ATTR_H]: material.height,
202
+ [ATTR_ANGLE]: material.angle,
203
+ [ATTR_TYPE]: material.type,
204
+ [ATTR_HELPER_TYPE]: HELPER_ELEMENT,
205
+ [ATTR_VALID_WATCH]: 'true',
206
+ style: {
207
+ display: 'inline-flex',
208
+ flexDirection: 'column',
209
+ position: 'absolute',
210
+ left: mtrlX,
211
+ top: mtrlY,
212
+ width: mtrlW,
213
+ height: mtrlH,
214
+ transform: `rotate(${limitAngle(material.angle || 0)}deg)`,
215
+ boxSizing: 'border-box',
216
+ overflow: 'visible',
217
+ padding: '0',
218
+ margin: '0',
219
+ outline: 'none',
220
+ },
221
+ });
222
+ const flatItem = calculator.getVirtualItem(material.id);
223
+ const cmds = scalePathCommands(flatItem.anchorCommands || [], scale, scale);
224
+ cmds.forEach((cmd, i) => {
225
+ const $anchor = createHTMLElement('div', {
226
+ [ATTR_HELPER_TYPE]: HELPER_ANCHOR,
227
+ [ATTR_AHCHOR_CMD_TYPE]: cmd.type,
228
+ [ATTR_AHCHOR_INDEX]: i,
229
+ [ATTR_AHCHOR_ID]: cmd.id,
230
+ [ATTR_VALID_WATCH]: 'true',
231
+ className: classNameMap.anchor,
232
+ style: Object.assign(Object.assign({}, getAnchorPosition({
233
+ x: cmd.start.x,
234
+ y: cmd.start.y,
235
+ size: styles.anchorSize,
236
+ borderWidth: styles.anchorBorderWidth,
237
+ })), { display: cmd.type === 'M' ? 'none' : 'block' }),
238
+ });
239
+ targetBox.appendChild($anchor);
240
+ });
241
+ parent.appendChild(targetBox);
242
+ resetPathLine(root, {
243
+ anchorCommands: cmds,
244
+ material,
245
+ viewScaleInfo,
246
+ styles,
247
+ });
248
+ };
249
+ export const resetAnchorStyle = (root, opts) => {
250
+ var _a, _b, _c;
251
+ if (!root) {
252
+ return;
253
+ }
254
+ const { material, viewScaleInfo, calculator, selectedAnchorId, styles } = opts;
255
+ if (!material) {
256
+ return;
257
+ }
258
+ const { scale, offsetTop, offsetLeft } = viewScaleInfo;
259
+ let current = root.children[0];
260
+ let index = 0;
261
+ while (['group', 'material'].includes(current === null || current === void 0 ? void 0 : current.getAttribute(ATTR_HELPER_TYPE))) {
262
+ if ((current === null || current === void 0 ? void 0 : current.getAttribute(ATTR_HELPER_TYPE)) === 'material') {
263
+ setHTMLCSSProps(current, {
264
+ width: material.width,
265
+ height: material.height,
266
+ left: material.x,
267
+ top: material.y,
268
+ });
269
+ assembleHTMLElement(current, {
270
+ [ATTR_W]: material.width,
271
+ [ATTR_H]: material.height,
272
+ [ATTR_X]: material.x,
273
+ [ATTR_Y]: material.y,
274
+ });
275
+ }
276
+ const { x, y, w, h, angle } = getBoxMaterialInfo(current);
277
+ const size = {
278
+ x: x * scale,
279
+ y: y * scale,
280
+ w: w * scale,
281
+ h: h * scale,
282
+ angle,
283
+ };
284
+ if (index === 0) {
285
+ size.x += offsetLeft;
286
+ size.y += offsetTop;
287
+ }
288
+ setHTMLCSSProps(current, {
289
+ left: size.x,
290
+ top: size.y,
291
+ width: size.w,
292
+ height: size.h,
293
+ transform: `rotate(${size.angle}deg)`,
294
+ });
295
+ if (((_b = (_a = current === null || current === void 0 ? void 0 : current.children) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.getAttribute(ATTR_HELPER_TYPE)) !== 'material') {
296
+ break;
297
+ }
298
+ current = (_c = current === null || current === void 0 ? void 0 : current.children) === null || _c === void 0 ? void 0 : _c[0];
299
+ index++;
300
+ }
301
+ const { id } = material;
302
+ const flatItem = calculator.getVirtualItem(id);
303
+ const cmds = scalePathCommands(flatItem.anchorCommands || [], scale, scale);
304
+ {
305
+ const $anchors = Array.from(current.querySelectorAll(`[${ATTR_HELPER_TYPE}="${HELPER_ANCHOR}"]`));
306
+ $anchors.forEach(($anchor, i) => {
307
+ const cmd = cmds[i];
308
+ const id = $anchor.getAttribute(ATTR_AHCHOR_ID);
309
+ const size = id === selectedAnchorId ? styles.anchorSelectedSize : styles.anchorSize;
310
+ setHTMLCSSProps($anchor, {
311
+ width: size,
312
+ height: size,
313
+ left: cmd.start.x - size / 2 - styles.anchorBorderWidth,
314
+ top: cmd.start.y - size / 2 - styles.anchorBorderWidth,
315
+ });
316
+ });
317
+ }
318
+ if (typeof selectedAnchorId === 'string' && selectedAnchorId) {
319
+ const anchorIndex = cmds.findIndex((cmd) => cmd.id === selectedAnchorId);
320
+ const curveCmd = cmds[anchorIndex];
321
+ const prevCurveCmd = cmds[anchorIndex - 1];
322
+ let currentDirector = null;
323
+ let prevDirector = null;
324
+ if (curveCmd.type === 'C') {
325
+ currentDirector = {
326
+ openedByAnchorId: selectedAnchorId,
327
+ anchorId: curveCmd.id,
328
+ anchorPoint: { x: curveCmd.start.x, y: curveCmd.start.y },
329
+ directPoint: { x: curveCmd.params[0], y: curveCmd.params[1] },
330
+ };
331
+ }
332
+ if (prevCurveCmd.type === 'C') {
333
+ prevDirector = {
334
+ openedByAnchorId: selectedAnchorId,
335
+ anchorId: prevCurveCmd.id,
336
+ anchorPoint: { x: prevCurveCmd.end.x, y: prevCurveCmd.end.y },
337
+ directPoint: { x: prevCurveCmd.params[2], y: prevCurveCmd.params[3] },
338
+ };
339
+ }
340
+ if (currentDirector || prevDirector) {
341
+ resetDirectionerStyle(root, { selectedAnchorId, currentDirector, prevDirector, styles });
342
+ resetDirectorLine(root, { currentDirector, prevDirector, styles });
343
+ }
344
+ else {
345
+ clearDirectioner(root);
346
+ }
347
+ }
348
+ resetPathPreviewStyle(root, { anchorCommands: cmds, viewScaleInfo, styles });
349
+ };
350
+ const createDirectorLines = (directors, opts) => {
351
+ const { styles } = opts;
352
+ const svg = `
353
+ <svg
354
+ width="100%"
355
+ height="100%"
356
+ overflow="visible"
357
+ xmlns="http://www.w3.org/2000/svg"
358
+ ${ATTR_VALID_WATCH}="true"
359
+ >
360
+ ${directors
361
+ .map((director) => {
362
+ if (!director) {
363
+ return '';
364
+ }
365
+ const { anchorPoint, directPoint } = director;
366
+ const x1 = anchorPoint.x;
367
+ const y1 = anchorPoint.y;
368
+ const x2 = directPoint.x;
369
+ const y2 = directPoint.y;
370
+ return `<line
371
+ x1="${x1}"
372
+ x2="${x2}"
373
+ y1="${y1}"
374
+ y2="${y2}"
375
+ stroke="${styles.directorLineColor}"
376
+ stroke-width="2"
377
+ ${ATTR_VALID_WATCH}="true"
378
+ />`;
379
+ })
380
+ .join('')}
381
+ </svg>
382
+ `;
383
+ const $lines = createHTMLElement('div', {
384
+ width: '100%',
385
+ height: '100%',
386
+ className: classNameMap.directorLines,
387
+ [ATTR_HELPER_TYPE]: HELPER_DIRECTOR_LINE,
388
+ [ATTR_VALID_WATCH]: 'true',
389
+ }, [parseHTMLStr(svg)]);
390
+ return $lines;
391
+ };
392
+ const clearDirectorLine = (root) => {
393
+ const existedLines = root.querySelectorAll(`[${ATTR_HELPER_TYPE}="${HELPER_DIRECTOR_LINE}"]`);
394
+ Array.from(existedLines).forEach((line) => {
395
+ line === null || line === void 0 ? void 0 : line.remove();
396
+ });
397
+ };
398
+ const resetDirectorLine = (root, opts) => {
399
+ const $material = root.querySelector(`[${ATTR_HELPER_TYPE}="${HELPER_ELEMENT}"]`);
400
+ const $pathPreview = root.querySelector(`[${ATTR_HELPER_TYPE}="${HELPER_PATH_PREVIEW}"]`);
401
+ if (!($material && $pathPreview)) {
402
+ return;
403
+ }
404
+ clearDirectorLine(root);
405
+ const { currentDirector, prevDirector, styles } = opts;
406
+ if (prevDirector || currentDirector) {
407
+ const $lines = createDirectorLines([prevDirector, currentDirector], { styles });
408
+ if ($material.firstElementChild) {
409
+ $material.insertBefore($lines, $pathPreview);
410
+ }
411
+ }
412
+ };
413
+ export const clearDirectioner = (root) => {
414
+ if (!root) {
415
+ return;
416
+ }
417
+ const existedDirectors = root.querySelectorAll(`[${ATTR_HELPER_TYPE}="${HELPER_DIRECTOR}"]`);
418
+ Array.from(existedDirectors).forEach((director) => {
419
+ director === null || director === void 0 ? void 0 : director.remove();
420
+ });
421
+ clearDirectorLine(root);
422
+ };
423
+ export const resetDirectionerStyle = (root, opts) => {
424
+ const { selectedAnchorId, prevDirector, currentDirector, styles } = opts;
425
+ const directors = [];
426
+ if (prevDirector) {
427
+ directors.push(prevDirector);
428
+ }
429
+ if (currentDirector) {
430
+ directors.push(currentDirector);
431
+ }
432
+ const $directors = Array.from(root.querySelectorAll(`[${ATTR_HELPER_TYPE}="${HELPER_DIRECTOR}"]`));
433
+ let needResetAll = false;
434
+ if (directors.length === $directors.length) {
435
+ for (let i = 0; i < $directors.length; i++) {
436
+ const $director = $directors[i];
437
+ const director = directors[i];
438
+ const info = getDirectorHandlerInfo($directors[i]);
439
+ if (info.openedAnchorId === selectedAnchorId && info.fromAnchorId === director.anchorId) {
440
+ setHTMLCSSProps($director, getDirectorPosition({
441
+ x: director.directPoint.x,
442
+ y: director.directPoint.y,
443
+ size: styles.directorSize,
444
+ borderWidth: styles.directorBorderWidth,
445
+ }));
446
+ }
447
+ else {
448
+ needResetAll = true;
449
+ break;
450
+ }
451
+ }
452
+ }
453
+ else {
454
+ needResetAll = true;
455
+ }
456
+ if (needResetAll) {
457
+ resetDirectioner(root, { prevDirector, currentDirector, styles });
458
+ }
459
+ };
460
+ const resetDirectioner = (root, opts) => {
461
+ if (!root) {
462
+ return;
463
+ }
464
+ const $material = root.querySelector(`[${ATTR_HELPER_TYPE}="${HELPER_ELEMENT}"]`);
465
+ if (!$material) {
466
+ return;
467
+ }
468
+ clearDirectioner(root);
469
+ resetDirectorLine(root, opts);
470
+ const { currentDirector, prevDirector, styles } = opts;
471
+ if (prevDirector) {
472
+ const $director = createHTMLElement('div', {
473
+ [ATTR_HELPER_TYPE]: HELPER_DIRECTOR,
474
+ [ATTR_DIRECTOR_CONTROL_TYPE]: 'curve-ctrl2',
475
+ [ATTR_DIRECTOR_FROM_AHCHOR_ID]: prevDirector.anchorId,
476
+ [ATTR_DIRECTOR_OPENED_BY_AHCHOR_ID]: prevDirector.openedByAnchorId,
477
+ [ATTR_VALID_WATCH]: 'true',
478
+ className: classNameMap.director,
479
+ style: Object.assign({}, getDirectorPosition({
480
+ x: prevDirector.directPoint.x,
481
+ y: prevDirector.directPoint.y,
482
+ size: styles.directorSize,
483
+ borderWidth: styles.directorBorderWidth,
484
+ })),
485
+ });
486
+ $material.appendChild($director);
487
+ }
488
+ if (currentDirector) {
489
+ const $director = createHTMLElement('div', {
490
+ [ATTR_HELPER_TYPE]: HELPER_DIRECTOR,
491
+ [ATTR_DIRECTOR_CONTROL_TYPE]: 'curve-ctrl1',
492
+ [ATTR_DIRECTOR_FROM_AHCHOR_ID]: currentDirector.anchorId,
493
+ [ATTR_DIRECTOR_OPENED_BY_AHCHOR_ID]: currentDirector.openedByAnchorId,
494
+ [ATTR_VALID_WATCH]: 'true',
495
+ className: classNameMap.director,
496
+ style: Object.assign({}, getDirectorPosition({
497
+ x: currentDirector.directPoint.x,
498
+ y: currentDirector.directPoint.y,
499
+ size: styles.directorSize,
500
+ borderWidth: styles.directorBorderWidth,
501
+ })),
502
+ });
503
+ $material.appendChild($director);
504
+ }
505
+ };
506
+ const resetPathLine = (root, opts) => {
507
+ if (!root) {
508
+ return;
509
+ }
510
+ const $material = root.querySelector(`[${ATTR_HELPER_TYPE}="${HELPER_ELEMENT}"]`);
511
+ if (!$material) {
512
+ return;
513
+ }
514
+ const $pathPreview = createHTMLElement('div', {
515
+ className: classNameMap.pathLine,
516
+ [ATTR_HELPER_TYPE]: HELPER_PATH_PREVIEW,
517
+ [ATTR_VALID_WATCH]: 'true',
518
+ });
519
+ if ($material.firstElementChild) {
520
+ $material.insertBefore($pathPreview, $material.firstElementChild);
521
+ }
522
+ resetPathPreview(root, opts);
523
+ };
524
+ const resetPathPreviewStyle = (root, opts) => {
525
+ const $pathPreview = root.querySelector(`[${ATTR_HELPER_TYPE}="${HELPER_PATH_PREVIEW}"]`);
526
+ if (!$pathPreview) {
527
+ return;
528
+ }
529
+ const $pathDefinition = $pathPreview.querySelector(`[${ATTR_HELPER_TYPE}="${HELPER_PATH_DEFINITION}"]`);
530
+ if ($pathDefinition) {
531
+ const { anchorCommands } = opts;
532
+ const definition = convertPathCommandsToStr(anchorCommands);
533
+ assembleHTMLElement($pathDefinition, {
534
+ d: definition,
535
+ });
536
+ }
537
+ else {
538
+ resetPathPreview(root, opts);
539
+ }
540
+ };
541
+ const resetPathPreview = (root, opts) => {
542
+ const $pathPreview = root.querySelector(`[${ATTR_HELPER_TYPE}="${HELPER_PATH_PREVIEW}"]`);
543
+ if (!$pathPreview) {
544
+ return;
545
+ }
546
+ if ($pathPreview === null || $pathPreview === void 0 ? void 0 : $pathPreview.children) {
547
+ Array.from($pathPreview.children).forEach((child) => {
548
+ child.remove();
549
+ });
550
+ }
551
+ const { anchorCommands, styles } = opts;
552
+ const $svg = parseHTMLStr(`
553
+ <svg
554
+ width="100%"
555
+ height="100%"
556
+ overflow="visible"
557
+ fill="transparent"
558
+ ${ATTR_VALID_WATCH}="true"
559
+ >
560
+ <path
561
+ ${ATTR_HELPER_TYPE}="${HELPER_PATH_DEFINITION}"
562
+ d="${convertPathCommandsToStr(anchorCommands)}"
563
+ stroke="${styles.helperStrokeColor}"
564
+ stroke-width="${styles.helperStrokeWidth}"
565
+ ${ATTR_VALID_WATCH}="true"
566
+ />
567
+ </svg>
568
+ `);
569
+ assembleHTMLElement($pathPreview, {}, [$svg]);
570
+ };
571
+ export function calcPathSize(root) {
572
+ if (!root) {
573
+ return null;
574
+ }
575
+ }
@@ -0,0 +1,7 @@
1
+ import type { ViewContext2D, StrictMaterial, ViewScaleInfo, ViewSizeInfo, Point } from '@idraw/types';
2
+ export declare function drawAncor(ctx: ViewContext2D, center: Point): void;
3
+ export declare function drawBreakpoint(ctx: ViewContext2D, center: Point): void;
4
+ export declare function drawPathAnchor(ctx: ViewContext2D, material: StrictMaterial<'path'> | null, opts: {
5
+ viewScaleInfo: ViewScaleInfo;
6
+ viewSizeInfo: ViewSizeInfo;
7
+ }): void;
@@ -0,0 +1,113 @@
1
+ import { convertPathCommandsToContext2DCommands, calcViewPoint, rotateMaterial, calcViewMaterialSize, } from '@idraw/util';
2
+ import { parseBezierCurveTo, parseMoveTo, parseEllipse } from './parse';
3
+ export function drawAncor(ctx, center) {
4
+ const { x, y } = center;
5
+ const w = 12;
6
+ const h = 12;
7
+ const borderColor = '#0000ff';
8
+ const borderWidth = 2;
9
+ const background = '#ffffffaf';
10
+ const lineDash = [];
11
+ ctx.setLineDash([]);
12
+ ctx.lineWidth = borderWidth;
13
+ ctx.strokeStyle = borderColor;
14
+ ctx.fillStyle = background;
15
+ ctx.setLineDash(lineDash);
16
+ ctx.beginPath();
17
+ ctx.moveTo(x - w / 2, y - h / 2);
18
+ ctx.lineTo(x + w / 2, y - h / 2);
19
+ ctx.lineTo(x + w / 2, y + h / 2);
20
+ ctx.lineTo(x - w / 2, y + h / 2);
21
+ ctx.lineTo(x - w / 2, y - h / 2);
22
+ ctx.closePath();
23
+ ctx.stroke();
24
+ ctx.fill('nonzero');
25
+ }
26
+ export function drawBreakpoint(ctx, center) {
27
+ const w = 12;
28
+ const h = 12;
29
+ const borderColor = '#ff0000';
30
+ const borderWidth = 2;
31
+ const background = '#ffffffaf';
32
+ const lineDash = [];
33
+ ctx.setLineDash([]);
34
+ ctx.lineWidth = borderWidth;
35
+ ctx.strokeStyle = borderColor;
36
+ ctx.fillStyle = background;
37
+ ctx.setLineDash(lineDash);
38
+ ctx.beginPath();
39
+ ctx.circle(center.x, center.y, w / 2, h / 2, 0, 0, 2 * Math.PI);
40
+ ctx.closePath();
41
+ ctx.fill();
42
+ ctx.stroke();
43
+ }
44
+ export function drawPathAnchor(ctx, material, opts) {
45
+ if (!((material === null || material === void 0 ? void 0 : material.type) === 'path' && Array.isArray(material === null || material === void 0 ? void 0 : material.commands))) {
46
+ return;
47
+ }
48
+ const { x, y, commands } = material;
49
+ const viewElemSize = calcViewMaterialSize(material, opts);
50
+ const ctxCmds = convertPathCommandsToContext2DCommands(commands);
51
+ ctx.strokeStyle = 'blue';
52
+ ctx.lineWidth = 1;
53
+ const scalePoint = (p) => ({
54
+ x: p.x * opts.viewScaleInfo.scale,
55
+ y: p.y * opts.viewScaleInfo.scale,
56
+ });
57
+ const movePoint = (p) => ({
58
+ x: p.x + x,
59
+ y: p.y + y,
60
+ });
61
+ let current = null;
62
+ const cmdItems = [];
63
+ rotateMaterial(ctx, viewElemSize, () => {
64
+ ctxCmds.forEach((cmd) => {
65
+ if (cmd.name === 'moveTo') {
66
+ const p = calcViewPoint(movePoint({ x: cmd.params.x, y: cmd.params.y }), opts);
67
+ ctx.moveTo(p.x, p.y);
68
+ cmdItems.push(parseMoveTo(Object.assign(Object.assign({}, cmd), { params: Object.assign({}, p) })));
69
+ current = { x: p.x, y: p.y };
70
+ }
71
+ else if (cmd.name === 'bezierCurveTo') {
72
+ const cp1 = calcViewPoint(movePoint({ x: cmd.params.cp1x, y: cmd.params.cp1y }), opts);
73
+ const cp2 = calcViewPoint(movePoint({ x: cmd.params.cp2x, y: cmd.params.cp2y }), opts);
74
+ const p = calcViewPoint(movePoint({ x: cmd.params.x, y: cmd.params.y }), opts);
75
+ ctx.bezierCurveTo(cp1.x, cp1.y, cp2.x, cp2.y, p.x, p.y);
76
+ cmdItems.push(parseBezierCurveTo(current, Object.assign(Object.assign({}, cmd), { params: {
77
+ cp1x: cp1.x,
78
+ cp1y: cp1.y,
79
+ cp2x: cp2.x,
80
+ cp2y: cp2.y,
81
+ x: p.x,
82
+ y: p.y,
83
+ } })));
84
+ current = { x: p.x, y: p.y };
85
+ }
86
+ else if (cmd.name === 'ellipse') {
87
+ const center = calcViewPoint(movePoint({ x: cmd.params.centerX, y: cmd.params.centerY }), opts);
88
+ const radius = scalePoint({ x: cmd.params.radiusX, y: cmd.params.radiusY });
89
+ ctx.ellipse(center.x, center.y, radius.x, radius.y, cmd.params.rotation, cmd.params.startRadian, cmd.params.endRadian, cmd.params.anticlockwise);
90
+ cmdItems.push(parseEllipse(current, Object.assign(Object.assign({}, cmd), { params: {
91
+ centerX: center.x,
92
+ centerY: center.y,
93
+ radiusX: radius.x,
94
+ radiusY: radius.y,
95
+ rotation: cmd.params.rotation,
96
+ startRadian: cmd.params.startRadian,
97
+ endRadian: cmd.params.endRadian,
98
+ anticlockwise: cmd.params.anticlockwise,
99
+ } })));
100
+ }
101
+ else if (cmd.name === 'beginPath') {
102
+ ctx.beginPath();
103
+ }
104
+ else if (cmd.name === 'closePath') {
105
+ ctx.closePath();
106
+ }
107
+ });
108
+ ctx.stroke();
109
+ cmdItems.forEach((item) => {
110
+ drawBreakpoint(ctx, item.end);
111
+ });
112
+ });
113
+ }
@@ -0,0 +1,5 @@
1
+ import type { Middleware, CoreEventMap, MiddlewarePathEditorConfig } from '@idraw/types';
2
+ import { getMiddlewarePathEditorStyles } from './static';
3
+ import type { PathEditorSharedStorage } from './types';
4
+ export { getMiddlewarePathEditorStyles };
5
+ export declare const MiddlewarePathEditor: Middleware<PathEditorSharedStorage, CoreEventMap, MiddlewarePathEditorConfig>;