@jnrs/lingshu-smart 2.2.6 → 2.2.8

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 (174) hide show
  1. package/dist/App.vue.d.ts +2 -1
  2. package/dist/App.vue.js +30 -0
  3. package/dist/assets/data/editor_default.d.ts +8 -1
  4. package/dist/assets/data/editor_default.js +59 -0
  5. package/dist/assets/data/editor_default_setting.d.ts +16 -0
  6. package/dist/assets/data/editor_default_setting.js +58 -0
  7. package/dist/assets/data/editor_preset.d.ts +8 -1
  8. package/dist/assets/data/editor_preset.js +51 -0
  9. package/dist/assets/data/editor_preset_menu.d.ts +9 -0
  10. package/dist/assets/data/editor_preset_menu.js +290 -0
  11. package/dist/components/editor/ControlBar/CaseManger.vue.d.ts +3 -15
  12. package/dist/components/editor/ControlBar/CaseManger.vue.js +465 -0
  13. package/dist/components/editor/ControlBar/CaseTitleEdit.vue.d.ts +2 -411
  14. package/dist/components/editor/ControlBar/CaseTitleEdit.vue.js +108 -0
  15. package/dist/components/editor/ControlBar/ExportImportDialog.vue.d.ts +3 -2
  16. package/dist/components/editor/ControlBar/ExportImportDialog.vue.js +280 -0
  17. package/dist/components/editor/ControlBar/MainButton.vue.d.ts +3 -2
  18. package/dist/components/editor/ControlBar/MainButton.vue.js +183 -0
  19. package/dist/components/editor/ControlBar/StepButton.vue.d.ts +2 -1
  20. package/dist/components/editor/ControlBar/StepButton.vue.js +147 -0
  21. package/dist/components/editor/ControlBar/StepRecordVisualizer.vue.d.ts +2 -1
  22. package/dist/components/editor/ControlBar/StepRecordVisualizer.vue.js +98 -0
  23. package/dist/components/editor/DrawingBoard.vue.d.ts +2 -1
  24. package/dist/components/editor/DrawingBoard.vue.js +31 -0
  25. package/dist/components/editor/MenuCard/Equipments.vue.d.ts +2 -1
  26. package/dist/components/editor/MenuCard/Equipments.vue.js +129 -0
  27. package/dist/components/editor/MenuCard/Layers.vue.d.ts +2 -1
  28. package/dist/components/editor/MenuCard/Layers.vue.js +201 -0
  29. package/dist/components/editor/MenuCard/index.vue.d.ts +2 -1
  30. package/dist/components/editor/MenuCard/index.vue.js +84 -0
  31. package/dist/components/editor/OptionCard/Equipment/Base.vue.d.ts +2 -1
  32. package/dist/components/editor/OptionCard/Equipment/Base.vue.js +96 -0
  33. package/dist/components/editor/OptionCard/Equipment/Binds.vue.d.ts +3 -0
  34. package/dist/components/editor/OptionCard/Equipment/Binds.vue.js +443 -0
  35. package/dist/components/editor/OptionCard/Equipment/Bot.vue.d.ts +3 -0
  36. package/dist/components/editor/OptionCard/Equipment/Bot.vue.js +81 -0
  37. package/dist/components/editor/OptionCard/Equipment/DataSets.vue.d.ts +2 -1
  38. package/dist/components/editor/OptionCard/Equipment/DataSets.vue.js +304 -0
  39. package/dist/components/editor/OptionCard/Equipment/DockStore.vue.d.ts +3 -0
  40. package/dist/components/editor/OptionCard/Equipment/DockStore.vue.js +597 -0
  41. package/dist/components/editor/OptionCard/Equipment/Interaction.vue.d.ts +2 -1
  42. package/dist/components/editor/OptionCard/Equipment/Interaction.vue.js +287 -0
  43. package/dist/components/editor/OptionCard/Equipment/Position.backup.vue.d.ts +3 -0
  44. package/dist/components/editor/OptionCard/Equipment/Position.backup.vue.js +440 -0
  45. package/dist/components/editor/OptionCard/Equipment/Position.vue.d.ts +2 -1
  46. package/dist/components/editor/OptionCard/Equipment/Position.vue.js +436 -0
  47. package/dist/components/editor/OptionCard/Equipment/StationSlotGroup.vue.d.ts +2 -1
  48. package/dist/components/editor/OptionCard/Equipment/StationSlotGroup.vue.js +1131 -0
  49. package/dist/components/editor/OptionCard/Equipment/Store.vue.d.ts +3 -0
  50. package/dist/components/editor/OptionCard/Equipment/Store.vue.js +453 -0
  51. package/dist/components/editor/OptionCard/Equipment/Trailer.vue.d.ts +3 -0
  52. package/dist/components/editor/OptionCard/Equipment/Trailer.vue.js +1109 -0
  53. package/dist/components/editor/OptionCard/Equipment/index.vue.d.ts +2 -1
  54. package/dist/components/editor/OptionCard/Equipment/index.vue.js +100 -0
  55. package/dist/components/editor/OptionCard/Equipment/models/MachineTool.vue.d.ts +3 -0
  56. package/dist/components/editor/OptionCard/Equipment/models/MachineTool.vue.js +99 -0
  57. package/dist/components/editor/OptionCard/Equipment/models/Rail.vue.d.ts +3 -0
  58. package/dist/components/editor/OptionCard/Equipment/models/Rail.vue.js +225 -0
  59. package/dist/components/editor/OptionCard/Equipment/models/SingleGripperRobot.vue.d.ts +3 -0
  60. package/dist/components/editor/OptionCard/Equipment/models/SingleGripperRobot.vue.js +99 -0
  61. package/dist/components/editor/OptionCard/Scene/Background.vue.d.ts +2 -1
  62. package/dist/components/editor/OptionCard/Scene/Background.vue.js +543 -0
  63. package/dist/components/editor/OptionCard/Scene/index.vue.d.ts +2 -1
  64. package/dist/components/editor/OptionCard/Scene/index.vue.js +200 -0
  65. package/dist/components/editor/OptionCard/index.vue.d.ts +2 -1
  66. package/dist/components/editor/OptionCard/index.vue.js +73 -0
  67. package/dist/components/editor/index.vue.d.ts +4 -13
  68. package/dist/components/editor/index.vue.js +156 -0
  69. package/dist/components/index.d.ts +2 -2
  70. package/dist/components/index.js +4 -25440
  71. package/dist/components/preview/index.vue.d.ts +6 -5
  72. package/dist/components/preview/index.vue.js +104 -0
  73. package/dist/composables/useStepRecord.d.ts +12 -4
  74. package/dist/composables/useStepRecord.js +135 -0
  75. package/dist/constants/options.d.ts +8 -1
  76. package/dist/constants/options.js +55 -0
  77. package/dist/controller/AppController.d.ts +10 -3
  78. package/dist/controller/AppController.js +168 -0
  79. package/dist/controller/EditorController.d.ts +9 -2
  80. package/dist/controller/EditorController.js +173 -0
  81. package/dist/index.js +1 -1
  82. package/dist/locales/en.js +5 -0
  83. package/dist/locales/i18next.d.ts +1 -1
  84. package/dist/locales/i18next.js +6 -0
  85. package/dist/locales/index.d.ts +2 -2
  86. package/dist/locales/index.js +3 -13
  87. package/dist/locales/zhCn.js +5 -0
  88. package/dist/main.d.ts +3 -0
  89. package/dist/main.js +13 -0
  90. package/dist/playground/EditPageDemo.vue.d.ts +2 -1
  91. package/dist/playground/EditPageDemo.vue.js +57 -0
  92. package/dist/playground/ViewPageDemo.vue.d.ts +2 -27
  93. package/dist/playground/ViewPageDemo.vue.js +277 -0
  94. package/dist/stores/index.js +3 -0
  95. package/dist/stores/useAppStore.d.ts +13 -6
  96. package/dist/stores/useAppStore.js +78 -0
  97. package/dist/stores/useDataStore.d.ts +18 -11
  98. package/dist/stores/useDataStore.js +116 -0
  99. package/dist/stores/useEditorStore.d.ts +27 -20
  100. package/dist/stores/useEditorStore.js +263 -0
  101. package/dist/types/app.types.d.ts +1 -1
  102. package/dist/types/app.types.js +2 -0
  103. package/dist/types/base.types.d.ts +4 -2
  104. package/dist/types/base.types.js +1 -0
  105. package/dist/types/components/config.types.d.ts +11 -3
  106. package/dist/types/components/config.types.js +1 -0
  107. package/dist/types/components/operating.types.d.ts +1 -1
  108. package/dist/types/components/operating.types.js +1 -0
  109. package/dist/types/enums.d.ts +5 -2
  110. package/dist/types/enums.js +46 -0
  111. package/dist/types/guards.d.ts +12 -2
  112. package/dist/types/guards.js +28 -0
  113. package/dist/types/index.d.ts +2 -2
  114. package/dist/types/index.js +8 -0
  115. package/dist/types/models/config.types.d.ts +74 -29
  116. package/dist/types/models/config.types.js +1 -0
  117. package/dist/types/models/operating.types.d.ts +83 -17
  118. package/dist/types/models/operating.types.js +1 -0
  119. package/dist/ui/abstract/ComponentAbs.d.ts +9 -2
  120. package/dist/ui/abstract/ComponentAbs.js +64 -0
  121. package/dist/ui/abstract/ModelAbs.d.ts +12 -2
  122. package/dist/ui/abstract/ModelAbs.js +119 -0
  123. package/dist/ui/components/Entrance.d.ts +8 -1
  124. package/dist/ui/components/Entrance.js +83 -0
  125. package/dist/ui/components/Light.d.ts +26 -3
  126. package/dist/ui/components/Light.js +167 -0
  127. package/dist/ui/components/Progress.d.ts +8 -1
  128. package/dist/ui/components/Progress.js +84 -0
  129. package/dist/ui/components/Resource.d.ts +8 -1
  130. package/dist/ui/components/Resource.js +70 -0
  131. package/dist/ui/components/StationSlot.d.ts +24 -2
  132. package/dist/ui/components/StationSlot.js +207 -0
  133. package/dist/ui/components/StationSlotGroup.d.ts +8 -1
  134. package/dist/ui/components/StationSlotGroup.js +110 -0
  135. package/dist/ui/factories/createGlass.d.ts +9 -1
  136. package/dist/ui/factories/createGlass.js +51 -0
  137. package/dist/ui/factories/createModel.d.ts +9 -2
  138. package/dist/ui/factories/createModel.js +35 -0
  139. package/dist/ui/factories/createShadow.d.ts +12 -4
  140. package/dist/ui/factories/createShadow.js +52 -0
  141. package/dist/ui/factories/createText.d.ts +7 -0
  142. package/dist/ui/factories/createText.js +46 -0
  143. package/dist/ui/models/CleaningMachine.d.ts +14 -0
  144. package/dist/ui/models/CleaningMachine.js +141 -0
  145. package/dist/ui/models/DoubleJointRobot.d.ts +23 -0
  146. package/dist/ui/models/DoubleJointRobot.js +545 -0
  147. package/dist/ui/models/LoadingStation.d.ts +16 -0
  148. package/dist/ui/models/LoadingStation.js +167 -0
  149. package/dist/ui/models/MachineTool.d.ts +5 -4
  150. package/dist/ui/models/MachineTool.js +184 -0
  151. package/dist/ui/models/MarkingMachine.d.ts +16 -0
  152. package/dist/ui/models/MarkingMachine.js +148 -0
  153. package/dist/ui/models/Rail.d.ts +15 -0
  154. package/dist/ui/models/Rail.js +117 -0
  155. package/dist/ui/models/ResourceStore.d.ts +12 -0
  156. package/dist/ui/models/ResourceStore.js +101 -0
  157. package/dist/ui/models/SingleBot.d.ts +20 -0
  158. package/dist/ui/models/SingleBot.js +202 -0
  159. package/dist/ui/models/SingleGripperRobot.d.ts +19 -0
  160. package/dist/ui/models/SingleGripperRobot.js +272 -0
  161. package/dist/ui/models/SingleJointRobot.d.ts +22 -0
  162. package/dist/ui/models/SingleJointRobot.js +346 -0
  163. package/dist/ui/shapes/NamePlate.d.ts +10 -1
  164. package/dist/ui/shapes/NamePlate.js +85 -0
  165. package/dist/ui/shapes/ScrewHole.d.ts +8 -1
  166. package/dist/ui/shapes/ScrewHole.js +57 -0
  167. package/dist/ui/shapes/Texture.d.ts +12 -3
  168. package/dist/ui/shapes/Texture.js +51 -0
  169. package/dist/ui/utils/attr.d.ts +10 -3
  170. package/dist/ui/utils/attr.js +50 -0
  171. package/dist/utils/index.js +92 -0
  172. package/dist/utils/type-guards.d.ts +1 -1
  173. package/dist/utils/type-guards.js +105 -0
  174. package/package.json +2 -2
