@meta2d/core 1.0.54 → 1.0.56

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 (302) hide show
  1. package/README.md +13 -0
  2. package/package.build.json +39 -0
  3. package/package.json +38 -38
  4. package/src/canvas/canvas.ts +8639 -0
  5. package/src/canvas/canvasImage.ts +525 -0
  6. package/src/canvas/canvasTemplate.ts +257 -0
  7. package/src/canvas/magnifierCanvas.ts +142 -0
  8. package/src/canvas/offscreen.ts +14 -0
  9. package/src/core.ts +5128 -0
  10. package/src/data.ts +86 -0
  11. package/src/diagrams/arrow.ts +50 -0
  12. package/src/diagrams/circle.ts +19 -0
  13. package/src/diagrams/cloud.ts +34 -0
  14. package/src/diagrams/cube.ts +94 -0
  15. package/src/diagrams/diamond.ts +14 -0
  16. package/src/diagrams/file.ts +19 -0
  17. package/src/diagrams/gif.ts +105 -0
  18. package/src/diagrams/{hexagon.js → hexagon.ts} +19 -14
  19. package/src/diagrams/iframe.ts +365 -0
  20. package/src/diagrams/{index.js → index.ts} +36 -34
  21. package/src/diagrams/line/arrow.ts +175 -0
  22. package/src/diagrams/line/curve.ts +260 -0
  23. package/src/diagrams/line/line.ts +409 -0
  24. package/src/diagrams/line/polyline.ts +676 -0
  25. package/src/diagrams/line/smooth.ts +133 -0
  26. package/src/diagrams/message.ts +17 -0
  27. package/src/diagrams/mindLine.ts +31 -0
  28. package/src/diagrams/mindNode.ts +177 -0
  29. package/src/diagrams/panel.ts +149 -0
  30. package/src/diagrams/pentagon.ts +48 -0
  31. package/src/diagrams/pentagram.ts +63 -0
  32. package/src/diagrams/people.ts +23 -0
  33. package/src/diagrams/rectangle.ts +29 -0
  34. package/src/diagrams/svg/parse.ts +319 -0
  35. package/src/diagrams/svgPath.ts +53 -0
  36. package/src/diagrams/triangle.ts +43 -0
  37. package/src/diagrams/video.ts +202 -0
  38. package/src/dialog/dialog.ts +177 -0
  39. package/src/event/event.ts +142 -0
  40. package/src/map/map.ts +239 -0
  41. package/src/options.ts +205 -0
  42. package/src/pen/arrow.ts +259 -0
  43. package/src/pen/math.ts +253 -0
  44. package/src/pen/model.ts +785 -0
  45. package/src/pen/plugin.ts +57 -0
  46. package/src/pen/render.ts +3725 -0
  47. package/src/pen/text.ts +341 -0
  48. package/src/pen/utils.ts +21 -0
  49. package/src/point/point.ts +232 -0
  50. package/src/rect/rect.ts +507 -0
  51. package/src/rect/triangle.ts +16 -0
  52. package/src/scroll/scroll.ts +277 -0
  53. package/src/store/global.ts +38 -0
  54. package/src/store/store.ts +293 -0
  55. package/src/theme.ts +35 -0
  56. package/src/title/title.ts +115 -0
  57. package/src/tooltip/tooltip.ts +199 -0
  58. package/src/utils/clone.ts +79 -0
  59. package/src/utils/color.ts +126 -0
  60. package/src/utils/error.ts +7 -0
  61. package/src/utils/file.ts +46 -0
  62. package/src/utils/{index.d.ts → index.ts} +1 -0
  63. package/src/utils/math.ts +120 -0
  64. package/src/utils/object.ts +23 -0
  65. package/src/utils/padding.ts +48 -0
  66. package/src/utils/time.ts +25 -0
  67. package/src/utils/url.ts +30 -0
  68. package/src/utils/uuid.ts +15 -0
  69. package/index.js +0 -10
  70. package/index.js.map +0 -1
  71. package/src/canvas/canvas.d.ts +0 -455
  72. package/src/canvas/canvas.js +0 -8168
  73. package/src/canvas/canvas.js.map +0 -1
  74. package/src/canvas/canvasImage.d.ts +0 -28
  75. package/src/canvas/canvasImage.js +0 -503
  76. package/src/canvas/canvasImage.js.map +0 -1
  77. package/src/canvas/canvasTemplate.d.ts +0 -19
  78. package/src/canvas/canvasTemplate.js +0 -229
  79. package/src/canvas/canvasTemplate.js.map +0 -1
  80. package/src/canvas/index.js +0 -3
  81. package/src/canvas/index.js.map +0 -1
  82. package/src/canvas/magnifierCanvas.d.ts +0 -20
  83. package/src/canvas/magnifierCanvas.js +0 -101
  84. package/src/canvas/magnifierCanvas.js.map +0 -1
  85. package/src/canvas/offscreen.d.ts +0 -2
  86. package/src/canvas/offscreen.js +0 -14
  87. package/src/canvas/offscreen.js.map +0 -1
  88. package/src/core.d.ts +0 -477
  89. package/src/core.js +0 -5168
  90. package/src/core.js.map +0 -1
  91. package/src/data.d.ts +0 -34
  92. package/src/data.js +0 -85
  93. package/src/data.js.map +0 -1
  94. package/src/diagrams/arrow.d.ts +0 -4
  95. package/src/diagrams/arrow.js +0 -47
  96. package/src/diagrams/arrow.js.map +0 -1
  97. package/src/diagrams/circle.d.ts +0 -2
  98. package/src/diagrams/circle.js +0 -9
  99. package/src/diagrams/circle.js.map +0 -1
  100. package/src/diagrams/cloud.d.ts +0 -2
  101. package/src/diagrams/cloud.js +0 -12
  102. package/src/diagrams/cloud.js.map +0 -1
  103. package/src/diagrams/cube.d.ts +0 -2
  104. package/src/diagrams/cube.js +0 -70
  105. package/src/diagrams/cube.js.map +0 -1
  106. package/src/diagrams/diamond.d.ts +0 -2
  107. package/src/diagrams/diamond.js +0 -13
  108. package/src/diagrams/diamond.js.map +0 -1
  109. package/src/diagrams/file.d.ts +0 -2
  110. package/src/diagrams/file.js +0 -18
  111. package/src/diagrams/file.js.map +0 -1
  112. package/src/diagrams/gif.d.ts +0 -5
  113. package/src/diagrams/gif.js +0 -90
  114. package/src/diagrams/gif.js.map +0 -1
  115. package/src/diagrams/hexagon.d.ts +0 -2
  116. package/src/diagrams/hexagon.js.map +0 -1
  117. package/src/diagrams/iframe.d.ts +0 -2
  118. package/src/diagrams/iframe.js +0 -356
  119. package/src/diagrams/iframe.js.map +0 -1
  120. package/src/diagrams/index.d.ts +0 -71
  121. package/src/diagrams/index.js.map +0 -1
  122. package/src/diagrams/line/arrow.d.ts +0 -2
  123. package/src/diagrams/line/arrow.js +0 -128
  124. package/src/diagrams/line/arrow.js.map +0 -1
  125. package/src/diagrams/line/curve.d.ts +0 -16
  126. package/src/diagrams/line/curve.js +0 -236
  127. package/src/diagrams/line/curve.js.map +0 -1
  128. package/src/diagrams/line/index.js +0 -6
  129. package/src/diagrams/line/index.js.map +0 -1
  130. package/src/diagrams/line/line.d.ts +0 -42
  131. package/src/diagrams/line/line.js +0 -431
  132. package/src/diagrams/line/line.js.map +0 -1
  133. package/src/diagrams/line/polyline.d.ts +0 -10
  134. package/src/diagrams/line/polyline.js +0 -657
  135. package/src/diagrams/line/polyline.js.map +0 -1
  136. package/src/diagrams/line/smooth.d.ts +0 -3
  137. package/src/diagrams/line/smooth.js +0 -174
  138. package/src/diagrams/line/smooth.js.map +0 -1
  139. package/src/diagrams/message.d.ts +0 -2
  140. package/src/diagrams/message.js +0 -15
  141. package/src/diagrams/message.js.map +0 -1
  142. package/src/diagrams/mindLine.d.ts +0 -3
  143. package/src/diagrams/mindLine.js +0 -31
  144. package/src/diagrams/mindLine.js.map +0 -1
  145. package/src/diagrams/mindNode.d.ts +0 -3
  146. package/src/diagrams/mindNode.js +0 -189
  147. package/src/diagrams/mindNode.js.map +0 -1
  148. package/src/diagrams/panel.d.ts +0 -2
  149. package/src/diagrams/panel.js +0 -131
  150. package/src/diagrams/panel.js.map +0 -1
  151. package/src/diagrams/pentagon.d.ts +0 -3
  152. package/src/diagrams/pentagon.js +0 -46
  153. package/src/diagrams/pentagon.js.map +0 -1
  154. package/src/diagrams/pentagram.d.ts +0 -3
  155. package/src/diagrams/pentagram.js +0 -77
  156. package/src/diagrams/pentagram.js.map +0 -1
  157. package/src/diagrams/people.d.ts +0 -2
  158. package/src/diagrams/people.js +0 -19
  159. package/src/diagrams/people.js.map +0 -1
  160. package/src/diagrams/rectangle.d.ts +0 -3
  161. package/src/diagrams/rectangle.js +0 -26
  162. package/src/diagrams/rectangle.js.map +0 -1
  163. package/src/diagrams/svg/parse.d.ts +0 -15
  164. package/src/diagrams/svg/parse.js +0 -326
  165. package/src/diagrams/svg/parse.js.map +0 -1
  166. package/src/diagrams/svgPath.d.ts +0 -2
  167. package/src/diagrams/svgPath.js +0 -30
  168. package/src/diagrams/svgPath.js.map +0 -1
  169. package/src/diagrams/triangle.d.ts +0 -3
  170. package/src/diagrams/triangle.js +0 -41
  171. package/src/diagrams/triangle.js.map +0 -1
  172. package/src/diagrams/video.d.ts +0 -5
  173. package/src/diagrams/video.js +0 -185
  174. package/src/diagrams/video.js.map +0 -1
  175. package/src/dialog/dialog.d.ts +0 -14
  176. package/src/dialog/dialog.js +0 -77
  177. package/src/dialog/dialog.js.map +0 -1
  178. package/src/dialog/index.js +0 -2
  179. package/src/dialog/index.js.map +0 -1
  180. package/src/event/event.d.ts +0 -102
  181. package/src/event/event.js +0 -22
  182. package/src/event/event.js.map +0 -1
  183. package/src/event/index.js +0 -2
  184. package/src/event/index.js.map +0 -1
  185. package/src/map/index.js +0 -2
  186. package/src/map/index.js.map +0 -1
  187. package/src/map/map.d.ts +0 -21
  188. package/src/map/map.js +0 -210
  189. package/src/map/map.js.map +0 -1
  190. package/src/options.d.ts +0 -130
  191. package/src/options.js +0 -80
  192. package/src/options.js.map +0 -1
  193. package/src/pen/arrow.d.ts +0 -4
  194. package/src/pen/arrow.js +0 -188
  195. package/src/pen/arrow.js.map +0 -1
  196. package/src/pen/index.js +0 -7
  197. package/src/pen/index.js.map +0 -1
  198. package/src/pen/math.d.ts +0 -28
  199. package/src/pen/math.js +0 -304
  200. package/src/pen/math.js.map +0 -1
  201. package/src/pen/model.d.ts +0 -512
  202. package/src/pen/model.js +0 -209
  203. package/src/pen/model.js.map +0 -1
  204. package/src/pen/plugin.d.ts +0 -5
  205. package/src/pen/plugin.js +0 -88
  206. package/src/pen/plugin.js.map +0 -1
  207. package/src/pen/render.d.ts +0 -147
  208. package/src/pen/render.js +0 -3229
  209. package/src/pen/render.js.map +0 -1
  210. package/src/pen/text.d.ts +0 -8
  211. package/src/pen/text.js +0 -375
  212. package/src/pen/text.js.map +0 -1
  213. package/src/pen/utils.d.ts +0 -2
  214. package/src/pen/utils.js +0 -41
  215. package/src/pen/utils.js.map +0 -1
  216. package/src/point/index.js +0 -2
  217. package/src/point/index.js.map +0 -1
  218. package/src/point/point.d.ts +0 -65
  219. package/src/point/point.js +0 -179
  220. package/src/point/point.js.map +0 -1
  221. package/src/rect/index.js +0 -2
  222. package/src/rect/index.js.map +0 -1
  223. package/src/rect/rect.d.ts +0 -52
  224. package/src/rect/rect.js +0 -486
  225. package/src/rect/rect.js.map +0 -1
  226. package/src/rect/triangle.d.ts +0 -2
  227. package/src/rect/triangle.js +0 -10
  228. package/src/rect/triangle.js.map +0 -1
  229. package/src/scroll/index.js +0 -2
  230. package/src/scroll/index.js.map +0 -1
  231. package/src/scroll/scroll.d.ts +0 -35
  232. package/src/scroll/scroll.js +0 -221
  233. package/src/scroll/scroll.js.map +0 -1
  234. package/src/store/global.d.ts +0 -25
  235. package/src/store/global.js +0 -18
  236. package/src/store/global.js.map +0 -1
  237. package/src/store/index.js +0 -3
  238. package/src/store/index.js.map +0 -1
  239. package/src/store/store.d.ts +0 -226
  240. package/src/store/store.js +0 -121
  241. package/src/store/store.js.map +0 -1
  242. package/src/theme.d.ts +0 -13
  243. package/src/theme.js +0 -23
  244. package/src/theme.js.map +0 -1
  245. package/src/title/index.js +0 -2
  246. package/src/title/index.js.map +0 -1
  247. package/src/title/title.d.ts +0 -30
  248. package/src/title/title.js +0 -99
  249. package/src/title/title.js.map +0 -1
  250. package/src/tooltip/index.js +0 -2
  251. package/src/tooltip/index.js.map +0 -1
  252. package/src/tooltip/tooltip.d.ts +0 -40
  253. package/src/tooltip/tooltip.js +0 -167
  254. package/src/tooltip/tooltip.js.map +0 -1
  255. package/src/utils/browser.d.ts +0 -1
  256. package/src/utils/browser.js +0 -4
  257. package/src/utils/browser.js.map +0 -1
  258. package/src/utils/clone.d.ts +0 -8
  259. package/src/utils/clone.js +0 -88
  260. package/src/utils/clone.js.map +0 -1
  261. package/src/utils/color.d.ts +0 -3
  262. package/src/utils/color.js +0 -126
  263. package/src/utils/color.js.map +0 -1
  264. package/src/utils/error.d.ts +0 -2
  265. package/src/utils/error.js +0 -6
  266. package/src/utils/error.js.map +0 -1
  267. package/src/utils/file.d.ts +0 -3
  268. package/src/utils/file.js +0 -92
  269. package/src/utils/file.js.map +0 -1
  270. package/src/utils/index.js +0 -9
  271. package/src/utils/index.js.map +0 -1
  272. package/src/utils/math.d.ts +0 -18
  273. package/src/utils/math.js +0 -152
  274. package/src/utils/math.js.map +0 -1
  275. package/src/utils/object.d.ts +0 -2
  276. package/src/utils/object.js +0 -21
  277. package/src/utils/object.js.map +0 -1
  278. package/src/utils/padding.d.ts +0 -7
  279. package/src/utils/padding.js +0 -47
  280. package/src/utils/padding.js.map +0 -1
  281. package/src/utils/time.d.ts +0 -1
  282. package/src/utils/time.js +0 -17
  283. package/src/utils/time.js.map +0 -1
  284. package/src/utils/url.d.ts +0 -4
  285. package/src/utils/url.js +0 -27
  286. package/src/utils/url.js.map +0 -1
  287. package/src/utils/uuid.d.ts +0 -4
  288. package/src/utils/uuid.js +0 -13
  289. package/src/utils/uuid.js.map +0 -1
  290. /package/{index.d.ts → index.ts} +0 -0
  291. /package/src/canvas/{index.d.ts → index.ts} +0 -0
  292. /package/src/diagrams/line/{index.d.ts → index.ts} +0 -0
  293. /package/src/dialog/{index.d.ts → index.ts} +0 -0
  294. /package/src/event/{index.d.ts → index.ts} +0 -0
  295. /package/src/map/{index.d.ts → index.ts} +0 -0
  296. /package/src/pen/{index.d.ts → index.ts} +0 -0
  297. /package/src/point/{index.d.ts → index.ts} +0 -0
  298. /package/src/rect/{index.d.ts → index.ts} +0 -0
  299. /package/src/scroll/{index.d.ts → index.ts} +0 -0
  300. /package/src/store/{index.d.ts → index.ts} +0 -0
  301. /package/src/title/{index.d.ts → index.ts} +0 -0
  302. /package/src/tooltip/{index.d.ts → index.ts} +0 -0
