@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,260 @@
1
+ import { Direction } from '../../data';
2
+ import { facePen, getToAnchor, Pen } from '../../pen';
3
+ import { distance, Point, PrevNextType, rotatePoint } from '../../point';
4
+ import { Meta2dStore } from '../../store';
5
+ import { s8 } from '../../utils';
6
+
7
+ export function curve(store: Meta2dStore, pen: Pen, mousedwon?: Point) {
8
+ if (!pen.calculative.worldAnchors) {
9
+ pen.calculative.worldAnchors = [];
10
+ }
11
+
12
+ if (mousedwon) {
13
+ if (pen.calculative.activeAnchor) {
14
+ pen.calculative.activeAnchor.next = {
15
+ penId: pen.id,
16
+ x: mousedwon.x,
17
+ y: mousedwon.y,
18
+ };
19
+ if (
20
+ distance(
21
+ pen.calculative.activeAnchor.next,
22
+ pen.calculative.activeAnchor
23
+ ) < 5
24
+ ) {
25
+ pen.calculative.activeAnchor.next = undefined;
26
+ } else {
27
+ pen.calculative.activeAnchor.prev = {
28
+ ...pen.calculative.activeAnchor.next,
29
+ };
30
+ rotatePoint(
31
+ pen.calculative.activeAnchor.prev,
32
+ 180,
33
+ pen.calculative.activeAnchor
34
+ );
35
+ }
36
+ }
37
+ } else {
38
+ const from = pen.calculative.worldAnchors[0];
39
+ if (!from.next) {
40
+ const fromFace = facePen(from, store.pens[from.connectTo]);
41
+ calcCurveCP(from, fromFace, 50);
42
+ from.prev = undefined;
43
+ }
44
+
45
+ const to =
46
+ pen.calculative.worldAnchors[pen.calculative.worldAnchors.length - 1];
47
+ if (to && to !== from && !to.prev) {
48
+ const toFace = facePen(to, store.pens[to.connectTo]);
49
+ calcCurveCP(to, toFace, -50);
50
+ to.next = undefined;
51
+ }
52
+ }
53
+ }
54
+
55
+ function calcCurveCP(pt: Point, d: Direction, dis: number) {
56
+ switch (d) {
57
+ case Direction.Up:
58
+ pt.prev = {
59
+ penId: pt.penId,
60
+ x: pt.x,
61
+ y: pt.y + dis,
62
+ };
63
+ pt.next = {
64
+ penId: pt.penId,
65
+ x: pt.x,
66
+ y: pt.y - dis,
67
+ };
68
+ break;
69
+ case Direction.Right:
70
+ pt.prev = {
71
+ penId: pt.penId,
72
+ x: pt.x - dis,
73
+ y: pt.y,
74
+ };
75
+ pt.next = {
76
+ penId: pt.penId,
77
+ x: pt.x + dis,
78
+ y: pt.y,
79
+ };
80
+ break;
81
+ case Direction.Bottom:
82
+ pt.prev = {
83
+ penId: pt.penId,
84
+ x: pt.x,
85
+ y: pt.y - dis,
86
+ };
87
+ pt.next = {
88
+ penId: pt.penId,
89
+ x: pt.x,
90
+ y: pt.y + dis,
91
+ };
92
+ break;
93
+ case Direction.Left:
94
+ pt.prev = {
95
+ penId: pt.penId,
96
+ x: pt.x + dis,
97
+ y: pt.y,
98
+ };
99
+ pt.next = {
100
+ penId: pt.penId,
101
+ x: pt.x - dis,
102
+ y: pt.y,
103
+ };
104
+ break;
105
+ }
106
+ }
107
+
108
+ // Get a point in quadratic.
109
+ // pos - The position of point in quadratic. It is expressed as a percentage(0 - 1).
110
+ export function getQuadraticPoint(
111
+ step: number,
112
+ from: Point,
113
+ cp: Point,
114
+ to: Point
115
+ ) {
116
+ const pos = 1 - step;
117
+ const x = pos * pos * from.x + 2 * pos * step * cp.x + step * step * to.x;
118
+ const y = pos * pos * from.y + 2 * pos * step * cp.y + step * step * to.y;
119
+ return { x, y, step };
120
+ }
121
+
122
+ // Get a point in bezier.
123
+ // pos - The position of point in bezier. It is expressed as a percentage(0 - 1).
124
+ export function getBezierPoint(
125
+ step: number,
126
+ from: Point,
127
+ cp1: Point,
128
+ cp2: Point,
129
+ to: Point
130
+ ) {
131
+ const { x: x1, y: y1 } = from;
132
+ const { x: x2, y: y2 } = to;
133
+ const { x: cx1, y: cy1 } = cp1;
134
+ const { x: cx2, y: cy2 } = cp2;
135
+
136
+ const pos = 1 - step;
137
+ const x =
138
+ x1 * pos * pos * pos +
139
+ 3 * cx1 * step * pos * pos +
140
+ 3 * cx2 * step * step * pos +
141
+ x2 * step * step * step;
142
+ const y =
143
+ y1 * pos * pos * pos +
144
+ 3 * cy1 * step * pos * pos +
145
+ 3 * cy2 * step * step * pos +
146
+ y2 * step * step * step;
147
+ return { x, y, step };
148
+ }
149
+
150
+ function lerp(pt1: Point, pt2: Point, t: number) {
151
+ return {
152
+ x: pt1.x + t * (pt2.x - pt1.x),
153
+ y: pt1.y + t * (pt2.y - pt1.y),
154
+ };
155
+ }
156
+
157
+ export function getSplitAnchor(pen: Pen, pt: Point, index: number) {
158
+ let from = pen.calculative.worldAnchors[index];
159
+ let to = pen.calculative.worldAnchors[index + 1];
160
+ if(!to && pen.close){
161
+ to = pen.calculative.worldAnchors[0];
162
+ }
163
+ const t = pt.step;
164
+ let anchor: Point;
165
+ if (from.next && to.prev) {
166
+ const p0 = from;
167
+ const p1 = from.next;
168
+ const p2 = to.prev;
169
+ const p3 = to;
170
+ const p4 = lerp(p0, p1, t);
171
+ const p5 = lerp(p1, p2, t);
172
+ const p6 = lerp(p2, p3, t);
173
+ const p7: Point = lerp(p4, p5, t);
174
+ const p8: Point = lerp(p5, p6, t);
175
+ anchor = lerp(p7, p8, t);
176
+ p7.penId = pen.id;
177
+ anchor.prev = p7;
178
+ p8.penId = pen.id;
179
+ anchor.next = p8;
180
+ from.next.x = p4.x;
181
+ from.next.y = p4.y;
182
+ to.prev.x = p6.x;
183
+ to.prev.y = p6.y;
184
+ } else if (from.next || to.prev) {
185
+ const p0 = from;
186
+ const p1 = from.next || to.prev;
187
+ const p2 = to;
188
+ const p3: Point = lerp(p0, p1, t);
189
+ const p4: Point = lerp(p1, p2, t);
190
+ anchor = pt;
191
+ p3.penId = pen.id;
192
+ p4.penId = pen.id;
193
+ anchor.prev = p3;
194
+ anchor.next = p4;
195
+ from.next = undefined;
196
+ to.prev = undefined;
197
+ } else {
198
+ // 并非贝塞尔点,即 from 和 to 之间是一条直线
199
+ anchor = pt;
200
+ }
201
+
202
+ anchor.penId = pen.id;
203
+ anchor.id = s8();
204
+ anchor.prevNextType = PrevNextType.Bilateral;
205
+ return anchor;
206
+ }
207
+
208
+ export function mind(store: Meta2dStore, pen: Pen, mousedwon?: Point) {
209
+ if (!pen.calculative.worldAnchors) {
210
+ pen.calculative.worldAnchors = [];
211
+ }
212
+
213
+ if (pen.calculative.worldAnchors.length < 2) {
214
+ return;
215
+ }
216
+
217
+ let from = pen.calculative.activeAnchor;
218
+ let to = mousedwon || getToAnchor(pen);
219
+ if (!from || !to) {
220
+ return;
221
+ }
222
+
223
+ const dis = 20;
224
+
225
+ const fromPen = store.pens[from.connectTo];
226
+ let fromFace = facePen(from, fromPen);
227
+ if (fromFace === Direction.None) {
228
+ if (to.x > from.x) {
229
+ fromFace = Direction.Right;
230
+ } else {
231
+ fromFace = Direction.Left;
232
+ }
233
+ }
234
+ from.next = {
235
+ id: s8(),
236
+ penId: pen.id,
237
+ x: from.x,
238
+ y: from.y,
239
+ prevNextType: 2,
240
+ };
241
+ to.prev = { id: s8(), penId: pen.id, x: to.x, y: to.y, prevNextType: 2 };
242
+ switch (fromFace) {
243
+ case Direction.Up:
244
+ from.next.y -= dis;
245
+ to.prev.y = from.y;
246
+ break;
247
+ case Direction.Bottom:
248
+ from.next.y += dis;
249
+ to.prev.y = from.y;
250
+ break;
251
+ case Direction.Left:
252
+ from.next.x -= dis;
253
+ to.prev.x = from.x;
254
+ break;
255
+ default:
256
+ from.next.x += dis;
257
+ to.prev.x = from.x;
258
+ break;
259
+ }
260
+ }
@@ -0,0 +1,409 @@
1
+ import { deleteTempAnchor, getFromAnchor, getGradientAnimatePath, getToAnchor, Pen } from '../../pen';
2
+ import { hitPoint, Point } from '../../point';
3
+ import { getRectOfPoints, pointInSimpleRect, Rect } from '../../rect';
4
+ import { Meta2dStore } from '../../store';
5
+ import { getBezierPoint, getQuadraticPoint } from './curve';
6
+
7
+ export function line(
8
+ pen: Pen,
9
+ ctx?: CanvasRenderingContext2D | Path2D
10
+ ): Path2D {
11
+ const path = !ctx ? new Path2D() : ctx;
12
+ if (pen.lineName === 'line' || pen.lineName === 'polyline') {
13
+ if (pen.calculative.lineSmooth) {
14
+ let _path = getGradientAnimatePath(pen);
15
+ (path as Path2D).addPath(_path);
16
+ if (path instanceof Path2D) return path;
17
+ }
18
+ }
19
+ const worldAnchors = pen.calculative.worldAnchors;
20
+ if (worldAnchors.length > 1) {
21
+ let from: Point; // 上一个点
22
+ worldAnchors.forEach((pt: Point) => {
23
+ if (from) {
24
+ draw(path, from, pt);
25
+ } else {
26
+ pt.start = true;
27
+ }
28
+ from = pt;
29
+ });
30
+ if (pen.close) {
31
+ draw(path, from, worldAnchors[0]);
32
+ }
33
+ }
34
+ if (path instanceof Path2D) return path;
35
+ }
36
+
37
+ export function lineSegment(store: Meta2dStore, pen: Pen, mousedwon?: Point) {
38
+ if (!pen.calculative.worldAnchors) {
39
+ pen.calculative.worldAnchors = [];
40
+ }
41
+
42
+ if (pen.calculative.worldAnchors.length < 2 || pen.anchors?.length > 1) {
43
+ return;
44
+ }
45
+
46
+ const from = getFromAnchor(pen);
47
+ const to = getToAnchor(pen);
48
+ if (!from || !to || !to.id || from === to) {
49
+ return;
50
+ }
51
+ from.next = undefined;
52
+ deleteTempAnchor(pen);
53
+ to.prev = undefined;
54
+ pen.calculative.worldAnchors.push(to);
55
+ }
56
+
57
+ function draw(path: CanvasRenderingContext2D | Path2D, from: Point, to: Point) {
58
+ if (!to || to.isTemp) {
59
+ return;
60
+ }
61
+ from.start && path.moveTo(from.x, from.y);
62
+ if (from.next) {
63
+ if (to.prev) {
64
+ path.bezierCurveTo(
65
+ from.next.x,
66
+ from.next.y,
67
+ to.prev.x,
68
+ to.prev.y,
69
+ to.x,
70
+ to.y
71
+ );
72
+ } else {
73
+ path.quadraticCurveTo(from.next.x, from.next.y, to.x, to.y);
74
+ }
75
+ } else {
76
+ if (to.prev) {
77
+ path.quadraticCurveTo(to.prev.x, to.prev.y, to.x, to.y);
78
+ } else {
79
+ path.lineTo(to.x, to.y);
80
+ }
81
+ }
82
+ }
83
+
84
+ export function getLineRect(pen: Pen) {
85
+ getLineLength(pen);
86
+ return getRectOfPoints(getLinePoints(pen));
87
+ }
88
+
89
+ /**
90
+ * 获取连线的 points ,并非 worldAnchors ,worldAnchors 之前的路径点也会记录
91
+ */
92
+ export function getLinePoints(pen: Pen) {
93
+ const pts: Point[] = [];
94
+ let from: Point; // 上一个点
95
+ pen.calculative.worldAnchors.forEach((pt: Point) => {
96
+ pts.push(pt);
97
+ from && pts.push(...getPoints(from, pt, pen));
98
+ from = pt;
99
+ });
100
+ if (pen.close && pen.calculative.worldAnchors.length > 1) {
101
+ pts.push(...getPoints(from, pen.calculative.worldAnchors[0], pen));
102
+ }
103
+ return pts;
104
+ }
105
+
106
+ export function getLineR(pen: Pen) {
107
+ return pen?.lineWidth ? pen.lineWidth / 2 + 4 : 4;
108
+ }
109
+
110
+ export function getPoints(from: Point, to: Point, pen?: Pen) {
111
+ const pts: Point[] = [];
112
+ if (!to) {
113
+ return pts;
114
+ }
115
+
116
+ let step = 0.02;
117
+ if (from.lineLength) {
118
+ const r = getLineR(pen);
119
+ step = r / from.lineLength;
120
+ }
121
+ if (from.next) {
122
+ if (to.prev) {
123
+ for (let i = step; i < 1; i += step) {
124
+ pts.push(getBezierPoint(i, from, from.next, to.prev, to));
125
+ }
126
+ } else {
127
+ for (let i = step; i < 1; i += step) {
128
+ pts.push(getQuadraticPoint(i, from, from.next, to));
129
+ }
130
+ }
131
+ } else {
132
+ if (to.prev) {
133
+ for (let i = step; i < 1; i += step) {
134
+ pts.push(getQuadraticPoint(i, from, to.prev, to));
135
+ }
136
+ } else {
137
+ pts.push({ x: to.x, y: to.y });
138
+ }
139
+ }
140
+ if (pts.length > 1) {
141
+ from.curvePoints = pts;
142
+ }
143
+
144
+ return pts;
145
+ }
146
+
147
+ export function pointInLine(pt: Point, pen: Pen) {
148
+ const r = getLineR(pen);
149
+
150
+ let i = 0;
151
+ let from: Point; // 上一个点
152
+ let point: Point;
153
+ for (const anchor of pen.calculative.worldAnchors) {
154
+ if (from) {
155
+ point = pointInLineSegment(pt, from, anchor, r);
156
+ if (point) {
157
+ return {
158
+ i,
159
+ point,
160
+ };
161
+ }
162
+ ++i;
163
+ }
164
+ from = anchor;
165
+ }
166
+ if (
167
+ pen.close &&
168
+ pen.calculative.worldAnchors.length > 1 &&
169
+ (point = pointInLineSegment(pt, from, pen.calculative.worldAnchors[0], r))
170
+ ) {
171
+ return {
172
+ i,
173
+ point,
174
+ };
175
+ }
176
+ }
177
+ export function pointInLineSegment(pt: Point, pt1: Point, pt2: Point, r = 4) {
178
+ if (!pt1.next && !pt2.prev) {
179
+ const { x: x1, y: y1 } = pt1;
180
+ const { x: x2, y: y2 } = pt2;
181
+ const minX = Math.min(x1, x2);
182
+ const maxX = Math.max(x1, x2);
183
+ const minY = Math.min(y1, y2);
184
+ const maxY = Math.max(y1, y2);
185
+ if (
186
+ !(
187
+ pt.x >= minX - r &&
188
+ pt.x <= maxX + r &&
189
+ pt.y >= minY - r &&
190
+ pt.y <= maxY + r
191
+ )
192
+ ) {
193
+ return;
194
+ }
195
+ return pointToLine(pt, pt1, pt2, r);
196
+ } else if (pt1.curvePoints) {
197
+ for (const point of pt1.curvePoints) {
198
+ if (hitPoint(pt, point, r)) {
199
+ return point;
200
+ }
201
+ }
202
+ }
203
+ }
204
+
205
+ export function pointToLine(pt: Point, pt1: Point, pt2: Point, r = 4) {
206
+ // 竖线
207
+ if (pt1.x === pt2.x) {
208
+ const len = Math.abs(pt.x - pt1.x);
209
+ if (len <= r) {
210
+ return {
211
+ x: pt1.x,
212
+ y: pt.y,
213
+ };
214
+ }
215
+ } else {
216
+ const A = (pt1.y - pt2.y) / (pt1.x - pt2.x);
217
+ const B = pt1.y - A * pt1.x;
218
+ const len = Math.abs((A * pt.x + B - pt.y) / Math.sqrt(A * A + 1));
219
+ if (len <= r) {
220
+ const m = pt.x + A * pt.y;
221
+ const x = (m - A * B) / (A * A + 1);
222
+ return {
223
+ x,
224
+ y: A * x + B,
225
+ };
226
+ }
227
+ }
228
+ }
229
+
230
+ function lineLen(from: Point, cp1?: Point, cp2?: Point, to?: Point): number {
231
+ if (!cp1 && !cp2) {
232
+ return (
233
+ Math.sqrt(
234
+ Math.pow(Math.abs(from.x - to.x), 2) +
235
+ Math.pow(Math.abs(from.y - to.y), 2)
236
+ ) || 0
237
+ );
238
+ }
239
+
240
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
241
+ if (cp1 && cp2) {
242
+ path.setAttribute(
243
+ 'd',
244
+ `M${from.x} ${from.y} C${cp1.x} ${cp1.y} ${cp2.x} ${cp2.y} ${to.x} ${to.y}`
245
+ );
246
+ } else if (cp1) {
247
+ path.setAttribute(
248
+ 'd',
249
+ `M${from.x} ${from.y} Q${cp1.x} ${cp1.y} ${to.x} ${to.y}`
250
+ );
251
+ } else {
252
+ path.setAttribute(
253
+ 'd',
254
+ `M${from.x} ${from.y} Q${cp2.x} ${cp2.y} ${to.x} ${to.y}`
255
+ );
256
+ }
257
+ return path.getTotalLength() || 0;
258
+ }
259
+
260
+ export function getLineLength(pen: Pen): number {
261
+ if (pen.calculative.worldAnchors.length < 2) {
262
+ return 0;
263
+ }
264
+
265
+ let len = 0;
266
+ let from: Point; // 上一个点
267
+ pen.calculative.worldAnchors.forEach((pt: Point) => {
268
+ if (from) {
269
+ from.lineLength = lineLen(from, from.next, pt.prev, pt);
270
+ len += from.lineLength;
271
+ }
272
+ from = pt;
273
+ });
274
+ if (pen.close) {
275
+ // pen.close ,下一个点即第一个点
276
+ const to = getFromAnchor(pen);
277
+ from.lineLength = lineLen(from, from.next, to.prev, to);
278
+ len += from.lineLength;
279
+ }
280
+ if (pen.calculative.animatePos) {
281
+ pen.calculative.animatePos =
282
+ (len / pen.length) * pen.calculative.animatePos;
283
+ }
284
+ pen.length = len;
285
+ return len;
286
+ }
287
+
288
+ /**
289
+ * 连线在 rect 内, 连线与 rect 相交
290
+ */
291
+ export function lineInRect(line: Pen, rect: Rect) {
292
+ // 判断是直线还是贝塞尔
293
+ const worldAnchors = line.calculative.worldAnchors;
294
+ for (let index = 0; index < worldAnchors.length - 1; index++) {
295
+ const current = worldAnchors[index];
296
+ const next = worldAnchors[index + 1];
297
+ if (!current.next && !next.prev) {
298
+ // 线段
299
+ if (isLineIntersectRectangle(current, next, rect)) {
300
+ return true;
301
+ }
302
+ } else {
303
+ // 贝塞尔
304
+ if (isBezierIntersectRectangle(current, next, rect)) {
305
+ return true;
306
+ }
307
+ }
308
+ }
309
+ return false;
310
+ }
311
+
312
+ /**
313
+ * 线段与矩形是否相交
314
+ * @param rect 矩形
315
+ */
316
+ export function isLineIntersectRectangle(pt1: Point, pt2: Point, rect: Rect) {
317
+ if (pointInSimpleRect(pt1, rect) || pointInSimpleRect(pt2, rect)) {
318
+ // 存在一个点在矩形内部
319
+ return true;
320
+ }
321
+ const linePointX1 = pt1.x;
322
+ const linePointY1 = pt1.y;
323
+ const linePointX2 = pt2.x;
324
+ const linePointY2 = pt2.y;
325
+
326
+ let rectangleLeftTopX = rect.x;
327
+ let rectangleLeftTopY = rect.y;
328
+ let rectangleRightBottomX = rect.ex;
329
+ let rectangleRightBottomY = rect.ey;
330
+
331
+ const lineHeight = linePointY1 - linePointY2;
332
+ const lineWidth = linePointX2 - linePointX1; // 计算叉乘
333
+ const c = linePointX1 * linePointY2 - linePointX2 * linePointY1;
334
+ if (
335
+ (lineHeight * rectangleLeftTopX + lineWidth * rectangleLeftTopY + c >= 0 &&
336
+ lineHeight * rectangleRightBottomX +
337
+ lineWidth * rectangleRightBottomY +
338
+ c <=
339
+ 0) ||
340
+ (lineHeight * rectangleLeftTopX + lineWidth * rectangleLeftTopY + c <= 0 &&
341
+ lineHeight * rectangleRightBottomX +
342
+ lineWidth * rectangleRightBottomY +
343
+ c >=
344
+ 0) ||
345
+ (lineHeight * rectangleLeftTopX + lineWidth * rectangleRightBottomY + c >=
346
+ 0 &&
347
+ lineHeight * rectangleRightBottomX + lineWidth * rectangleLeftTopY + c <=
348
+ 0) ||
349
+ (lineHeight * rectangleLeftTopX + lineWidth * rectangleRightBottomY + c <=
350
+ 0 &&
351
+ lineHeight * rectangleRightBottomX + lineWidth * rectangleLeftTopY + c >=
352
+ 0)
353
+ ) {
354
+ if (rectangleLeftTopX > rectangleRightBottomX) {
355
+ const temp = rectangleLeftTopX;
356
+ rectangleLeftTopX = rectangleRightBottomX;
357
+ rectangleRightBottomX = temp;
358
+ }
359
+ if (rectangleLeftTopY < rectangleRightBottomY) {
360
+ const temp1 = rectangleLeftTopY;
361
+ rectangleLeftTopY = rectangleRightBottomY;
362
+ rectangleRightBottomY = temp1;
363
+ }
364
+ if (
365
+ (linePointX1 < rectangleLeftTopX && linePointX2 < rectangleLeftTopX) ||
366
+ (linePointX1 > rectangleRightBottomX &&
367
+ linePointX2 > rectangleRightBottomX) ||
368
+ (linePointY1 > rectangleLeftTopY && linePointY2 > rectangleLeftTopY) ||
369
+ (linePointY1 < rectangleRightBottomY &&
370
+ linePointY2 < rectangleRightBottomY)
371
+ ) {
372
+ return false;
373
+ } else {
374
+ return true;
375
+ }
376
+ } else {
377
+ return false;
378
+ }
379
+ }
380
+
381
+ /**
382
+ * 贝塞尔曲线与矩形是否相交
383
+ * @param from 前点
384
+ * @param to 后点
385
+ * @param rect 矩形
386
+ */
387
+ export function isBezierIntersectRectangle(from: Point, to: Point, rect: Rect) {
388
+ const step = 0.02;
389
+ if (!from.next && !to.prev) {
390
+ // 直线
391
+ return isLineIntersectRectangle(from, to, rect);
392
+ } else if (from.next && to.prev) {
393
+ for (let i = step; i < 1; i += step) {
394
+ const point = getBezierPoint(i, from, from.next, to.prev, to);
395
+ if (pointInSimpleRect(point, rect)) {
396
+ return true;
397
+ }
398
+ }
399
+ } else if (from.next || to.prev) {
400
+ for (let i = step; i < 1; i += step) {
401
+ const point = getQuadraticPoint(i, from, from.next || to.prev, to);
402
+ if (pointInSimpleRect(point, rect)) {
403
+ return true;
404
+ }
405
+ }
406
+ }
407
+
408
+ return false;
409
+ }