@@ -0,0 +1,346 @@
1
+ import { EnumResourceType } from '@/types';
2
+ import { Box, Group } from 'leafer';
3
+ import { ModelAbs } from '../abstract/ModelAbs';
4
+ import { StationSlot } from '../components/StationSlot';
5
+ import { setCursor } from '../utils/attr';
6
+ import { createShadow } from '../factories/createShadow';
7
+ import { ScrewHole } from '../shapes/ScrewHole';
8
+ import { RectLight } from '../components/Light';
9
+ /**
10
+ * 单关节机器人(SingleGripperRobot)
11
+ * 基于 ModelAbs 重构,保留 Bot.js 核心运行行为:状态灯、沿 X 移动、手臂旋转、夹具切换。
12
+ */
13
+ export class SingleJointRobot extends ModelAbs {
14
+ static DEFAULT_WIDTH = 90;
15
+ static DEFAULT_HEIGHT = 76;
16
+ static DEFAULT_LIGHT_COLOR = '#DFC285';
17
+ light1 = null;
18
+ light2 = null;
19
+ defaultLightColor = SingleJointRobot.DEFAULT_LIGHT_COLOR;
20
+ palletStationSlot = null;
21
+ cutterStationSlot = null;
22
+ createUi() {
23
+ const { uuid, className, width = SingleJointRobot.DEFAULT_WIDTH, height = SingleJointRobot.DEFAULT_HEIGHT, x, y, zIndex, rotation, scale, visible, editable, draggable, currentFixture } = this.config;
24
+ // 创建托盘工位槽
25
+ this.palletStationSlot = new StationSlot({
26
+ index: 10,
27
+ x: 40,
28
+ y: 25,
29
+ width: 46,
30
+ height: 46,
31
+ hittable: this.config.hittable,
32
+ showContainer: false,
33
+ resourceType: EnumResourceType.PALLET,
34
+ visible: currentFixture === EnumResourceType.PALLET ? true : 0
35
+ }).init();
36
+ // 创建刀具工位槽
37
+ this.cutterStationSlot = new StationSlot({
38
+ index: 10,
39
+ x: 44,
40
+ y: 25,
41
+ width: 46,
42
+ height: 46,
43
+ hittable: this.config.hittable,
44
+ showContainer: false,
45
+ resourceType: EnumResourceType.TOOL,
46
+ visible: currentFixture === EnumResourceType.TOOL ? true : 0
47
+ }).init();
48
+ // 小摆臂
49
+ const smallArm = new Group({
50
+ hitSelf: false,
51
+ className: 'smallArm',
52
+ x: 35,
53
+ y: 30,
54
+ zIndex: 1,
55
+ around: {
56
+ type: 'percent',
57
+ x: 0.1,
58
+ y: 0.5
59
+ },
60
+ children: [
61
+ {
62
+ hittable: false,
63
+ tag: 'Box',
64
+ width: 36,
65
+ height: 16,
66
+ stroke: 'rgba(0,0,0,0.1)',
67
+ strokeWidth: 0.5,
68
+ fill: {
69
+ type: 'linear',
70
+ stops: ['#FF6600', '#FFbb00', '#FF6600']
71
+ },
72
+ cornerRadius: [16, 0, 0, 16]
73
+ },
74
+ {
75
+ hittable: false,
76
+ className: 'smallArmJoint1',
77
+ tag: 'Rect',
78
+ width: 16,
79
+ height: 16,
80
+ fill: '#424242',
81
+ cornerRadius: 16
82
+ },
83
+ {
84
+ hittable: false,
85
+ className: 'smallArmJoint2',
86
+ tag: 'Rect',
87
+ x: 36,
88
+ width: 5,
89
+ height: 16,
90
+ fill: '#424242',
91
+ cornerRadius: [0, 16, 16, 0]
92
+ },
93
+ // 夹具容器
94
+ {
95
+ hitSelf: false,
96
+ className: 'fork',
97
+ tag: 'Box',
98
+ x: 30,
99
+ y: -17,
100
+ zIndex: -1,
101
+ children: [
102
+ {
103
+ hitSelf: false,
104
+ id: 'fixture',
105
+ tag: 'Box',
106
+ state: currentFixture,
107
+ states: {
108
+ // 托盘夹具
109
+ [EnumResourceType.PALLET]: {
110
+ hitSelf: false,
111
+ width: 66,
112
+ height: 50,
113
+ cornerRadius: [15, 0, 0, 15],
114
+ strokeWidth: 4,
115
+ stroke: {
116
+ type: 'linear',
117
+ from: 'left',
118
+ to: 'right',
119
+ stops: [
120
+ { offset: 0, color: '#424242' },
121
+ { offset: 0.9, color: '#000' },
122
+ { offset: 0.9, color: 'rgba(255, 0, 0, 0)' },
123
+ { offset: 1, color: 'rgba(255, 0, 0, 0)' }
124
+ ]
125
+ },
126
+ animation: {
127
+ keyframes: [
128
+ { opacity: 0, scaleX: 0 },
129
+ { opacity: 1, scaleX: 1 }
130
+ ],
131
+ duration: 0.3
132
+ }
133
+ },
134
+ // 刀具夹具
135
+ [EnumResourceType.TOOL]: {
136
+ tag: 'Box',
137
+ width: 30,
138
+ height: 12,
139
+ y: 19,
140
+ fill: {
141
+ type: 'linear',
142
+ from: 'left',
143
+ to: 'right',
144
+ stops: [
145
+ { offset: 0, color: '#424242' },
146
+ { offset: 0.75, color: '#666' },
147
+ { offset: 0.75, color: '#424242' },
148
+ { offset: 1, color: '#424242' }
149
+ ]
150
+ },
151
+ children: [
152
+ {
153
+ className: 'cutterTip1',
154
+ tag: 'Box',
155
+ width: 6,
156
+ height: 2,
157
+ x: 24,
158
+ y: 2,
159
+ fill: '#000'
160
+ },
161
+ {
162
+ className: 'cutterTip2',
163
+ tag: 'Box',
164
+ width: 6,
165
+ height: 2,
166
+ x: 24,
167
+ y: 8,
168
+ fill: '#000'
169
+ }
170
+ ]
171
+ }
172
+ }
173
+ },
174
+ this.palletStationSlot.ui,
175
+ this.cutterStationSlot.ui
176
+ ]
177
+ }
178
+ ]
179
+ });
180
+ // 大摆臂
181
+ const bigArm = new Box({
182
+ hittable: false,
183
+ className: 'bigArm',
184
+ width: 50,
185
+ height: 30,
186
+ x: 35,
187
+ y: 30,
188
+ cornerRadius: [15, 3, 3, 15],
189
+ around: 'center',
190
+ fill: {
191
+ type: 'radial',
192
+ stops: [
193
+ { offset: 0, color: '#FFcc00' },
194
+ { offset: 1, color: '#FF6600' }
195
+ ]
196
+ },
197
+ shadow: {
198
+ color: 'rgba(0,0,0,0.5)',
199
+ spread: 0,
200
+ blur: 2
201
+ }
202
+ });
203
+ // 二级基座
204
+ const secondBase = new Box({
205
+ hitSelf: false,
206
+ className: 'secondBase',
207
+ width: 70,
208
+ height: 60,
209
+ x: 45,
210
+ y: 38,
211
+ cornerRadius: 10,
212
+ around: 'center',
213
+ fill: {
214
+ type: 'radial',
215
+ stops: [
216
+ { offset: 0.3, color: '#FFcc00' },
217
+ { offset: 1, color: '#FF6600' }
218
+ ]
219
+ },
220
+ shadow: {
221
+ color: 'rgba(0,0,0,0.5)',
222
+ spread: 0,
223
+ blur: 2
224
+ },
225
+ children: [
226
+ ScrewHole({ x: 10, y: 10, styleType: 'dark' }),
227
+ ScrewHole({ x: 62, y: 10, styleType: 'dark' }),
228
+ ScrewHole({ x: 62, y: 50, styleType: 'dark' }),
229
+ ScrewHole({ x: 10, y: 50, styleType: 'dark' }),
230
+ {
231
+ hitSelf: false,
232
+ rotation: -rotation,
233
+ tag: 'Box',
234
+ width: 50,
235
+ height: 50,
236
+ around: 'center',
237
+ x: width / 2 - 10,
238
+ y: height / 2 - 8,
239
+ fill: '#ee6600',
240
+ cornerRadius: 50,
241
+ strokeWidth: 1,
242
+ stroke: 'rgba(255,255,255,0.65)',
243
+ children: [
244
+ createShadow({
245
+ width: 50,
246
+ height: 50,
247
+ cornerRadius: 50,
248
+ shadow: null,
249
+ innerShadow: [
250
+ {
251
+ x: 4,
252
+ y: 2,
253
+ blur: 4,
254
+ color: 'rgba(0,0,0,0.5)'
255
+ },
256
+ {
257
+ x: -3,
258
+ y: -1,
259
+ blur: 3,
260
+ color: 'rgba(255, 255, 255, 0.4)'
261
+ }
262
+ ]
263
+ })
264
+ ]
265
+ }
266
+ ]
267
+ });
268
+ secondBase.add([bigArm, smallArm]);
269
+ // 主体
270
+ const main = new Box({
271
+ data: this.config,
272
+ id: uuid,
273
+ className,
274
+ x,
275
+ y,
276
+ width,
277
+ height,
278
+ around: 'center',
279
+ fill: '#FF9933',
280
+ cornerRadius: 10,
281
+ zIndex,
282
+ rotation,
283
+ scale,
284
+ visible,
285
+ editable,
286
+ draggable,
287
+ shadow: {
288
+ spread: 1,
289
+ blur: 4,
290
+ color: 'rgba(0,0,0,0.5)'
291
+ }
292
+ });
293
+ // 设备状态灯
294
+ this.light1 = new RectLight({
295
+ width: 30,
296
+ height: 4,
297
+ x: this.width_05,
298
+ y: 4,
299
+ color: this.defaultLightColor
300
+ }).init();
301
+ this.light2 = new RectLight({
302
+ width: 30,
303
+ height: 4,
304
+ x: this.width_05,
305
+ y: height - 4,
306
+ color: this.defaultLightColor
307
+ }).init();
308
+ main.add([this.light1.ui, this.light2.ui, secondBase]);
309
+ setCursor(main, this.config);
310
+ return main;
311
+ }
312
+ operating(data) {
313
+ if (data.light && this.light1 && this.light2) {
314
+ this.light1.operating(data.light);
315
+ this.light2.operating(data.light);
316
+ }
317
+ if (typeof data.x === 'number')
318
+ this.moveX(data.x);
319
+ if (typeof data.r === 'number')
320
+ this.handleRotate(data.r);
321
+ if (data.currentFixture)
322
+ this.switchFork(data.currentFixture);
323
+ }
324
+ handleRotate(r) {
325
+ if (!Number.isFinite(r))
326
+ return;
327
+ this.ui.findOne('.bigArm')?.animate({ rotation: -r, duration: 0.5 });
328
+ this.ui.findOne('.smallArm')?.animate({ rotation: r, duration: 0.5 });
329
+ this.ui.findOne('.secondBase')?.animate({ offsetX: Math.abs(r / 9) - 10, duration: 0.5 });
330
+ }
331
+ moveX(x) {
332
+ if (!Number.isFinite(x))
333
+ return;
334
+ this.ui.animate({ x, duration: 0.25 });
335
+ }
336
+ // 切换夹具类型
337
+ switchFork(type) {
338
+ if (this.palletStationSlot) {
339
+ this.palletStationSlot.toggleVisible(type === EnumResourceType.PALLET ? true : 0);
340
+ }
341
+ if (this.cutterStationSlot) {
342
+ this.cutterStationSlot.toggleVisible(type === EnumResourceType.TOOL ? true : 0);
343
+ }
344
+ this.ui.findOne('#fixture')?.set({ state: type });
345
+ }
346
+ }
@@ -1,3 +1,10 @@
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : NamePlate.ts
5
+ * @Date : 2026/02/12
6
+ * @Desc. : 铭牌
7
+ */
1
8
  import { Box } from 'leafer';