@@ -0,0 +1,115 @@
1
+ import { Pen } from '../pen';
2
+ import { Point } from '../point';
3
+
4
+ export class Title {
5
+ box: HTMLElement;
6
+ private currentAnchor: Point; // 本次 tooltip 在哪个画笔上
7
+ constructor(public parentElement: HTMLElement) {
8
+ this.box = document.createElement('div');
9
+ this.box.className = 'meta2d-title';
10
+
11
+ parentElement.appendChild(this.box);
12
+
13
+ // this.box.onmouseleave = () => {
14
+ // this.hide();
15
+ // };
16
+
17
+ let sheet: any;
18
+ for (let i = 0; i < document.styleSheets.length; i++) {
19
+ if (document.styleSheets[i].title === 'le5le.com/title') {
20
+ sheet = document.styleSheets[i];
21
+ }
22
+ }
23
+
24
+ if (!sheet) {
25
+ let style = document.createElement('style');
26
+ style.type = 'text/css';
27
+ style.title = 'le5le.com/title';
28
+ document.head.appendChild(style);
29
+
30
+ style = document.createElement('style');
31
+ style.type = 'text/css';
32
+ document.head.appendChild(style);
33
+ sheet = style.sheet;
34
+ sheet.insertRule(
35
+ '.meta2d-title{position:absolute;padding:0;z-index:10;left: -9999px;top: -9999px;background:#fff;color:#000; cursor: crosshair;border: 1px solid black;}'
36
+ );
37
+ }
38
+ }
39
+
40
+ /**
41
+ * @returns 此次应该展示的 title
42
+ */
43
+ private static getTitle(anchor: Point) {
44
+ // if (anchor.titleFnJs && !anchor.titleFn) {
45
+ // try {
46
+ // anchor.titleFn = new Function('anchor', anchor.titleFnJs) as (
47
+ // anchor: Point
48
+ // ) => string;
49
+ // } catch (error) {
50
+ // console.log('titleFnJs', error);
51
+ // }
52
+ // }
53
+ // return anchor.titleFn ? anchor.titleFn(anchor) : String(anchor.title);
54
+ }
55
+
56
+ /**
57
+ * @returns 返回设置前的 rect
58
+ */
59
+ private setText(anchor: Point) {
60
+ // this.box.title = anchor.title;
61
+ this.box.innerText = anchor.title;
62
+ }
63
+
64
+ /**
65
+ * 更新文字
66
+ */
67
+ updateText(anchor: Point) {
68
+ if (this.currentAnchor?.id !== anchor.id) {
69
+ return;
70
+ }
71
+ if (Title.titleEmpty(anchor)) {
72
+ return;
73
+ }
74
+
75
+ this.setText(anchor);
76
+ this.changePositionByAnchor(anchor);
77
+ }
78
+
79
+ /**
80
+ * 改变文字会 影响 box 的大小,需要重新设置位置
81
+ * @param oldRect 原
82
+ * @param newRect 新
83
+ */
84
+ private changePositionByAnchor(anchor: Point) {
85
+ this.box.style.left = anchor.x + 10 + 'px';
86
+ this.box.style.top = anchor.y + 10 + 'px';
87
+ }
88
+
89
+ private static titleEmpty(anchor: Point) {
90
+ return !anchor.title; // && !anchor.titleFn && !anchor.titleFnJs;
91
+ }
92
+
93
+ show(anchor: Point, pen: Pen) {
94
+ if (Title.titleEmpty(anchor)) {
95
+ return;
96
+ }
97
+ this.currentAnchor = anchor;
98
+ this.setText(anchor);
99
+ let pos = {
100
+ x: pen.calculative.canvas.store.data.x + anchor.x,
101
+ y: pen.calculative.canvas.store.data.y + anchor.y,
102
+ };
103
+ this.changePositionByAnchor(pos);
104
+ }
105
+
106
+ hide() {
107
+ this.box.style.left = '-9999px';
108
+ this.box.innerText = '';
109
+ this.currentAnchor = null;
110
+ }
111
+
112
+ destroy() {
113
+ this.box.onmouseleave = null;
114
+ }
115
+ }
@@ -0,0 +1,199 @@
1
+ import { Pen } from '../pen';
2
+ import { Point } from '../point';
3
+ import { Meta2dStore } from '../store';
4
+ import type { marked as Marked } from 'marked';
5
+ import { getParent } from '../pen';
6
+
7
+ export class Tooltip {
8
+ box: HTMLElement;
9
+ text: HTMLElement;
10
+ arrowUp: HTMLElement;
11
+ arrowDown: HTMLElement;
12
+ x: number;
13
+ y: number;
14
+ private currentPen: Pen; // 本次 tooltip 在哪个画笔上
15
+ constructor(public parentElement: HTMLElement, private store: Meta2dStore) {
16
+ this.box = document.createElement('div');
17
+ this.text = document.createElement('div');
18
+ this.arrowUp = document.createElement('div');
19
+ this.arrowDown = document.createElement('div');
20
+
21
+ this.box.className = 'meta2d-tooltip';
22
+ this.text.className = 'text';
23
+ this.arrowUp.className = 'arrow';
24
+ this.arrowDown.className = 'arrow down';
25
+
26
+ this.box.appendChild(this.text);
27
+ this.box.appendChild(this.arrowUp);
28
+ this.box.appendChild(this.arrowDown);
29
+ parentElement.appendChild(this.box);
30
+
31
+ this.box.onmouseleave = () => {
32
+ this.hide();
33
+ this.store.lastHover = undefined;
34
+ };
35
+
36
+ let sheet: any;
37
+ for (let i = 0; i < document.styleSheets.length; i++) {
38
+ if (document.styleSheets[i].title === 'le5le.com/tooltip') {
39
+ sheet = document.styleSheets[i];
40
+ }
41
+ }
42
+
43
+ if (!sheet) {
44
+ let style = document.createElement('style');
45
+ style.type = 'text/css';
46
+ style.title = 'le5le.com/tooltip';
47
+ document.head.appendChild(style);
48
+
49
+ style = document.createElement('style');
50
+ style.type = 'text/css';
51
+ document.head.appendChild(style);
52
+ sheet = style.sheet;
53
+ sheet.insertRule(
54
+ '.meta2d-tooltip{position:absolute;padding:8px 0;z-index:10;left: -9999px;top: -9999px;}'
55
+ );
56
+ sheet.insertRule(
57
+ '.meta2d-tooltip .text{max-width:320px;min-height:30px;max-height:400px;outline:none;padding:8px 16px;border-radius:4px;background:#777777;color:#ffffff;line-height:1.8;overflow-y:auto;}'
58
+ );
59
+ sheet.insertRule(
60
+ '.meta2d-tooltip .arrow{position:absolute;border:10px solid transparent;background:transparent;top:-5px;left:50%;transform:translateX(-50%)}'
61
+ );
62
+ sheet.insertRule(
63
+ '.meta2d-tooltip .arrow.down{top:initial;bottom: -1px;}'
64
+ );
65
+ }
66
+ }
67
+
68
+ /**
69
+ * 通过 pen 的 titleFn titleFnJs title 来获取 title
70
+ * @returns 此次应该展示的 title
71
+ */
72
+ private static getTitle(pen: Pen) {
73
+ if (pen.titleFnJs && !pen.titleFn) {
74
+ try {
75
+ pen.titleFn = new Function('pen', pen.titleFnJs) as (
76
+ pen: Pen
77
+ ) => string;
78
+ } catch (error) {
79
+ console.log('titleFnJs', error);
80
+ }
81
+ }
82
+ return pen.titleFn ? pen.titleFn(pen) : String(pen.title);
83
+ }
84
+
85
+ /**
86
+ * 更改 tooltip dom 的文本
87
+ * @returns 返回设置前的 rect
88
+ */
89
+ private setText(pen: Pen): DOMRect {
90
+ const oldElemRect = this.box.getBoundingClientRect();
91
+ let marked: typeof Marked = globalThis.marked;
92
+ const title = Tooltip.getTitle(pen);
93
+ if (marked) {
94
+ this.text.innerHTML = marked(title);
95
+ const a = this.text.getElementsByTagName('A');
96
+ for (let i = 0; i < a.length; ++i) {
97
+ a[i].setAttribute('target', '_blank');
98
+ }
99
+ } else {
100
+ this.text.innerHTML = title;
101
+ }
102
+ return oldElemRect;
103
+ }
104
+
105
+ /**
106
+ * 更新文字
107
+ */
108
+ updateText(pen: Pen) {
109
+ if (this.currentPen?.id !== pen.id) {
110
+ return;
111
+ }
112
+
113
+ if (Tooltip.titleEmpty(pen)) {
114
+ return;
115
+ }
116
+
117
+ const oldRect = this.setText(pen);
118
+ const newRect = this.box.getBoundingClientRect();
119
+ this.changePositionByText(oldRect, newRect);
120
+ }
121
+
122
+ /**
123
+ * 改变文字会 影响 box 的大小,需要重新设置位置
124
+ * @param oldRect 原
125
+ * @param newRect 新
126
+ */
127
+ private changePositionByText(oldRect: DOMRect, newRect: DOMRect) {
128
+ this.x -= (newRect.width - oldRect.width) / 2;
129
+ this.y -= newRect.height - oldRect.height;
130
+ this.box.style.left = this.x + 'px';
131
+ this.box.style.top = this.y + 'px';
132
+ }
133
+
134
+ private static titleEmpty(pen: Pen) {
135
+ return !pen.title && !pen.titleFn && !pen.titleFnJs;
136
+ }
137
+
138
+ show(pen: Pen, pos: Point) {
139
+ this.currentPen = pen;
140
+ if (Tooltip.titleEmpty(pen)) {
141
+ let parent = getParent(pen, true);
142
+ if (parent) {
143
+ this.show(parent, pos);
144
+ }
145
+ return;
146
+ }
147
+
148
+ this.setText(pen);
149
+ const elemRect = this.box.getBoundingClientRect();
150
+ const rect = pen.calculative.worldRect;
151
+ let x = pen.calculative.canvas.store.data.x + pos.x - elemRect.width / 2;
152
+ let y = pen.calculative.canvas.store.data.y + pos.y - elemRect.height;
153
+ if (!pen.type) {
154
+ x =
155
+ pen.calculative.canvas.store.data.x +
156
+ rect.x -
157
+ (elemRect.width - rect.width) / 2;
158
+ y =
159
+ pen.calculative.canvas.store.data.y +
160
+ rect.ey -
161
+ elemRect.height -
162
+ rect.height;
163
+ }
164
+
165
+ if (y > 0) {
166
+ this.arrowUp.style.borderBottomColor = 'transparent';
167
+ this.arrowDown.style.borderTopColor = '#777777';
168
+ } else {
169
+ y += elemRect.height + rect.height + 5;
170
+ this.arrowUp.style.borderBottomColor = '#777777';
171
+ this.arrowDown.style.borderTopColor = 'transparent';
172
+ }
173
+
174
+ this.x = x;
175
+ this.y = y;
176
+ this.box.style.left = this.x + 'px';
177
+ this.box.style.top = this.y + 'px';
178
+ }
179
+
180
+ hide() {
181
+ this.currentPen = null;
182
+ this.x = -9999;
183
+ this.box.style.left = '-9999px';
184
+ }
185
+
186
+ translate(x: number, y: number) {
187
+ if (this.x < -1000) {
188
+ return;
189
+ }
190
+ this.x += x;
191
+ this.y += y;
192
+ this.box.style.left = this.x + 'px';
193
+ this.box.style.top = this.y + 'px';
194
+ }
195
+
196
+ destroy() {
197
+ this.box.onmouseleave = null;
198
+ }
199
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * 拷贝一个对象
3
+ * @param o - object to clone
4
+ * @param keepCalc 是否保留计算属性, false, 不保留, true, 保留(但 calculative.canvas 属性仍不保存)
5
+ * @returns 拷贝后的对象
6
+ */
7
+ export function deepClone<T>(o: T, keepCalc = false): T {
8
+ if (Array.isArray(o)) {
9
+ const arr = [] as T & any[];
10
+ o.forEach((item) => {
11
+ arr.push(deepClone(item, keepCalc));
12
+ });
13
+ return arr;
14
+ } else if (typeof o === 'object') {
15
+ if (o === null) {
16
+ return null;
17
+ } else if (o.constructor === RegExp) {
18
+ return o;
19
+ }
20
+ const _o = {} as T;
21
+ for (const key in o) {
22
+ if (
23
+ ['canvas', 'lastFrame'].includes(key) ||
24
+ o[key] instanceof HTMLImageElement ||
25
+ o[key] instanceof HTMLMediaElement
26
+ ) {
27
+ continue;
28
+ } else if (key === 'calculative' && !keepCalc) {
29
+ continue;
30
+ } else if (key === 'singleton') {
31
+ if (keepCalc) {
32
+ _o[key] = {} as any;
33
+ } else {
34
+ _o[key] = o[key];
35
+ }
36
+ continue;
37
+ }
38
+ _o[key] = deepClone(o[key], keepCalc);
39
+ }
40
+ return _o;
41
+ }
42
+
43
+ return o;
44
+ }
45
+
46
+ export function deepSetValue<T>(o: any, keyWords: string[], value: number): T {
47
+ if (Array.isArray(o)) {
48
+ const arr = [] as T & any[];
49
+ o.forEach((item) => {
50
+ arr.push(deepSetValue(item, keyWords, value));
51
+ });
52
+ return arr;
53
+ } else if (typeof o === 'object') {
54
+ if (o === null) {
55
+ return null;
56
+ }
57
+ // const _o = {} as any;
58
+ for (const key in o) {
59
+ if (keyWords.includes(key)) {
60
+ if(Array.isArray(o[key])){
61
+ o[key].forEach((i,index)=>{
62
+ if(!Number.isNaN(Number(i))){
63
+ o[key][index] = Number(i * value);
64
+ }
65
+ });
66
+ }else {
67
+ if(Number.isNaN(Number(o[key]))){
68
+ continue;
69
+ }
70
+ o[key] = Number(o[key]) * value;
71
+ }
72
+ } else {
73
+ o[key] = deepSetValue(o[key], keyWords, value);
74
+ }
75
+ }
76
+ return o;
77
+ }
78
+ return o;
79
+ }
@@ -0,0 +1,126 @@
1
+ // pSBC - Shade Blend Convert - Version 4.0 - 02/18/2019
2
+ // https://github.com/PimpTrizkit/PJs/edit/master/pSBC.js
3
+
4
+ export function pSBCr(d) {
5
+ const i = parseInt,
6
+ m = Math.round;
7
+ let n = d.length,
8
+ x: any = {};
9
+ if (n > 9) {
10
+ const [r, g, b, a] = (d = d.split(','));
11
+ n = d.length;
12
+ if (n < 3 || n > 4) return null;
13
+ (x.r = i(r[3] == 'a' ? r.slice(5) : r.slice(4))),
14
+ (x.g = i(g)),
15
+ (x.b = i(b)),
16
+ (x.a = a ? parseFloat(a) : -1);
17
+ } else {
18
+ if (n == 8 || n == 6 || n < 4) return null;
19
+ if (n < 6)
20
+ d =
21
+ '#' +
22
+ d[1] +
23
+ d[1] +
24
+ d[2] +
25
+ d[2] +
26
+ d[3] +
27
+ d[3] +
28
+ (n > 4 ? d[4] + d[4] : '');
29
+ d = i(d.slice(1), 16);
30
+ if (n == 9 || n == 5)
31
+ (x.r = (d >> 24) & 255),
32
+ (x.g = (d >> 16) & 255),
33
+ (x.b = (d >> 8) & 255),
34
+ (x.a = m((d & 255) / 0.255) / 1000);
35
+ else (x.r = d >> 16), (x.g = (d >> 8) & 255), (x.b = d & 255), (x.a = -1);
36
+ }
37
+ return x;
38
+ }
39
+
40
+ /*
41
+ example:
42
+ pSBC ( 0.42, color1 ); // rgb(20,60,200) + [42% Lighter] => rgb(166,171,225)
43
+ pSBC ( -0.4, color5 ); // #F3A + [40% Darker] => #c62884
44
+
45
+ pSBC ( -0.5, color2, color8, true ); // rgba(20,60,200,0.67423) + rgba(200,60,20,0.98631) + [50% Blend] => rgba(110,60,110,0.83)
46
+ pSBC ( 0.7, color2, color7, true ); // rgba(20,60,200,0.67423) + rgb(200,60,20) + [70% Blend] => rgba(146,60,74,0.67423)
47
+
48
+ more:
49
+ https://github-wiki-see.page/m/PimpTrizkit/PJs/wiki/12.-Shade%2C-Blend-and-Convert-a-Web-Color-%28pSBC.js%29
50
+ */
51
+
52
+ export function pSBC(p, c0, c1?, l?) {
53
+ let r,
54
+ g,
55
+ b,
56
+ P,
57
+ f,
58
+ t,
59
+ h,
60
+ m = Math.round,
61
+ a: any = typeof c1 == 'string';
62
+ if (
63
+ typeof p != 'number' ||
64
+ p < -1 ||
65
+ p > 1 ||
66
+ typeof c0 != 'string' ||
67
+ (c0[0] != 'r' && c0[0] != '#') ||
68
+ (c1 && !a)
69
+ )
70
+ return null;
71
+ (h = c0.length > 9),
72
+ (h = a ? (c1.length > 9 ? true : c1 == 'c' ? !h : false) : h),
73
+ (f = pSBCr(c0)),
74
+ (P = p < 0),
75
+ (t =
76
+ c1 && c1 != 'c'
77
+ ? pSBCr(c1)
78
+ : P
79
+ ? { r: 0, g: 0, b: 0, a: -1 }
80
+ : { r: 255, g: 255, b: 255, a: -1 }),
81
+ (p = P ? p * -1 : p),
82
+ (P = 1 - p);
83
+ if (!f || !t) return null;
84
+ if (l)
85
+ (r = m(P * f.r + p * t.r)),
86
+ (g = m(P * f.g + p * t.g)),
87
+ (b = m(P * f.b + p * t.b));
88
+ else
89
+ (r = m((P * f.r ** 2 + p * t.r ** 2) ** 0.5)),
90
+ (g = m((P * f.g ** 2 + p * t.g ** 2) ** 0.5)),
91
+ (b = m((P * f.b ** 2 + p * t.b ** 2) ** 0.5));
92
+ (a = f.a),
93
+ (t = t.a),
94
+ (f = a >= 0 || t >= 0),
95
+ (a = f ? (a < 0 ? t : t < 0 ? a : a * P + t * p) : 0);
96
+ if (h)
97
+ return (
98
+ 'rgb' +
99
+ (f ? 'a(' : '(') +
100
+ r +
101
+ ',' +
102
+ g +
103
+ ',' +
104
+ b +
105
+ (f ? ',' + m(a * 1000) / 1000 : '') +
106
+ ')'
107
+ );
108
+ else
109
+ return (
110
+ '#' +
111
+ (4294967296 + r * 16777216 + g * 65536 + b * 256 + (f ? m(a * 255) : 0))
112
+ .toString(16)
113
+ .slice(1, f ? undefined : -2)
114
+ );
115
+ }
116
+
117
+ globalThis.pSBC = pSBC;
118
+
119
+ export function rgba(c: string, p: number) {
120
+ const f = pSBCr(c) || { r: 0, g: 0, b: 0 };
121
+ if (f.a < 0) {
122
+ return `rgba(${f.r},${f.g},${f.b},${p})`;
123
+ }
124
+
125
+ return `rgba(${f.r},${f.g},${f.b},${p + f.a})`;
126
+ }
@@ -0,0 +1,7 @@
1
+ import { Meta2dStore } from '../store';
2
+
3
+ export function lockedError(store: Meta2dStore) {
4
+ if (store.data.locked) {
5
+ throw new Error('canvas is locked');
6
+ }
7
+ }
@@ -0,0 +1,46 @@
1
+ export async function fileToBase64(file: File): Promise<string> {
2
+ return new Promise((resolve, reject) => {
3
+ const reader = new FileReader();
4
+ reader.onload = (e) => {
5
+ resolve(e.target.result as string);
6
+ };
7
+ reader.onerror = (e) => {
8
+ reject(e);
9
+ };
10
+ reader.readAsDataURL(file);
11
+ });
12
+ }
13
+
14
+ export async function uploadFile(
15
+ file: File,
16
+ url: string,
17
+ params: Record<string, any>,
18
+ headers: Record<string, string>
19
+ ): Promise<string> {
20
+ const formData = new FormData();
21
+ // 后端接受的 formData 文件属性名一定为 file
22
+ formData.append('file', file);
23
+ if (params) {
24
+ for (const key in params) {
25
+ if (params.hasOwnProperty(key)) {
26
+ formData.append(key, params[key]);
27
+ }
28
+ }
29
+ }
30
+ const res = await fetch(url, {
31
+ method: 'POST',
32
+ headers,
33
+ body: formData,
34
+ });
35
+ // 后端返回的一级属性中,必须包含一个名为url的属性
36
+ return (await res.json()).url;
37
+ }
38
+
39
+ export function loadCss(url: string, success?: any, error?: any) {
40
+ var link = document.createElement('link');
41
+ link.href = url;
42
+ link.rel = 'stylesheet';
43
+ success && (link.onload = success);
44
+ error && (link.onerror = error);
45
+ document.head.appendChild(link);
46
+ }
@@ -6,3 +6,4 @@ export * from './clone';
6
6
  export * from './file';
7
7
  export * from './url';
8
8
  export * from './object';
9
+ export * from './time';
@@ -0,0 +1,120 @@
1
+ export function abs(num: number, percent: number | string): number {
2
+ if (+percent) {
3
+ return +percent;
4
+ }
5
+
6
+ if (!percent || percent[(percent as string).length - 1] !== '%') {
7
+ return 0;
8
+ }
9
+
10
+ percent = (percent as string).substr(0, (percent as string).length - 1);
11
+
12
+ return (num * +percent) / 100;
13
+ }
14
+
15
+ /**
16
+ * 实际值是否在范围中, 数学上的开闭
17
+ * @param realValue 实际值
18
+ * @param collection 集合规范,与数学上相同,如[0, 100],前闭后闭;如[0, 100),前闭后开;
19
+ * @returns undefined 说明参数不规范 ,true 说明在范围内,false 说明不在范围内
20
+ */
21
+ export function valueInRange(realValue: number, collection: unknown): boolean {
22
+ if (isNaN(realValue)) {
23
+ console.warn(`realValue not number`);
24
+ return;
25
+ }
26
+ if (typeof collection !== 'string') {
27
+ console.warn('collection must be string');
28
+ return;
29
+ }
30
+ const [start, end] = [collection[0], collection[collection.length - 1]];
31
+ if (!['[', '('].includes(start)) {
32
+ console.warn('collection must start with "[" or "("');
33
+ return;
34
+ }
35
+ if (![']', ')'].includes(end)) {
36
+ console.warn('collection must end with "]" or ")"');
37
+ return;
38
+ }
39
+ const nums = collection.substring(1, collection.length - 1).split(',');
40
+ if (nums.length !== 2) {
41
+ console.warn('collection must have 2 numbers');
42
+ return;
43
+ }
44
+ const [startNum, endNum] = [+nums[0], +nums[1]];
45
+ if (startNum >= endNum) {
46
+ console.warn('startNum must less than endNum');
47
+ return;
48
+ }
49
+ // 大于 startNum 左肯定成立
50
+ const left =
51
+ realValue > startNum || (start === '[' && realValue === startNum)
52
+ ? true
53
+ : false;
54
+ if (!left) {
55
+ return false;
56
+ }
57
+ // 执行到这,左边已经是true了,判断右边
58
+ const right =
59
+ realValue < endNum || (end === ']' && realValue === endNum) ? true : false;
60
+
61
+ return right;
62
+ }
63
+
64
+ /**
65
+ * 实际值是否在数组中,即是否属于
66
+ * 例如: [1,2,3] 只有 1 2 3 是属于 collection 的
67
+ * .. 范围值 30..50 等于 闭区间的 [30,50] ,即范围值
68
+ * [1,20,30..50,65] 只有 1 20 30..50 65 是属于 collection 的
69
+ * @param realValue 实际值
70
+ * @param collection 集合
71
+ * @returns undefined 说明参数不规范 ,true 说明在范围内,false 说明不在范围内
72
+ */
73
+ export function valueInArray(realValue: any, collection: unknown): boolean {
74
+ // if (isNaN(realValue)) {
75
+ // console.warn(`realValue not number`);
76
+ // return;
77
+ // }
78
+ //允许字符串的情况
79
+ if (typeof collection !== 'string') {
80
+ console.warn('collection must be string');
81
+ return;
82
+ }
83
+ const [start, end] = [collection[0], collection[collection.length - 1]];
84
+ if (start !== '[' || end !== ']') {
85
+ console.warn('collection must start with "[" and end with "]"');
86
+ return;
87
+ }
88
+ const numStrs = collection.substring(1, collection.length - 1).split(',');
89
+ for (const numStr of numStrs) {
90
+ if (numStr.includes('..')) {
91
+ // 范围值
92
+ const [start, end] = numStr.split('..');
93
+ const [startNum, endNum] = [+start, +end];
94
+ if (startNum >= endNum) {
95
+ console.warn('startNum must less than endNum');
96
+ return;
97
+ }
98
+ if (realValue >= startNum && realValue <= endNum) {
99
+ return true;
100
+ }
101
+ } else {
102
+ // 单个值
103
+ // let num:any = +numStr;
104
+ // if(Number.isNaN(num)){
105
+ // num = numStr;
106
+ // const [start, end] = [num[0], num[num.length - 1]];
107
+ // if (!((start !== '"' && end !== '"')||(start !== "'" && end !== "'"))) {
108
+ // console.warn('Not a valid string');
109
+ // return;
110
+ // }else{
111
+ // num = num.substring(1, num.length - 1)
112
+ // }
113
+ // }
114
+ if (realValue == numStr) {
115
+ return true;
116
+ }
117
+ }
118
+ }
119
+ return false;
120
+ }