@meta2d/core 1.1.22 → 1.1.24

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meta2d/core",
3
- "version": "1.1.22",
3
+ "version": "1.1.24",
4
4
  "description": "@meta2d/core: Powerful, Beautiful, Simple, Open - Web-Based 2D At Its Best .",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -81,6 +81,8 @@ export declare class Canvas {
81
81
  private lastAnimateRender;
82
82
  animateRendering: boolean;
83
83
  renderTimer: number;
84
+ private viewAnimation?;
85
+ private viewAnimationTimer?;
84
86
  initPens?: Pen[];
85
87
  pointSize: 8;
86
88
  pasteOffset: boolean;
@@ -153,6 +155,7 @@ export declare class Canvas {
153
155
  dropPens(pens: Pen[], e: Point): Promise<void>;
154
156
  randomCombineId(pen: Pen, pens: Pen[], parentId?: string): Pen;
155
157
  addPens(pens: Pen[], history?: boolean, abs?: boolean): Promise<Pen[]>;
158
+ addPensSync(pens: Pen[], history?: boolean, abs?: boolean): Pen[];
156
159
  ontouchstart: (e: TouchEvent) => void;
157
160
  ontouchmove: (event: TouchEvent) => void;
158
161
  ontouchend: (event: TouchEvent) => void;
@@ -305,6 +308,16 @@ export declare class Canvas {
305
308
  x: number;
306
309
  y: number;
307
310
  }): void;
311
+ animateView(options: {
312
+ x?: number;
313
+ y?: number;
314
+ scale?: number;
315
+ pen?: Pen;
316
+ duration?: number;
317
+ easing?: string;
318
+ center?: Point;
319
+ }): void;
320
+ private animateViewFrame;
308
321
  templateScale(scale: number, center?: {
309
322
  x: number;
310
323
  y: number;
@@ -22,6 +22,7 @@ import { getLinePoints } from '../diagrams/line';
22
22
  import { Popconfirm } from '../popconfirm';
23
23
  import { le5leTheme, themeKeys } from '../theme';
24
24
  import { getFont } from '../pen/render';
25
+ import { getEasingFunction } from '../utils/easing';
25
26
  export const movingSuffix = '-moving';
26
27
  export class Canvas {
27
28
  parent;
@@ -82,6 +83,8 @@ export class Canvas {
82
83
  lastAnimateRender = 0;
83
84
  animateRendering = false;
84
85
  renderTimer;
86
+ viewAnimation;
87
+ viewAnimationTimer;
85
88
  initPens;
86
89
  pointSize = 8;
87
90
  pasteOffset = true;
@@ -125,7 +128,7 @@ export class Canvas {
125
128
  this.parent = parent;
126
129
  this.parentElement = parentElement;
127
130
  this.store = store;
128
- this.canvasTemplate = new CanvasTemplate(parentElement, store);
131
+ this.canvasTemplate = new CanvasTemplate(parentElement, store, this);
129
132
  this.canvasTemplate.canvas.style.zIndex = '1';
130
133
  this.canvasImageBottom = new CanvasImage(parentElement, store, true);
131
134
  this.canvasImageBottom.canvas.style.zIndex = '2';
@@ -415,6 +418,7 @@ export class Canvas {
415
418
  }
416
419
  };
417
420
  onwheel = (e) => {
421
+ this.viewAnimation = undefined;
418
422
  //输入模式不允许滚动
419
423
  if (this.inputDiv.contentEditable === 'true') {
420
424
  return;
@@ -1376,7 +1380,37 @@ export class Canvas {
1376
1380
  }
1377
1381
  return list;
1378
1382
  }
1383
+ addPensSync(pens, history, abs) {
1384
+ const list = [];
1385
+ // for (const pen of pens) {
1386
+ // if (!pen.id) {
1387
+ // pen.id = s8();
1388
+ // }
1389
+ // !pen.calculative && (pen.calculative = { canvas: this });
1390
+ // this.store.pens[pen.id] = pen;
1391
+ // }
1392
+ for (const pen of pens) {
1393
+ if (this.beforeAddPen && this.beforeAddPen(pen) != true) {
1394
+ continue;
1395
+ }
1396
+ if (abs && !pen.parentId) {
1397
+ pen.x = pen.x * this.store.data.scale + this.store.data.origin.x;
1398
+ pen.y = pen.y * this.store.data.scale + this.store.data.origin.y;
1399
+ pen.width = pen.width * this.store.data.scale;
1400
+ pen.height = pen.height * this.store.data.scale;
1401
+ }
1402
+ this.makePen(pen);
1403
+ list.push(pen);
1404
+ }
1405
+ this.render();
1406
+ this.store.emitter.emit('add', list);
1407
+ if (history) {
1408
+ this.pushHistory({ type: EditType.Add, pens: deepClone(list, true) });
1409
+ }
1410
+ return list;
1411
+ }
1379
1412
  ontouchstart = (e) => {
1413
+ this.viewAnimation = undefined;
1380
1414
  this.lastTouchY = e.touches[0].clientY;
1381
1415
  if (this.store.data.locked === LockState.Disable) {
1382
1416
  return;
@@ -1638,6 +1672,7 @@ export class Canvas {
1638
1672
  };
1639
1673
  }
1640
1674
  onMouseDown = (e) => {
1675
+ this.viewAnimation = undefined;
1641
1676
  if (e.buttons === 2 && !this.drawingLine) {
1642
1677
  this.mouseRight = MouseRight.Down;
1643
1678
  }
@@ -3571,6 +3606,12 @@ export class Canvas {
3571
3606
  const i = this.store.data.pens.findIndex((item) => item.id === pen.id);
3572
3607
  if (i > -1) {
3573
3608
  pen.onDestroy?.(this.store.pens[pen.id]);
3609
+ const parent = pen.parentId
3610
+ ? this.store.pens[pen.parentId]
3611
+ : undefined;
3612
+ if (parent?.children) {
3613
+ parent.children = parent.children.filter((item) => item !== pen.id);
3614
+ }
3574
3615
  this.store.data.pens.splice(i, 1);
3575
3616
  this.store.pens[pen.id] = undefined;
3576
3617
  if (!pen.calculative) {
@@ -3643,6 +3684,13 @@ export class Canvas {
3643
3684
  }
3644
3685
  // 先放进去,pens 可能是子节点在前,而父节点在后
3645
3686
  this.store.pens[pen.id] = pen;
3687
+ if (pen.parentId) {
3688
+ !this.store.pens[pen.parentId].children &&
3689
+ (this.store.pens[pen.parentId].children = []);
3690
+ if (!this.store.pens[pen.parentId].children.includes(pen.id)) {
3691
+ this.store.pens[pen.parentId].children.push(pen.id);
3692
+ }
3693
+ }
3646
3694
  if (pen.type && pen.lastConnected) {
3647
3695
  for (let key in pen.lastConnected) {
3648
3696
  this.store.pens[key] && (this.store.pens[key].connectedLines = pen.lastConnected[key]);
@@ -4367,6 +4415,10 @@ export class Canvas {
4367
4415
  now = performance.now();
4368
4416
  }
4369
4417
  if (!this.patchFlags) {
4418
+ if (this.store.options.gridAlwaysRender && (this.store.options.grid || this.store.data.grid)) {
4419
+ this.canvasTemplate.bgPatchFlags = true;
4420
+ this.canvasTemplate.render();
4421
+ }
4370
4422
  return;
4371
4423
  }
4372
4424
  if (patchFlags != null) {
@@ -4766,11 +4818,11 @@ export class Canvas {
4766
4818
  if (anchor.label) {
4767
4819
  ctx.save();
4768
4820
  ctx.font = getFont({
4769
- fontStyle,
4770
- fontWeight,
4771
- fontFamily,
4772
- fontSize,
4773
- lineHeight,
4821
+ fontStyle: anchor.labelStyle?.fontStyle || fontStyle,
4822
+ fontWeight: anchor.labelStyle?.fontWeight || fontWeight,
4823
+ fontFamily: anchor.labelStyle?.fontFamily || fontFamily,
4824
+ lineHeight: anchor.labelStyle?.lineHeight || lineHeight,
4825
+ fontSize: anchor.labelStyle?.fontSize * scale || fontSize,
4774
4826
  });
4775
4827
  const rX = pen.anchors[index].x;
4776
4828
  const rY = pen.anchors[index].y;
@@ -4824,7 +4876,7 @@ export class Canvas {
4824
4876
  }
4825
4877
  }
4826
4878
  }
4827
- ctx.fillStyle = getTextColor(pen, this.store);
4879
+ ctx.fillStyle = anchor.labelStyle?.textColor || getTextColor(pen, this.store);
4828
4880
  ctx.fillText(anchor.label, anchor.x + xGap, anchor.y + yGap);
4829
4881
  ctx.restore();
4830
4882
  }
@@ -4995,6 +5047,184 @@ export class Canvas {
4995
5047
  this.store.emitter.emit('scale', this.store.data.scale);
4996
5048
  // });
4997
5049
  }
5050
+ animateView(options) {
5051
+ if (this.viewAnimationTimer) {
5052
+ cancelAnimationFrame(this.viewAnimationTimer);
5053
+ this.viewAnimationTimer = undefined;
5054
+ }
5055
+ this.viewAnimation = undefined;
5056
+ const duration = options.duration ?? 300;
5057
+ const easingName = options.easing ?? 'easeOutCubic';
5058
+ const center = options.center
5059
+ ? { ...options.center }
5060
+ : {
5061
+ x: this.width / 2,
5062
+ y: this.height / 2,
5063
+ };
5064
+ let toX = options.x !== undefined ? options.x : this.store.data.x;
5065
+ let toY = options.y !== undefined ? options.y : this.store.data.y;
5066
+ let toScale = options.scale !== undefined ? options.scale : this.store.data.scale;
5067
+ const minScale = this.store.data.minScale || this.store.options.minScale;
5068
+ const maxScale = this.store.data.maxScale || this.store.options.maxScale;
5069
+ if (toScale < minScale)
5070
+ toScale = minScale;
5071
+ if (toScale > maxScale)
5072
+ toScale = maxScale;
5073
+ if (options.pen) {
5074
+ const viewCenter = {
5075
+ x: this.width / 2,
5076
+ y: this.height / 2,
5077
+ };
5078
+ toX =
5079
+ viewCenter.x -
5080
+ options.pen.calculative.worldRect.x -
5081
+ options.pen.calculative.worldRect.width / 2;
5082
+ toY =
5083
+ viewCenter.y -
5084
+ options.pen.calculative.worldRect.y -
5085
+ options.pen.calculative.worldRect.height / 2;
5086
+ }
5087
+ if (!options.pen &&
5088
+ Math.abs(toX - this.store.data.x) < 0.5 &&
5089
+ Math.abs(toY - this.store.data.y) < 0.5 &&
5090
+ Math.abs(toScale - this.store.data.scale) < 0.001) {
5091
+ return;
5092
+ }
5093
+ this.calibrateMouse(center);
5094
+ this.viewAnimation = {
5095
+ startTime: performance.now(),
5096
+ duration,
5097
+ fromX: this.store.data.x,
5098
+ fromY: this.store.data.y,
5099
+ fromScale: this.store.data.scale,
5100
+ toX,
5101
+ toY,
5102
+ toScale,
5103
+ easing: getEasingFunction(easingName),
5104
+ center,
5105
+ pen: options.pen,
5106
+ };
5107
+ this.animateViewFrame();
5108
+ }
5109
+ animateViewFrame = () => {
5110
+ if (!this.viewAnimation) {
5111
+ return;
5112
+ }
5113
+ const now = performance.now();
5114
+ const { startTime, duration, fromX, fromY, fromScale, toX, toY, toScale, easing, center, pen, } = this.viewAnimation;
5115
+ let progress = Math.min(1, (now - startTime) / duration);
5116
+ progress = easing(progress);
5117
+ const prevScale = this.store.data.scale;
5118
+ const currentScale = fromScale + (toScale - fromScale) * progress;
5119
+ const s = currentScale / prevScale;
5120
+ if (s !== 1) {
5121
+ this.store.data.scale = currentScale;
5122
+ this.store.data.center = center;
5123
+ scalePoint(this.store.data.origin, s, center);
5124
+ this.store.data.pens.forEach((p) => {
5125
+ p.onScale && p.onScale(p);
5126
+ if (p.parentId) {
5127
+ return;
5128
+ }
5129
+ scalePen(p, s, center);
5130
+ if (p.isRuleLine) {
5131
+ const lineScale = 1 / s;
5132
+ const lineCenter = p.calculative.worldRect.center;
5133
+ if (!p.width) {
5134
+ scalePen(p, lineScale, lineCenter);
5135
+ }
5136
+ else if (!p.height) {
5137
+ scalePen(p, lineScale, lineCenter);
5138
+ }
5139
+ }
5140
+ this.updatePenRect(p, { worldRectIsReady: true });
5141
+ this.execPenResize(p);
5142
+ });
5143
+ this.calcActiveRect();
5144
+ }
5145
+ // Calculate current x, y
5146
+ let currentX;
5147
+ let currentY;
5148
+ if (pen) {
5149
+ // 参考 gotoView 的计算方式,基于当前 worldRect 实时计算
5150
+ const viewCenter = {
5151
+ x: this.width / 2,
5152
+ y: this.height / 2,
5153
+ };
5154
+ const targetX = viewCenter.x -
5155
+ pen.calculative.worldRect.x -
5156
+ pen.calculative.worldRect.width / 2;
5157
+ const targetY = viewCenter.y -
5158
+ pen.calculative.worldRect.y -
5159
+ pen.calculative.worldRect.height / 2;
5160
+ currentX = fromX + (targetX - fromX) * progress;
5161
+ currentY = fromY + (targetY - fromY) * progress;
5162
+ }
5163
+ else {
5164
+ currentX = fromX + (toX - fromX) * progress;
5165
+ currentY = fromY + (toY - fromY) * progress;
5166
+ }
5167
+ const prevX = this.store.data.x;
5168
+ const prevY = this.store.data.y;
5169
+ this.store.data.x = currentX;
5170
+ this.store.data.y = currentY;
5171
+ if (this.scroll && this.scroll.isShow) {
5172
+ this.scroll.translate(currentX - prevX, currentY - prevY);
5173
+ }
5174
+ this.onMovePens();
5175
+ this.canvasTemplate.init();
5176
+ this.canvasImage.init();
5177
+ this.canvasImageBottom.init();
5178
+ this.render();
5179
+ if (progress < 1) {
5180
+ this.viewAnimationTimer = requestAnimationFrame(this.animateViewFrame);
5181
+ }
5182
+ else {
5183
+ // Ensure final values are exact
5184
+ if (!pen) {
5185
+ this.store.data.x = toX;
5186
+ this.store.data.y = toY;
5187
+ }
5188
+ if (Math.abs(this.store.data.scale - toScale) > 0.001) {
5189
+ const finalS = toScale / this.store.data.scale;
5190
+ this.store.data.scale = toScale;
5191
+ this.store.data.center = center;
5192
+ scalePoint(this.store.data.origin, finalS, center);
5193
+ this.store.data.pens.forEach((p) => {
5194
+ p.onScale && p.onScale(p);
5195
+ if (p.parentId) {
5196
+ return;
5197
+ }
5198
+ scalePen(p, finalS, center);
5199
+ if (p.isRuleLine) {
5200
+ const lineScale = 1 / finalS;
5201
+ const lineCenter = p.calculative.worldRect.center;
5202
+ if (!p.width) {
5203
+ scalePen(p, lineScale, lineCenter);
5204
+ }
5205
+ else if (!p.height) {
5206
+ scalePen(p, lineScale, lineCenter);
5207
+ }
5208
+ }
5209
+ this.updatePenRect(p, { worldRectIsReady: true });
5210
+ this.execPenResize(p);
5211
+ });
5212
+ this.calcActiveRect();
5213
+ this.onMovePens();
5214
+ this.canvasTemplate.init();
5215
+ this.canvasImage.init();
5216
+ this.canvasImageBottom.init();
5217
+ this.render();
5218
+ }
5219
+ this.viewAnimation = undefined;
5220
+ this.viewAnimationTimer = undefined;
5221
+ this.store.emitter.emit('scale', this.store.data.scale);
5222
+ this.store.emitter.emit('translate', {
5223
+ x: this.store.data.x,
5224
+ y: this.store.data.y,
5225
+ });
5226
+ }
5227
+ };
4998
5228
  templateScale(scale, center = { x: 0, y: 0 }) {
4999
5229
  const { minScale, maxScale } = this.store.options;
5000
5230
  if (!(scale >= minScale && scale <= maxScale)) {
@@ -6899,11 +7129,10 @@ export class Canvas {
6899
7129
  if (pen.fontWeight) {
6900
7130
  style += `font-weight: ${pen.fontWeight};`;
6901
7131
  }
7132
+ let ml = 0;
6902
7133
  if (pen.textLeft) {
6903
- style += `margin-left:${scale > 1
6904
- ? pen.textLeft * scale
6905
- : (pen.textLeft * scale) // scale
6906
- }px;`;
7134
+ ml = scale > 1 ? pen.textLeft * scale : (pen.textLeft * scale);
7135
+ style += `margin-left:${ml}px;`;
6907
7136
  }
6908
7137
  if (pen.textTop) {
6909
7138
  style += `margin-top:${scale > 1
@@ -6960,7 +7189,7 @@ export class Canvas {
6960
7189
  if (tem < 0) {
6961
7190
  tem = 0;
6962
7191
  }
6963
- style += `width:${pen.fontSize * scale < 12 ? tem * scale : tem * scale}px;`;
7192
+ style += `width:${pen.fontSize * scale < 12 ? tem * scale - ml : tem * scale - ml}px;`;
6964
7193
  }
6965
7194
  // if (pen.whiteSpace === 'pre-line') {
6966
7195
  // //回车换行
@@ -6987,9 +7216,9 @@ export class Canvas {
6987
7216
  Math.floor(pen.calculative.worldRect.height /
6988
7217
  scale /
6989
7218
  (pen.lineHeight * pen.fontSize));
6990
- if (textWidth > contentWidth) {
6991
- style += 'justify-content: start;';
6992
- }
7219
+ // if (textWidth > contentWidth) {
7220
+ // style += 'justify-content: start;';
7221
+ // }
6993
7222
  }
6994
7223
  sheet.deleteRule(0);
6995
7224
  sheet.deleteRule(0);