2
9
  export interface NamePlateOptions {
3
10
  title: string;
@@ -9,7 +16,9 @@ export interface NamePlateOptions {
9
16
  fill?: string;
10
17
  textColor?: string;
11
18
  fontSize?: number;
19
+ stroke?: string;
20
+ strokeWidth?: number;
12
21
  screwHole?: boolean;
13
22
  zIndex?: number | string;
14
23
  }
15
- export declare function NamePlateUi(options: NamePlateOptions): Box;
24
+ export declare function NamePlate(options: NamePlateOptions): Box;
@@ -0,0 +1,85 @@
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : NamePlate.ts
5
+ * @Date : 2026/02/12
6
+ * @Desc. : 铭牌
7
+ */
8
+ import { Box, Text } from 'leafer';
9
+ import { ScrewHole } from './ScrewHole';
10
+ export function NamePlate(options) {
11
+ const opts = {
12
+ x: 0,
13
+ y: 0,
14
+ width: undefined, // 显式区分是否传入
15
+ height: 18,
16
+ cornerRadius: 2,
17
+ fill: '#f2f2f2',
18
+ textColor: '#d15f2c',
19
+ fontSize: 14,
20
+ stroke: 'rgba(0,0,0,0.2)',
21
+ strokeWidth: 1,
22
+ screwHole: true,
23
+ zIndex: '',
24
+ ...options
25
+ };
26
+ // 默认宽度:按字符估算
27
+ const defaultWidth = Math.max(20, (opts.title.length + 2) * opts.fontSize);
28
+ const finalWidth = opts.width ?? defaultWidth;
29
+ // 文本节点配置
30
+ const textConfig = {
31
+ text: opts.title,
32
+ textAlign: 'center',
33
+ verticalAlign: 'middle',
34
+ fill: opts.textColor,
35
+ fontWeight: 'black',
36
+ width: finalWidth,
37
+ height: opts.height,
38
+ lineHeight: opts.height, // 行距为 0
39
+ wordWrap: !!opts.width, // 仅当指定了 width 时才允许换行
40
+ overflow: 'hide'
41
+ };
42
+ // 如果指定了 width,则使用较小字号尝试适配
43
+ if (opts.width !== undefined) {
44
+ textConfig.fontSize = Math.min(opts.fontSize, 12);
45
+ }
46
+ else {
47
+ textConfig.fontSize = opts.fontSize;
48
+ }
49
+ const textNode = new Text(textConfig);
50
+ const box = new Box({
51
+ hittable: false,
52
+ className: 'name-plate',
53
+ x: opts.x,
54
+ y: opts.y,
55
+ width: finalWidth,
56
+ height: opts.height,
57
+ fill: opts.fill,
58
+ overflow: 'hide',
59
+ around: 'center',
60
+ stroke: opts.stroke,
61
+ strokeWidth: opts.strokeWidth,
62
+ cornerRadius: opts.cornerRadius,
63
+ zIndex: opts.zIndex,
64
+ children: [textNode]
65
+ });
66
+ // 添加螺丝孔
67
+ if (opts.screwHole) {
68
+ const height_05 = opts.height / 2;
69
+ const holeSize = 4;
70
+ const leftScrew = ScrewHole({
71
+ x: holeSize,
72
+ y: height_05,
73
+ width: holeSize,
74
+ height: holeSize
75
+ });
76
+ const rightScrew = ScrewHole({
77
+ x: finalWidth - holeSize,
78
+ y: height_05,
79
+ width: holeSize,
80
+ height: holeSize
81
+ });
82
+ box.add([leftScrew, rightScrew]);
83
+ }
84
+ return box;
85
+ }
@@ -1,3 +1,10 @@
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : ScrewHole.ts
5
+ * @Date : 2026/02/12
6
+ * @Desc. : 梅花螺丝孔
7
+ */
1
8
  import { Box } from 'leafer';
2
9
  export type ScrewHoleStyle = 'light' | 'dark';
3
10
  export interface ScrewHoleOptions {
@@ -8,4 +15,4 @@ export interface ScrewHoleOptions {
8
15
  fill?: string;
9
16
  styleType?: ScrewHoleStyle;
10
17
  }
11
- export declare function ScrewHoleUi(options?: ScrewHoleOptions): Box;
18
+ export declare function ScrewHole(options?: ScrewHoleOptions): Box;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : ScrewHole.ts
5
+ * @Date : 2026/02/12
6
+ * @Desc. : 梅花螺丝孔
7
+ */
8
+ import { Box, Star } from 'leafer';
9
+ export function ScrewHole(options = {}) {
10
+ const opts = {
11
+ x: 0,
12
+ y: 0,
13
+ width: 5,
14
+ height: 5,
15
+ fill: '',
16
+ styleType: 'light',
17
+ ...options
18
+ };
19
+ // 根据 styleType 自动设置 fill
20
+ if (options.fill === undefined) {
21
+ opts.fill = opts.styleType === 'dark' ? '#777' : '#ccc';
22
+ }
23
+ const strokeWidth = 0.15;
24
+ const strokeColor = opts.styleType === 'dark' ? '#333' : '#888';
25
+ const screwHole = new Box({
26
+ hittable: false,
27
+ className: 'screw-hole',
28
+ x: opts.x,
29
+ y: opts.y,
30
+ width: opts.width,
31
+ height: opts.height,
32
+ fill: opts.fill,
33
+ cornerRadius: opts.width / 2,
34
+ stroke: strokeColor,
35
+ strokeWidth: strokeWidth,
36
+ around: 'center'
37
+ });
38
+ // 如果需要中心标记
39
+ const markSize = Math.min(opts.width, opts.height);
40
+ const width_05 = opts.width / 2;
41
+ const height_05 = opts.height / 2;
42
+ // 梅花图案
43
+ const torx = new Star({
44
+ x: width_05,
45
+ y: height_05,
46
+ width: markSize,
47
+ height: markSize,
48
+ innerRadius: 0.25,
49
+ corners: 5,
50
+ cornerRadius: 2,
51
+ rotation: 30,
52
+ fill: strokeColor,
53
+ around: 'center'
54
+ });
55
+ screwHole.add(torx);
56
+ return screwHole;
57
+ }
@@ -1,12 +1,21 @@
1
- import { Box } from 'leafer';
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : Texture.ts
5
+ * @Date : 2025/05/30
6
+ * @Desc. : 纹理
7
+ */
8
+ import { Box, type IFill } from 'leafer';
2
9
  export type TextureEffect = 'LightGrid' | 'DarkGrid' | 'MatrixGrid' | 'LightDot' | 'DarkDot' | 'WoodFloor' | 'VerticalBar';
3
10
  export interface ITextureOptions {
11
+ className?: string;
4
12
  width?: number;
5
13
  height?: number;
6
14
  effect?: TextureEffect;
7
15
  opacity?: number;
8
16
  scale?: number;
9
17
  rotation?: number;
10
- cornerRadius?: number;
18
+ cornerRadius?: number | number[];
19
+ fill?: IFill;
11
20
  }
12
- export declare function TextureUi(options?: ITextureOptions): Box;
21
+ export declare function Texture(options?: ITextureOptions): Box;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : Texture.ts
5
+ * @Date : 2025/05/30
6
+ * @Desc. : 纹理
7
+ */
8
+ import { Box, Rect } from 'leafer';
9
+ import LightGrid from '@/assets/images/texture/LightGrid.png';
10
+ import DarkGrid from '@/assets/images/texture/DarkGrid.png';
11
+ import MatrixGrid from '@/assets/images/texture/MatrixGrid.png';
12
+ import LightDot from '@/assets/images/texture/LightDot.png';
13
+ import DarkDot from '@/assets/images/texture/DarkDot.png';
14
+ import WoodFloor from '@/assets/images/texture/WoodFloor.png';
15
+ import VerticalBar from '@/assets/images/texture/VerticalBar.png';
16
+ const EFFECT_MAP = {
17
+ LightGrid,
18
+ DarkGrid,
19
+ MatrixGrid,
20
+ LightDot,
21
+ DarkDot,
22
+ WoodFloor,
23
+ VerticalBar
24
+ };
25
+ export function Texture(options = {}) {
26
+ const { className = 'Texture', width = 0, height = 0, effect = 'LightGrid', opacity = 1, scale = 0.02, rotation = 0, cornerRadius = 0, fill } = options;
27
+ return new Box({
28
+ hittable: false,
29
+ className,
30
+ width,
31
+ height,
32
+ fill,
33
+ cornerRadius,
34
+ overflow: 'hide',
35
+ children: [
36
+ new Rect({
37
+ className: 'Texture-Image',
38
+ width,
39
+ height,
40
+ opacity,
41
+ fill: {
42
+ type: 'image',
43
+ url: EFFECT_MAP[effect],
44
+ mode: 'repeat',
45
+ scale,
46
+ rotation
47
+ }
48
+ })
49
+ ]
50
+ });
51
+ }
@@ -1,9 +1,16 @@
1
- import { UI } from 'leafer';
2
- import { IInteractiveState, IEventState } from '../../types';
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : attr.ts
5
+ * @Date : 2026/04/07
6
+ * @Desc. : 修改属性的工具函数
7
+ */
8
+ import { type UI } from 'leafer';
9
+ import type { IInteractiveState, IEventState } from '@/types';
3
10
  /**
4
11
  * 根据交互属性设置鼠标样式和 hover 效果
5
12
  * @param target UI 目标对象
6
13
  * @param data 交互属性数据
7
- * @param type 效果类型,默认为 'shadow',可选 'border'
14
+ * @param type 效果类型,默认为 'shadow',可选 'border'('border' 特别适用于 overflow: 'hidden' 的容器)
8
15
  */
9
16
  export declare function setCursor(target: UI, data: IInteractiveState & IEventState, type?: 'shadow' | 'border'): void;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @Author : TanRui
3
+ * @WeChat : Tan578853789
4
+ * @File : attr.ts
5
+ * @Date : 2026/04/07
6
+ * @Desc. : 修改属性的工具函数
7
+ */
8
+ import {} from 'leafer';
9
+ /**
10
+ * 根据交互属性设置鼠标样式和 hover 效果
11
+ * @param target UI 目标对象
12
+ * @param data 交互属性数据
13
+ * @param type 效果类型,默认为 'shadow',可选 'border'('border' 特别适用于 overflow: 'hidden' 的容器)
14
+ */
15
+ export function setCursor(target, data, type = 'shadow') {
16
+ if (data.hittable && data.hitSelf && (data.clickable || data.menuClickable || data.draggable)) {
17
+ let cursor = 'default';
18
+ const color = '#806EF7';
19
+ if (data.clickable) {
20
+ cursor = 'pointer';
21
+ }
22
+ else if (data.menuClickable) {
23
+ cursor = 'context-menu';
24
+ }
25
+ else if (data.draggable) {
26
+ cursor = 'move';
27
+ }
28
+ if (type === 'shadow') {
29
+ target.set({
30
+ cursor,
31
+ hoverStyle: {
32
+ shadow: {
33
+ spread: 2,
34
+ blur: 2,
35
+ color
36
+ }
37
+ }
38
+ });
39
+ }
40
+ else if (type === 'border') {
41
+ target.set({
42
+ cursor,
43
+ hoverStyle: {
44
+ stroke: color,
45
+ strokeWidth: 3
46
+ }
47
+ });
48
+ }
49
+ }
50
+ }