@hailin-zheng/editor-core 1.1.5 → 1.1.6

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.
@@ -1,10 +1,7 @@
1
- import { IArrangeEvent, IMeasureEvent, IRenderData, Panel, Size } from "./Node";
1
+ import { AbsolutePanel, IRenderData } from "./Node";
2
2
  /**
3
3
  * 采用绝对布局系统的容器
4
4
  */
5
- export declare class Canvas extends Panel {
6
- constructor();
7
- measureOverride(e: IMeasureEvent, availableSize: Size): Size;
8
- protected arrangeOverride(e: IArrangeEvent, finalSize: Size): Size;
5
+ export declare class Canvas extends AbsolutePanel {
9
6
  render(e: IRenderData): void;
10
7
  }
@@ -42,6 +42,8 @@ export interface IAppState {
42
42
  export declare abstract class NodeCore {
43
43
  enableClip: boolean;
44
44
  pointEvent: boolean;
45
+ allowHitTest: boolean;
46
+ hitTest(hitPos: Position, currPos: Position): boolean;
45
47
  get enable(): boolean;
46
48
  set enable(value: boolean);
47
49
  private _enable;
@@ -171,6 +173,7 @@ export declare abstract class NodeItems extends NodeCore {
171
173
  eventMap: WeakMap<NodeCore, Array<Subscription>>;
172
174
  absoluteItems: boolean;
173
175
  containerPropName: string;
176
+ constructor();
174
177
  addChild(control: NodeCore, index?: number): void;
175
178
  getRenderItems(): Array<NodeCore>;
176
179
  removeChild(index: number | NodeCore): void;
@@ -184,6 +187,14 @@ export declare abstract class NodeItems extends NodeCore {
184
187
  }
185
188
  export declare abstract class Panel extends NodeItems {
186
189
  }
190
+ /**
191
+ * 子内容采用绝对定位的容器
192
+ */
193
+ export declare abstract class AbsolutePanel extends NodeItems {
194
+ protected constructor();
195
+ measureOverride(e: IMeasureEvent, availableSize: Size): Size;
196
+ protected arrangeOverride(e: IArrangeEvent, finalSize: Size): Size;
197
+ }
187
198
  export interface ActiveAppContext {
188
199
  root: SurfaceView;
189
200
  render: () => void;
@@ -199,6 +210,10 @@ export declare function renderNode(node: NodeCore, renderCtx: ViewPaint, appStat
199
210
  * @param renderCtx
200
211
  */
201
212
  export declare function drawBorderline(node: NodeCore, renderCtx: ViewPaint): void;
213
+ /**
214
+ * 绘制外轮廓
215
+ */
216
+ export declare function drawOutline(node: NodeCore, renderCtx: ViewPaint): void;
202
217
  export declare function clipContent(node: NodeCore, renderCtx: ViewPaint): void;
203
218
  export declare function translate(renderCtx: ViewPaint, x: number, y: number): void;
204
219
  export declare function getParents(node: NodeCore): Array<NodeCore>;
@@ -1,17 +1,18 @@
1
1
  import { Size, IRenderData, IMeasureEvent, IArrangeEvent } from "./Node";
2
2
  import { TextBase } from "./TextBase";
3
- export declare type TextVertAlign = 'superscript' | 'subscript';
4
3
  /**
5
4
  * 文本元素尺寸默认按照横向排列进行测量,内容高度等于字体大小
6
5
  * 如果有默认宽度限制,而且支持换行显示,则内容高度等于多行累计高度
7
6
  */
8
7
  export declare class LabelNode extends TextBase {
8
+ constructor();
9
9
  private _textWrapping;
10
10
  get textWrapping(): "wrap" | "no";
11
11
  set textWrapping(value: "wrap" | "no");
12
12
  protected cacheTextRect: TextMeasureRect;
13
- private textUnits;
13
+ private lines;
14
14
  measureOverride(e: IMeasureEvent, availableSize: Size): Size;
15
+ private getMuiltLines;
15
16
  protected arrangeOverride(e: IArrangeEvent, finalSize: Size): Size;
16
17
  private getTextProps;
17
18
  private measureTextRect;
@@ -17,11 +17,20 @@ export declare class ViewPaint {
17
17
  getGlobalAlpha(): number;
18
18
  clear(): void;
19
19
  drawText(text: string, textProps: TextProps, x: number, y: number, width: number, height: number): void;
20
+ drawText2(text: string, textProps: {
21
+ color: string;
22
+ fontSize: number;
23
+ fontName: string;
24
+ }, x: number, y: number): void;
20
25
  fillCircular(x: number, y: number, r: number, color?: string): void;
21
26
  measureText(text: string, textProps: TextProps): {
22
27
  width: number;
23
28
  height: number;
24
29
  };
30
+ measureText2(text: string, font: {
31
+ fontSize: number;
32
+ fontName: string;
33
+ }): number;
25
34
  measureTextUnits(units: Array<TextUnits>, textProps: TextProps): void;
26
35
  clearRect(x: number, y: number, width: number, height: number): void;
27
36
  save(): void;
package/index-cjs.js CHANGED
@@ -4261,7 +4261,6 @@ class TableUtil {
4261
4261
  if (!ss.startControl) {
4262
4262
  return;
4263
4263
  }
4264
- ss.clear();
4265
4264
  const startCell = ElementUtil.getParentByType(ss.startControl, TableCellElement);
4266
4265
  if (!startCell?.parent) {
4267
4266
  throw new Error('parent is null');
@@ -4272,6 +4271,7 @@ class TableUtil {
4272
4271
  if (tb.length === 0) {
4273
4272
  tb.remove();
4274
4273
  }
4274
+ ss.clear();
4275
4275
  }
4276
4276
  /**
4277
4277
  * 移除光标所在的当前列
@@ -11193,6 +11193,7 @@ class ParagraphMeasure {
11193
11193
  */
11194
11194
  measureParagraph(p, limitWidth) {
11195
11195
  ElementUtil.fixParagraphContent(p);
11196
+ this.verifyPara(p, limitWidth);
11196
11197
  p.cacheRender = null;
11197
11198
  const paraModels = [];
11198
11199
  let currRenderLine;
@@ -11313,6 +11314,17 @@ class ParagraphMeasure {
11313
11314
  }
11314
11315
  return paraRenders;
11315
11316
  }
11317
+ /**
11318
+ * 校验当前段落属性
11319
+ */
11320
+ verifyPara(p, limitWidth) {
11321
+ if (p.props.indent > 0 && p.props.indent + 20 > limitWidth) {
11322
+ p.props.indent = limitWidth - 20;
11323
+ }
11324
+ if (p.props.hanging > 0 && p.props.hanging + 20 > limitWidth) {
11325
+ p.props.hanging = limitWidth - 20;
11326
+ }
11327
+ }
11316
11328
  /**
11317
11329
  * 获取段落行布局横向坐标起始位置,被段落text-align影响
11318
11330
  */
@@ -17149,6 +17161,10 @@ var ModifyFlag;
17149
17161
  class NodeCore {
17150
17162
  enableClip = true;
17151
17163
  pointEvent = true;
17164
+ allowHitTest = false;
17165
+ hitTest(hitPos, currPos) {
17166
+ return false;
17167
+ }
17152
17168
  get enable() {
17153
17169
  return this._enable;
17154
17170
  }
@@ -17478,6 +17494,9 @@ class NodeItems extends NodeCore {
17478
17494
  eventMap = new WeakMap();
17479
17495
  absoluteItems = false;
17480
17496
  containerPropName;
17497
+ constructor() {
17498
+ super();
17499
+ }
17481
17500
  addChild(control, index = -1) {
17482
17501
  if (this.containerPropName) {
17483
17502
  this[this.containerPropName].addChild(control, index);
@@ -17549,6 +17568,33 @@ class NodeItems extends NodeCore {
17549
17568
  return this.controls.length;
17550
17569
  }
17551
17570
  }
17571
+ /**
17572
+ * 子内容采用绝对定位的容器
17573
+ */
17574
+ class AbsolutePanel extends NodeItems {
17575
+ constructor() {
17576
+ super();
17577
+ this.absoluteItems = true;
17578
+ }
17579
+ measureOverride(e, availableSize) {
17580
+ this.controls.forEach(item => {
17581
+ item.measure(e, availableSize);
17582
+ });
17583
+ return super.measureOverride(e, availableSize);
17584
+ }
17585
+ arrangeOverride(e, finalSize) {
17586
+ this.controls.forEach(item => {
17587
+ const itemRect = {
17588
+ x: item.x,
17589
+ y: item.y,
17590
+ width: item.desiredSize.width,
17591
+ height: item.desiredSize.height
17592
+ };
17593
+ item.arrange(e, itemRect);
17594
+ });
17595
+ return super.arrangeOverride(e, finalSize);
17596
+ }
17597
+ }
17552
17598
  let currentActiveAppContext = null;
17553
17599
  function getCurrentActiveAppContext() {
17554
17600
  return currentActiveAppContext;
@@ -17666,7 +17712,7 @@ function drawBorderline(node, renderCtx) {
17666
17712
  if (!node.border) {
17667
17713
  return;
17668
17714
  }
17669
- let { x, y, finalRect: { width, height } } = node;
17715
+ let { finalRect: { x, y, width, height } } = node;
17670
17716
  const ctx = renderCtx.ctx;
17671
17717
  ctx.save();
17672
17718
  ctx.fillStyle = node.borderColor;
@@ -18230,7 +18276,7 @@ class NodeEvent {
18230
18276
  };
18231
18277
  mouseleaveRenders.forEach(item => {
18232
18278
  onMouseoutEvent.target = item;
18233
- invokeEvent(onMouseoutEvent, 'mouseleave', item, false);
18279
+ invokeEvent(onMouseoutEvent, 'mouseout', item, false);
18234
18280
  });
18235
18281
  const onMouseoverEvent = {
18236
18282
  pos: this.appState.pos,
@@ -18396,7 +18442,8 @@ class NodeEvent {
18396
18442
  width: width,
18397
18443
  height: height
18398
18444
  };
18399
- if (isInsideRectByPosition(currRect, hitPos)) {
18445
+ const hitTest = node.allowHitTest ? node.hitTest(hitPos, currRect) : isInsideRectByPosition(currRect, hitPos);
18446
+ if (hitTest) {
18400
18447
  //有边框和内边距,所以在计算子节点的时候,需要考虑
18401
18448
  const innerPos = {
18402
18449
  x: currRect.x + node.border + node.padding,
@@ -18558,6 +18605,13 @@ class ViewPaint {
18558
18605
  this.drawHoriLine(x, y, width, textProps.color, 1);
18559
18606
  }
18560
18607
  }
18608
+ drawText2(text, textProps, x, y) {
18609
+ this.ctx.save();
18610
+ this.ctx.fillStyle = textProps.color;
18611
+ this.ctx.font = `${textProps.fontSize}px ${textProps.fontName}`;
18612
+ this.ctx.fillText(text, x, y + textProps.fontSize / 7);
18613
+ this.ctx.restore();
18614
+ }
18561
18615
  fillCircular(x, y, r, color = 'black') {
18562
18616
  this.ctx.save();
18563
18617
  this.ctx.beginPath();
@@ -18572,6 +18626,10 @@ class ViewPaint {
18572
18626
  const textMeasure = this.ctx.measureText(text);
18573
18627
  return { width: textMeasure.width, height: textProps.fontSize };
18574
18628
  }
18629
+ measureText2(text, font) {
18630
+ this.ctx.font = font.fontSize + 'px ' + font.fontName;
18631
+ return this.ctx.measureText(text).width;
18632
+ }
18575
18633
  measureTextUnits(units, textProps) {
18576
18634
  this.ctx.font = textProps.getFont();
18577
18635
  const letterSpace = textProps.letterSpace ?? 0;
@@ -18988,6 +19046,11 @@ class SurfaceView extends NodeItems {
18988
19046
  * 如果有默认宽度限制,而且支持换行显示,则内容高度等于多行累计高度
18989
19047
  */
18990
19048
  class LabelNode extends TextBase {
19049
+ constructor() {
19050
+ super();
19051
+ this.border = 1;
19052
+ this.borderColor = '#000';
19053
+ }
18991
19054
  _textWrapping = 'no';
18992
19055
  get textWrapping() {
18993
19056
  return this._textWrapping;
@@ -18997,34 +19060,54 @@ class LabelNode extends TextBase {
18997
19060
  this._textWrapping = value;
18998
19061
  }
18999
19062
  cacheTextRect;
19000
- textUnits;
19063
+ //private textUnits!: Array<TextUnits>;
19064
+ lines = [];
19001
19065
  measureOverride(e, availableSize) {
19002
- const textProps = this.getTextProps();
19003
- this.textUnits = this.text.split('').map(char => ({ char, actualSize: 0, sourceSize: 0 }));
19004
- e.render.measureTextUnits(this.textUnits, textProps);
19066
+ this.getTextProps();
19067
+ this.lines = this.getMuiltLines(this.text, e);
19068
+ // this.textUnits = this.text.split('').map<TextUnits>(char => ({char, actualSize: 0, sourceSize: 0}));
19069
+ // e.render.measureTextUnits(this.textUnits, textProps);
19005
19070
  //没有宽度限制,测量横向排列的尺寸大小,此时不需要考虑换行
19006
- if (Number.isNaN(this._width)) {
19007
- return {
19008
- width: this.textUnits.reduce((prev, curr) => {
19009
- return prev + curr.sourceSize;
19010
- }, 0), height: this.fontSize
19011
- };
19012
- }
19013
- if (this._textWrapping === 'no') {
19014
- return { width: this.getPercentWidth(availableSize.width), height: this.fontSize };
19015
- }
19016
- return this.measureTextRect(this.textUnits, {
19071
+ // if (Number.isNaN(this._width)) {
19072
+ // // return {
19073
+ // // width: this.lines[0].textUnits.reduce((prev, curr) => {
19074
+ // // return prev + curr.sourceSize
19075
+ // // }, 0), height: this.fontSize
19076
+ // // };
19077
+ // return this.measureTextRect(this.lines, {
19078
+ // width: availableSize.width,
19079
+ // height: this.getPercentHeight(availableSize.height)
19080
+ // });
19081
+ // }
19082
+ // if (this._textWrapping === 'no') {
19083
+ // return {width: this.getPercentWidth(availableSize.width), height: this.fontSize};
19084
+ // }
19085
+ return this.measureTextRect(this.lines, {
19017
19086
  width: availableSize.width,
19018
19087
  height: this.getPercentHeight(availableSize.height)
19019
19088
  });
19020
19089
  }
19021
- arrangeOverride(e, finalSize) {
19022
- if (!Number.isNaN(this._width) && this._textWrapping === 'wrap') {
19023
- this.measureTextRect(this.textUnits, {
19024
- width: finalSize.width,
19025
- height: finalSize.height
19026
- });
19090
+ getMuiltLines(text, e) {
19091
+ const lineRects = [];
19092
+ const lines = this.text.split('\r\n');
19093
+ for (let i = 0; i < lines.length; i++) {
19094
+ const units = lines[i].split('').map(char => ({ char, actualSize: 0, sourceSize: 0 }));
19095
+ e.render.measureTextUnits(units, this.getTextProps());
19096
+ lineRects.push({ textUnits: units });
19027
19097
  }
19098
+ return lineRects;
19099
+ }
19100
+ arrangeOverride(e, finalSize) {
19101
+ // if (!Number.isNaN(this._width) && this._textWrapping === 'wrap') {
19102
+ // this.measureTextRect(this.lines, {
19103
+ // width: finalSize.width,
19104
+ // height: finalSize.height
19105
+ // });
19106
+ // }
19107
+ this.measureTextRect(this.lines, {
19108
+ width: finalSize.width,
19109
+ height: finalSize.height
19110
+ });
19028
19111
  return super.arrangeOverride(e, finalSize);
19029
19112
  }
19030
19113
  getTextProps() {
@@ -19034,54 +19117,56 @@ class LabelNode extends TextBase {
19034
19117
  textProps.color = this.color ?? '#000';
19035
19118
  return textProps;
19036
19119
  }
19037
- measureTextRect(textUnits, availableSize, final = false) {
19038
- const sumWidth = textUnits.reduce((prev, curr) => {
19039
- return curr.sourceSize + prev;
19040
- }, 0);
19120
+ measureTextRect(lines, availableSize, final = false) {
19041
19121
  //总宽度大于可用宽度,换行计算
19042
19122
  const cacheLines = [];
19043
19123
  const { width: limitWidth, height: limitHeight } = availableSize;
19044
- let line = { lineUnits: [], x: 0, y: 0, width: 0, height: 0 };
19045
- cacheLines.push(line);
19046
- for (let i = 0; i < textUnits.length; i++) {
19047
- const unit = textUnits[i];
19048
- //至少每行一个字符
19049
- if (line.lineUnits.length > 0 && line.width + unit.sourceSize > limitWidth) {
19050
- line = { lineUnits: [], x: 0, y: 0, width: 0, height: 0 };
19051
- cacheLines.push(line);
19052
- }
19053
- line.lineUnits.push(unit);
19054
- line.width += unit.sourceSize;
19055
- line.height = this.fontSize;
19124
+ for (let i = 0; i < lines.length; i++) {
19125
+ const lineText = lines[i];
19126
+ let line = { lineUnits: [], x: 0, y: 0, width: 0, height: 0 };
19127
+ cacheLines.push(line);
19128
+ for (let j = 0; j < lineText.textUnits.length; j++) {
19129
+ const unit = lineText.textUnits[j];
19130
+ //至少每行一个字符
19131
+ if (line.lineUnits.length > 0 && line.width + unit.sourceSize > limitWidth) {
19132
+ line = { lineUnits: [], x: 0, y: 0, width: 0, height: 0 };
19133
+ cacheLines.push(line);
19134
+ }
19135
+ line.lineUnits.push(unit);
19136
+ line.width += unit.sourceSize;
19137
+ line.height = this.fontSize;
19138
+ }
19056
19139
  }
19057
19140
  let contentHeight = 0;
19141
+ let maxLineWidth = 0;
19058
19142
  cacheLines.forEach(line => {
19059
19143
  line.y = contentHeight;
19060
19144
  contentHeight += line.height;
19145
+ maxLineWidth = Math.max(line.width, maxLineWidth);
19061
19146
  });
19062
19147
  //期望高度
19063
19148
  let desiredHeight = final ? limitHeight : contentHeight;
19064
19149
  this.cacheTextRect = {
19065
19150
  lines: cacheLines,
19066
- width: sumWidth,
19151
+ width: maxLineWidth,
19067
19152
  height: contentHeight,
19068
19153
  desiredHeight,
19069
19154
  desiredWidth: limitWidth
19070
19155
  };
19071
19156
  return {
19072
- width: limitWidth,
19157
+ width: maxLineWidth,
19073
19158
  height: desiredHeight
19074
19159
  };
19075
19160
  }
19076
19161
  render(e) {
19077
- const textProp = new TextProps();
19078
- textProp.fontName = this.fontName;
19079
- textProp.fontSize = this.fontSize;
19080
- textProp.color = this.color;
19081
- if (this.textWrapping === 'no' || Number.isNaN(this._width)) {
19082
- e.render.drawText(this.text, textProp, 0, 0, this.finalRect.width, textProp.fontSize);
19083
- return;
19084
- }
19162
+ // const textProp = new TextProps();
19163
+ // textProp.fontName = this.fontName;
19164
+ // textProp.fontSize = this.fontSize;
19165
+ // textProp.color = this.color;
19166
+ // if (this.textWrapping === 'no' || Number.isNaN(this._width)) {
19167
+ // e.render.drawText(this.text, textProp, 0, 0, this.finalRect.width, textProp.fontSize);
19168
+ // return;
19169
+ // }
19085
19170
  for (let i = 0; i < this.cacheTextRect.lines.length; i++) {
19086
19171
  const line = this.cacheTextRect.lines[i];
19087
19172
  this.drawLine(e, line);
@@ -19097,7 +19182,7 @@ class LabelNode extends TextBase {
19097
19182
  render.tran(() => {
19098
19183
  const textProps = this.getTextProps();
19099
19184
  render.ctx.font = textProps.getFont();
19100
- render.drawText(line.lineUnits.join(''), textProps, 0, line.y, line.width, line.height);
19185
+ render.drawText(line.lineUnits.map(item => item.char).join(''), textProps, 0, line.y, line.width, line.height);
19101
19186
  });
19102
19187
  }
19103
19188
  }
@@ -19347,8 +19432,8 @@ class ScrollView extends NodeItems {
19347
19432
  });
19348
19433
  this.addEventListener('wheel', evt => {
19349
19434
  const { deltaY, deltaX } = evt;
19350
- this.horBar.updateScrollByCurrent(deltaX / 10, deltaY / 10);
19351
- this.verBar.updateScrollByCurrent(deltaX / 10, deltaY / 10);
19435
+ this.horBar.updateScrollByCurrent(deltaX, deltaY);
19436
+ this.verBar.updateScrollByCurrent(deltaX, deltaY);
19352
19437
  });
19353
19438
  }
19354
19439
  scrollTo(x, y) {
@@ -20067,7 +20152,7 @@ function pointInPoly(pt, poly) {
20067
20152
  * 1.在单页模式下,文档最小宽度为单个文档宽度+合适的外边距
20068
20153
  * 2.在多页模式下,文档最小宽度为单个文档宽度+合适的外边距
20069
20154
  */
20070
- class CanvasTextEditor extends NodeItems {
20155
+ class CanvasTextEditor extends AbsolutePanel {
20071
20156
  editCanvas;
20072
20157
  editInput;
20073
20158
  contentCtx;
@@ -20994,6 +21079,13 @@ class CanvasTextEditor extends NodeItems {
20994
21079
  const win = new Window();
20995
21080
  win.width = 1000;
20996
21081
  win.height = 800;
21082
+ //win.content.addChild(timelineScrollbar)
21083
+ const rule2 = new RuleControl(this.docCtx);
21084
+ this.rule = rule2;
21085
+ rule2.width = 700;
21086
+ rule2.height = 30;
21087
+ rule2.x = 20;
21088
+ rule2.y = 500;
20997
21089
  const surface = new SurfaceView(this.editCanvas, this.editInput);
20998
21090
  this.surfaceView = surface;
20999
21091
  surface.width = 1000;
@@ -21005,12 +21097,6 @@ class CanvasTextEditor extends NodeItems {
21005
21097
  this.resetViewer();
21006
21098
  });
21007
21099
  surface.addChild(scrollView);
21008
- const rule2 = new RuleControl(this.docCtx);
21009
- this.rule = rule2;
21010
- rule2.width = 700;
21011
- rule2.height = 30;
21012
- rule2.x = 20;
21013
- rule2.y = 500;
21014
21100
  surface.addChild(rule2);
21015
21101
  //surface.addChild(win);
21016
21102
  surface.start();
@@ -21085,24 +21171,6 @@ class CanvasTextEditor extends NodeItems {
21085
21171
  appCtx.root.setInputPosition(caretPos);
21086
21172
  }
21087
21173
  }
21088
- measureOverride(e, availableSize) {
21089
- this.controls.forEach(item => {
21090
- item.measure(e, availableSize);
21091
- });
21092
- return super.measureOverride(e, availableSize);
21093
- }
21094
- arrangeOverride(e, finalSize) {
21095
- this.controls.forEach(item => {
21096
- const itemRect = {
21097
- x: item.x,
21098
- y: item.y,
21099
- width: item.desiredSize.width,
21100
- height: item.desiredSize.height
21101
- };
21102
- item.arrange(e, itemRect);
21103
- });
21104
- return super.arrangeOverride(e, finalSize);
21105
- }
21106
21174
  }
21107
21175
 
21108
21176
  /**