@meta2d/core 1.1.22 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meta2d/core",
3
- "version": "1.1.22",
3
+ "version": "1.1.23",
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
  }
@@ -4367,6 +4402,10 @@ export class Canvas {
4367
4402
  now = performance.now();
4368
4403
  }
4369
4404
  if (!this.patchFlags) {
4405
+ if (this.store.options.gridAlwaysRender && (this.store.options.grid || this.store.data.grid)) {
4406
+ this.canvasTemplate.bgPatchFlags = true;
4407
+ this.canvasTemplate.render();
4408
+ }
4370
4409
  return;
4371
4410
  }
4372
4411
  if (patchFlags != null) {
@@ -4766,11 +4805,11 @@ export class Canvas {
4766
4805
  if (anchor.label) {
4767
4806
  ctx.save();
4768
4807
  ctx.font = getFont({
4769
- fontStyle,
4770
- fontWeight,
4771
- fontFamily,
4772
- fontSize,
4773
- lineHeight,
4808
+ fontStyle: anchor.labelStyle?.fontStyle || fontStyle,
4809
+ fontWeight: anchor.labelStyle?.fontWeight || fontWeight,
4810
+ fontFamily: anchor.labelStyle?.fontFamily || fontFamily,
4811
+ lineHeight: anchor.labelStyle?.lineHeight || lineHeight,
4812
+ fontSize: anchor.labelStyle?.fontSize * scale || fontSize,
4774
4813
  });
4775
4814
  const rX = pen.anchors[index].x;
4776
4815
  const rY = pen.anchors[index].y;
@@ -4824,7 +4863,7 @@ export class Canvas {
4824
4863
  }
4825
4864
  }
4826
4865
  }
4827
- ctx.fillStyle = getTextColor(pen, this.store);
4866
+ ctx.fillStyle = anchor.labelStyle?.textColor || getTextColor(pen, this.store);
4828
4867
  ctx.fillText(anchor.label, anchor.x + xGap, anchor.y + yGap);
4829
4868
  ctx.restore();
4830
4869
  }
@@ -4995,6 +5034,184 @@ export class Canvas {
4995
5034
  this.store.emitter.emit('scale', this.store.data.scale);
4996
5035
  // });
4997
5036
  }
