@meta2d/core 1.1.21 → 1.1.23

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.
package/src/core.js CHANGED
@@ -2,7 +2,7 @@ import { clearIframes, commonAnchors, commonPens, cube, updateIframes, reset, up
2
2
  import { Canvas } from './canvas';
3
3
  import { calcInView, calcTextDrawRect, calcTextLines, calcTextRect, facePen, formatAttrs, getAllChildren, getFromAnchor, getParent, getToAnchor, getWords, LockState, PenType, renderPenRaw, setElemPosition, connectLine, nearestAnchor, setChildValue, isAncestor, isShowChild, CanvasLayer, validationPlugin, setLifeCycleFunc, getAllFollowers, isInteraction, calcWorldAnchors, isDomShapes, defaultFormat, findOutliersByZScore, } from './pen';
4
4
  import { rotatePoint } from './point';
5
- import { clearStore, EditType, globalStore, register, registerAnchors, registerCanvasDraw, useStore, } from './store';
5
+ import { clearStore, EditType, globalStore, register, registerAnchors, registerCanvasDraw, registerGridDrawer, unregisterGridDrawer, useStore, } from './store';
6
6
  import { formatPadding, loadCss, s8, valueInArray, valueInRange, } from './utils';
7
7
  import { calcCenter, calcRelativeRect, calcRightBottom, getRect, rectInRect, } from './rect';
8
8
  import { deepClone } from './utils/clone';
@@ -32,6 +32,12 @@ export class Meta2d {
32
32
  events = {};
33
33
  map;
34
34
  mapTimer;
35
+ /**
36
+ * fillView 首次填充前各 fit 顶层图元的原始几何快照(设计坐标系,与 scale/origin 无关)。
37
+ * 用于保证多次调用 fillView 的幂等性:每次填充前先还原到原始几何,再执行拉伸,
38
+ * 避免在已拉伸的结果上重复拉伸导致超出屏幕。open 新图纸时置空。
39
+ */
40
+ fillViewSnapshot = null;
35
41
  constructor(parent, opts = {}) {
36
42
  this.store = useStore(s8());
37
43
  this.setOptions(opts);
@@ -201,12 +207,14 @@ export class Meta2d {
201
207
  this.render();
202
208
  }
203
209
  setDatabyOptions(options = {}) {
204
- const { color, activeColor, activeBackground, grid, gridColor, gridSize, fromArrow, toArrow, rule, ruleColor, textColor, x = 0, y = 0, } = options;
210
+ const { color, activeColor, activeBackground, grid, gridColor, gridSize, gridType, gridScope, fromArrow, toArrow, rule, ruleColor, textColor, x = 0, y = 0, } = options;
205
211
  this.setRule({ rule, ruleColor });
206
212
  this.setGrid({
207
213
  grid,
208
214
  gridColor,
209
215
  gridSize,
216
+ gridType,
217
+ gridScope,
210
218
  });
211
219
  this.store.data = Object.assign(this.store.data, {
212
220
  textColor,
@@ -927,9 +935,12 @@ export class Meta2d {
927
935
  async addPen(pen, history, emit = true, abs = false) {
928
936
  return await this.canvas.addPen(pen, history, emit, abs);
929
937
  }
930
- addPenSync(pen, history, emit = true, abs = false) {
938
+ addPenSync(pen, history, emit = true, abs = true) {
931
939
  return this.canvas.addPenSync(pen, history, emit, abs);
932
940
  }
941
+ addPensSync(pens, history, abs = true) {
942
+ return this.canvas.addPensSync(pens, history, abs);
943
+ }
933
944
  async addPens(pens, history, abs = false) {
934
945
  return await this.canvas.addPens(pens, history, abs);
935
946
  }
@@ -986,11 +997,13 @@ export class Meta2d {
986
997
  // this.store.patchFlagsBackground = true;
987
998
  this.canvas && (this.canvas.canvasTemplate.bgPatchFlags = true);
988
999
  }
989
- setGrid({ grid = this.store.data.grid, gridColor = this.store.data.gridColor, gridSize = this.store.data.gridSize, gridRotate = this.store.data.gridRotate, } = {}) {
1000
+ setGrid({ grid = this.store.data.grid, gridColor = this.store.data.gridColor, gridSize = this.store.data.gridSize, gridRotate = this.store.data.gridRotate, gridType = this.store.data.gridType, gridScope = this.store.data.gridScope, } = {}) {
990
1001
  this.store.data.grid = grid;
991
1002
  this.store.data.gridColor = gridColor;
992
1003
  this.store.data.gridSize = gridSize < 0 ? 0 : gridSize;
993
1004
  this.store.data.gridRotate = gridRotate;
1005
+ this.store.data.gridType = gridType;
1006
+ this.store.data.gridScope = gridScope;
994
1007
  // this.store.patchFlagsBackground = true;
995
1008
  this.canvas && (this.canvas.canvasTemplate.bgPatchFlags = true);
996
1009
  }
@@ -1001,6 +1014,8 @@ export class Meta2d {
1001
1014
  }
1002
1015
  open(data, render = true) {
1003
1016
  this.clear(false, data?.template);
1017
+ // 打开新图纸,原始几何快照失效,下次 fillView 时重新采集
1018
+ this.fillViewSnapshot = null;
1004
1019
  this.canvas.autoPolylineFlag = true;
1005
1020
  if (data) {
1006
1021
  // 根据图纸的主题设置主题
@@ -1583,6 +1598,8 @@ export class Meta2d {
1583
1598
  register = register;
1584
1599
  registerCanvasDraw = registerCanvasDraw;
1585
1600
  registerAnchors = registerAnchors;
1601
+ registerGridDrawer = registerGridDrawer;
1602
+ unregisterGridDrawer = unregisterGridDrawer;
1586
1603
  registerLineAnimateDraws = (name, drawFunc) => {
1587
1604
  this.store.data.lineAnimateDraws[name] = drawFunc;
1588
1605
  // 同步到store
@@ -1696,6 +1713,9 @@ export class Meta2d {
1696
1713
  }
1697
1714
  if (index !== -1 && index !== undefined) {
1698
1715
  const animate = deepClone(pen.animations[index]);
1716
+ if (!animate.animateCycle) {
1717
+ animate.animateCycle = 0;
1718
+ }
1699
1719
  animate.animateName = animate.name;
1700
1720
  delete animate.name;
1701
1721
  animate.currentAnimation = index;
@@ -2230,7 +2250,13 @@ export class Meta2d {
2230
2250
  this.store.data.websocket = websocket;
2231
2251
  }
2232
2252
  if (this.store.data.websocket) {
2233
- this.websocket = new WebSocket(this.store.data.websocket, this.store.data.websocketProtocols || undefined);
2253
+ try {
2254
+ this.websocket = new WebSocket(this.store.data.websocket, this.store.data.websocketProtocols || undefined);
2255
+ }
2256
+ catch (error) {
2257
+ this.store.emitter.emit('error', { type: 'websocket', error });
2258
+ return;
2259
+ }
2234
2260
  this.websocket.onmessage = (e) => {
2235
2261
  this.socketCallback(e.data, {
2236
2262
  type: 'websocket',
@@ -2494,7 +2520,10 @@ export class Meta2d {
2494
2520
  this.connectSqls();
2495
2521
  }
2496
2522
  reconnectNetwork(index) {
2497
- const net = this.store.data.networks[index];
2523
+ const net = this.store.data.networks?.[index];
2524
+ if (!net) {
2525
+ return;
2526
+ }
2498
2527
  if (net.protocol === 'mqtt') {
2499
2528
  this.mqttClients && this.mqttClients[net.index]?.end();
2500
2529
  this.connectNetMqtt(net);
@@ -3173,6 +3202,9 @@ export class Meta2d {
3173
3202
  }
3174
3203
  }
3175
3204
  penNetwork(pen) {
3205
+ if (!pen.apiUrl) {
3206
+ return;
3207
+ }
3176
3208
  const penNetwork = {
3177
3209
  url: pen.apiUrl,
3178
3210
  method: pen.apiMethod,
@@ -3268,8 +3300,8 @@ export class Meta2d {
3268
3300
  }
3269
3301
  async requestHttp(_req) {
3270
3302
  let req = deepClone(_req);
3271
- const net = this.store.data.networks.filter((item) => item.protocol === 'http')[req.index];
3272
- if (net.preJs) {
3303
+ const net = this.store.data.networks?.filter((item) => item.protocol === 'http')[req.index];
3304
+ if (net?.preJs) {
3273
3305
  if (!net.preFn) {
3274
3306
  const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
3275
3307
  net.preFn = new AsyncFunction('network', net.preJs);
@@ -3912,11 +3944,9 @@ export class Meta2d {
3912
3944
  }
3913
3945
  event.actions.forEach((action) => {
3914
3946
  if (action.timeout) {
3915
- let timer = setTimeout(() => {
3947
+ setTimeout(() => {
3916
3948
  if (this.events[action.action]) {
3917
3949
  this.events[action.action](pen, action);
3918
- clearTimeout(timer);
3919
- timer = null;
3920
3950
  }
3921
3951
  }, action.timeout);
3922
3952
  }
@@ -3962,11 +3992,9 @@ export class Meta2d {
3962
3992
  if (indexArr.includes(index)) {
3963
3993
  trigger.actions?.forEach((event) => {
3964
3994
  if (event.timeout) {
3965
- let timer = setTimeout(() => {
3995
+ setTimeout(() => {
3966
3996
  if (this.events[event.action]) {
3967
3997
  this.events[event.action](pen, event);
3968
- clearTimeout(timer);
3969
- timer = null;
3970
3998
  }
3971
3999
  }, event.timeout);
3972
4000
  }
@@ -4005,11 +4033,9 @@ export class Meta2d {
4005
4033
  if (indexArr.includes(index)) {
4006
4034
  trigger.actions?.forEach((event) => {
4007
4035
  if (event.timeout) {
4008
- let timer = setTimeout(() => {
4036
+ setTimeout(() => {
4009
4037
  if (this.events[event.action]) {
4010
4038
  this.events[event.action](pen, event);
4011
- clearTimeout(timer);
4012
- timer = null;
4013
4039
  }
4014
4040
  }, event.timeout);
4015
4041
  }
@@ -4044,11 +4070,9 @@ export class Meta2d {
4044
4070
  if (flag) {
4045
4071
  state.actions?.forEach((event) => {
4046
4072
  if (event.timeout) {
4047
- let timer = setTimeout(() => {
4073
+ setTimeout(() => {
4048
4074
  if (this.events[event.action]) {
4049
4075
  this.events[event.action](pen, event);
4050
- clearTimeout(timer);
4051
- timer = null;
4052
4076
  }
4053
4077
  }, event.timeout);
4054
4078
  }
@@ -4087,7 +4111,14 @@ export class Meta2d {
4087
4111
  }
4088
4112
  if (flag) {
4089
4113
  item.event.actions.forEach((action) => {
4090
- this.events[action.action](item.pen, action, data);
4114
+ if (action.timeout) {
4115
+ setTimeout(() => {
4116
+ this.events[action.action](item.pen, action, data);
4117
+ }, action.timeout);
4118
+ }
4119
+ else {
4120
+ this.events[action.action](item.pen, action, data);
4121
+ }
4091
4122
  });
4092
4123
  }
4093
4124
  });
@@ -4553,6 +4584,75 @@ export class Meta2d {
4553
4584
  rect = this.getRect();
4554
4585
  }
4555
4586
  // const rect = this.getRect();
4587
+ // 幂等处理:首次填充前记录各 fit 顶层图元的原始几何(设计坐标系,除以 scale、
4588
+ // 相对 origin,从而与当前缩放/平移无关);后续每次填充前先还原到原始几何,
4589
+ // 避免在上一次已拉伸的基础上再次拉伸,导致多次适应屏幕时内容超出屏幕。
4590
+ const { origin: _origin, scale: _scale } = this.store.data;
4591
+ if (!this.fillViewSnapshot) {
4592
+ this.fillViewSnapshot = new Map();
4593
+ this.store.data.fits?.forEach((fit) => {
4594
+ fit.children.forEach((id) => {
4595
+ const pen = this.store.pens[id];
4596
+ if (!pen) {
4597
+ return;
4598
+ }
4599
+ const wr = pen.calculative.worldRect;
4600
+ this.fillViewSnapshot.set(id, {
4601
+ x: (wr.x - _origin.x) / _scale,
4602
+ y: (wr.y - _origin.y) / _scale,
4603
+ width: wr.width / _scale,
4604
+ height: wr.height / _scale,
4605
+ textWidth: pen.textWidth != null ? pen.textWidth / _scale : undefined,
4606
+ colWidth: pen.colWidth,
4607
+ styleWidths: pen.styles?.map((style) => style.width),
4608
+ imageRatio: pen.imageRatio,
4609
+ ratio: pen.ratio,
4610
+ });
4611
+ });
4612
+ });
4613
+ }
4614
+ else {
4615
+ this.fillViewSnapshot.forEach((snap, id) => {
4616
+ const pen = this.store.pens[id];
4617
+ if (!pen) {
4618
+ return;
4619
+ }
4620
+ pen.x = _origin.x + snap.x * _scale;
4621
+ pen.y = _origin.y + snap.y * _scale;
4622
+ pen.width = snap.width * _scale;
4623
+ pen.height = snap.height * _scale;
4624
+ if (snap.textWidth !== undefined) {
4625
+ pen.textWidth = snap.textWidth * _scale;
4626
+ }
4627
+ if (snap.colWidth !== undefined) {
4628
+ pen.colWidth = snap.colWidth;
4629
+ }
4630
+ if (snap.styleWidths) {
4631
+ pen.styles?.forEach((style, i) => {
4632
+ if (snap.styleWidths[i] !== undefined) {
4633
+ style.width = snap.styleWidths[i];
4634
+ }
4635
+ });
4636
+ }
4637
+ if (snap.imageRatio !== undefined) {
4638
+ pen.imageRatio = snap.imageRatio;
4639
+ }
4640
+ if (snap.ratio !== undefined) {
4641
+ pen.ratio = snap.ratio;
4642
+ }
4643
+ this.canvas.updatePenRect(pen, { worldRectIsReady: false });
4644
+ if (pen.externElement) {
4645
+ pen.onResize?.(pen);
4646
+ }
4647
+ if (pen.children?.length) {
4648
+ getAllChildren(pen, this.store).forEach((cPen) => {
4649
+ if (cPen.externElement) {
4650
+ cPen.onResize?.(cPen);
4651
+ }
4652
+ });
4653
+ }
4654
+ });
4655
+ }
4556
4656
  const wGap = this.canvas.width - rect.width;
4557
4657
  const hGap = this.canvas.height - rect.height;
4558
4658
  //宽度拉伸
@@ -5518,6 +5618,9 @@ export class Meta2d {
5518
5618
  this.canvas.canvasImageBottom.init();
5519
5619
  this.render();
5520
5620
  }
5621
+ animateView(options) {
5622
+ this.canvas.animateView(options);
5623
+ }
5521
5624
  showMap() {
5522
5625
  if (!this.map) {
5523
5626
  this.map = new ViewMap(this.canvas);