5037
+ animateView(options) {
5038
+ if (this.viewAnimationTimer) {
5039
+ cancelAnimationFrame(this.viewAnimationTimer);
5040
+ this.viewAnimationTimer = undefined;
5041
+ }
5042
+ this.viewAnimation = undefined;
5043
+ const duration = options.duration ?? 300;
5044
+ const easingName = options.easing ?? 'easeOutCubic';
5045
+ const center = options.center
5046
+ ? { ...options.center }
5047
+ : {
5048
+ x: this.width / 2,
5049
+ y: this.height / 2,
5050
+ };
5051
+ let toX = options.x !== undefined ? options.x : this.store.data.x;
5052
+ let toY = options.y !== undefined ? options.y : this.store.data.y;
5053
+ let toScale = options.scale !== undefined ? options.scale : this.store.data.scale;
5054
+ const minScale = this.store.data.minScale || this.store.options.minScale;
5055
+ const maxScale = this.store.data.maxScale || this.store.options.maxScale;
5056
+ if (toScale < minScale)
5057
+ toScale = minScale;
5058
+ if (toScale > maxScale)
5059
+ toScale = maxScale;
5060
+ if (options.pen) {
5061
+ const viewCenter = {
5062
+ x: this.width / 2,
5063
+ y: this.height / 2,
5064
+ };
5065
+ toX =
5066
+ viewCenter.x -
5067
+ options.pen.calculative.worldRect.x -
5068
+ options.pen.calculative.worldRect.width / 2;
5069
+ toY =
5070
+ viewCenter.y -
5071
+ options.pen.calculative.worldRect.y -
5072
+ options.pen.calculative.worldRect.height / 2;
5073
+ }
5074
+ if (!options.pen &&
5075
+ Math.abs(toX - this.store.data.x) < 0.5 &&
5076
+ Math.abs(toY - this.store.data.y) < 0.5 &&
5077
+ Math.abs(toScale - this.store.data.scale) < 0.001) {
5078
+ return;
5079
+ }
5080
+ this.calibrateMouse(center);
5081
+ this.viewAnimation = {
5082
+ startTime: performance.now(),
5083
+ duration,
5084
+ fromX: this.store.data.x,
5085
+ fromY: this.store.data.y,
5086
+ fromScale: this.store.data.scale,
5087
+ toX,
5088
+ toY,
5089
+ toScale,
5090
+ easing: getEasingFunction(easingName),
5091
+ center,
5092
+ pen: options.pen,
5093
+ };
5094
+ this.animateViewFrame();
5095
+ }
5096
+ animateViewFrame = () => {
5097
+ if (!this.viewAnimation) {
5098
+ return;
5099
+ }
5100
+ const now = performance.now();
5101
+ const { startTime, duration, fromX, fromY, fromScale, toX, toY, toScale, easing, center, pen, } = this.viewAnimation;
5102
+ let progress = Math.min(1, (now - startTime) / duration);
5103
+ progress = easing(progress);
5104
+ const prevScale = this.store.data.scale;
5105
+ const currentScale = fromScale + (toScale - fromScale) * progress;
5106
+ const s = currentScale / prevScale;
5107
+ if (s !== 1) {
5108
+ this.store.data.scale = currentScale;
5109
+ this.store.data.center = center;
5110
+ scalePoint(this.store.data.origin, s, center);
5111
+ this.store.data.pens.forEach((p) => {
5112
+ p.onScale && p.onScale(p);
5113
+ if (p.parentId) {
5114
+ return;
5115
+ }
5116
+ scalePen(p, s, center);
5117
+ if (p.isRuleLine) {
5118
+ const lineScale = 1 / s;
5119
+ const lineCenter = p.calculative.worldRect.center;
5120
+ if (!p.width) {
5121
+ scalePen(p, lineScale, lineCenter);
5122
+ }
5123
+ else if (!p.height) {
5124
+ scalePen(p, lineScale, lineCenter);
5125
+ }
5126
+ }
5127
+ this.updatePenRect(p, { worldRectIsReady: true });
5128
+ this.execPenResize(p);
5129
+ });
5130
+ this.calcActiveRect();
5131
+ }
5132
+ // Calculate current x, y
5133
+ let currentX;
5134
+ let currentY;
5135
+ if (pen) {
5136
+ // 参考 gotoView 的计算方式,基于当前 worldRect 实时计算
5137
+ const viewCenter = {
5138
+ x: this.width / 2,
5139
+ y: this.height / 2,
5140
+ };
5141
+ const targetX = viewCenter.x -
5142
+ pen.calculative.worldRect.x -
5143
+ pen.calculative.worldRect.width / 2;
5144
+ const targetY = viewCenter.y -
5145
+ pen.calculative.worldRect.y -
5146
+ pen.calculative.worldRect.height / 2;
5147
+ currentX = fromX + (targetX - fromX) * progress;
5148
+ currentY = fromY + (targetY - fromY) * progress;
5149
+ }
5150
+ else {
5151
+ currentX = fromX + (toX - fromX) * progress;
5152
+ currentY = fromY + (toY - fromY) * progress;
5153
+ }
5154
+ const prevX = this.store.data.x;
5155
+ const prevY = this.store.data.y;
5156
+ this.store.data.x = currentX;
5157
+ this.store.data.y = currentY;
5158
+ if (this.scroll && this.scroll.isShow) {
5159
+ this.scroll.translate(currentX - prevX, currentY - prevY);
5160
+ }
5161
+ this.onMovePens();
5162
+ this.canvasTemplate.init();
5163
+ this.canvasImage.init();
5164
+ this.canvasImageBottom.init();
5165
+ this.render();
5166
+ if (progress < 1) {
5167
+ this.viewAnimationTimer = requestAnimationFrame(this.animateViewFrame);
5168
+ }
5169
+ else {
5170
+ // Ensure final values are exact
5171
+ if (!pen) {
5172
+ this.store.data.x = toX;
5173
+ this.store.data.y = toY;
5174
+ }
5175
+ if (Math.abs(this.store.data.scale - toScale) > 0.001) {
5176
+ const finalS = toScale / this.store.data.scale;
5177
+ this.store.data.scale = toScale;
5178
+ this.store.data.center = center;
5179
+ scalePoint(this.store.data.origin, finalS, center);
5180
+ this.store.data.pens.forEach((p) => {
5181
+ p.onScale && p.onScale(p);
5182
+ if (p.parentId) {
5183
+ return;
5184
+ }
5185
+ scalePen(p, finalS, center);
5186
+ if (p.isRuleLine) {
5187
+ const lineScale = 1 / finalS;
5188
+ const lineCenter = p.calculative.worldRect.center;
5189
+ if (!p.width) {
5190
+ scalePen(p, lineScale, lineCenter);
5191
+ }
5192
+ else if (!p.height) {
5193
+ scalePen(p, lineScale, lineCenter);
5194
+ }
5195
+ }
5196
+ this.updatePenRect(p, { worldRectIsReady: true });
5197
+ this.execPenResize(p);
5198
+ });
5199
+ this.calcActiveRect();
5200
+ this.onMovePens();
5201
+ this.canvasTemplate.init();
5202
+ this.canvasImage.init();
5203
+ this.canvasImageBottom.init();
5204
+ this.render();
5205
+ }
5206
+ this.viewAnimation = undefined;
5207
+ this.viewAnimationTimer = undefined;
5208
+ this.store.emitter.emit('scale', this.store.data.scale);
5209
+ this.store.emitter.emit('translate', {
5210
+ x: this.store.data.x,
5211
+ y: this.store.data.y,
5212
+ });
5213
+ }
5214
+ };
4998
5215
  templateScale(scale, center = { x: 0, y: 0 }) {
4999
5216
  const { minScale, maxScale } = this.store.options;
5000
5217
  if (!(scale >= minScale && scale <= maxScale)) {
@@ -6899,11 +7116,10 @@ export class Canvas {
6899
7116
  if (pen.fontWeight) {
6900
7117
  style += `font-weight: ${pen.fontWeight};`;
6901
7118
  }
7119
+ let ml = 0;
6902
7120
  if (pen.textLeft) {
6903
- style += `margin-left:${scale > 1
6904
- ? pen.textLeft * scale
6905
- : (pen.textLeft * scale) // scale
6906
- }px;`;
7121
+ ml = scale > 1 ? pen.textLeft * scale : (pen.textLeft * scale);
7122
+ style += `margin-left:${ml}px;`;
6907
7123
  }
6908
7124
  if (pen.textTop) {
6909
7125
  style += `margin-top:${scale > 1
@@ -6960,7 +7176,7 @@ export class Canvas {
6960
7176
  if (tem < 0) {
6961
7177
  tem = 0;
6962
7178
  }
6963
- style += `width:${pen.fontSize * scale < 12 ? tem * scale : tem * scale}px;`;
7179
+ style += `width:${pen.fontSize * scale < 12 ? tem * scale - ml : tem * scale - ml}px;`;
6964
7180
  }
6965
7181
  // if (pen.whiteSpace === 'pre-line') {
6966
7182
  // //回车换行
@@ -6987,9 +7203,9 @@ export class Canvas {
6987
7203
  Math.floor(pen.calculative.worldRect.height /
6988
7204
  scale /
6989
7205
  (pen.lineHeight * pen.fontSize));
6990
- if (textWidth > contentWidth) {
6991
- style += 'justify-content: start;';
6992
- }
7206
+ // if (textWidth > contentWidth) {
7207
+ // style += 'justify-content: start;';
7208
+ // }
6993
7209
  }
6994
7210
  sheet.deleteRule(0);
6995
7211
  sheet.deleteRule(0);