@gedit/editor-2d 0.1.115 → 0.2.0

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 (100) hide show
  1. package/lib/browser/editor2d-context-key-service.js.map +1 -1
  2. package/lib/browser/editor2d-contribution.js.map +1 -1
  3. package/lib/browser/editor2d-label-provider.js.map +1 -1
  4. package/lib/browser/editor2d-model-provider.js.map +1 -1
  5. package/lib/browser/editor2d-ref-provider-contribution.d.ts +1 -1
  6. package/lib/browser/editor2d-ref-provider-contribution.d.ts.map +1 -1
  7. package/lib/browser/editor2d-ref-provider-contribution.js +8 -8
  8. package/lib/browser/editor2d-ref-provider-contribution.js.map +1 -1
  9. package/lib/browser/editor2d-service.js.map +1 -1
  10. package/lib/browser/model/editor2d-document.d.ts +45 -19
  11. package/lib/browser/model/editor2d-document.d.ts.map +1 -1
  12. package/lib/browser/model/editor2d-document.js +291 -70
  13. package/lib/browser/model/editor2d-document.js.map +1 -1
  14. package/lib/browser/model/editor2d-model.js.map +1 -1
  15. package/lib/browser/model/editor2d-selection.js.map +1 -1
  16. package/lib/browser/model/editor2d-widget.js.map +1 -1
  17. package/lib/browser/model/editor2d.d.ts +8 -4
  18. package/lib/browser/model/editor2d.d.ts.map +1 -1
  19. package/lib/browser/model/editor2d.js +23 -4
  20. package/lib/browser/model/editor2d.js.map +1 -1
  21. package/lib/browser/model/utils/anim.utils.d.ts +3 -0
  22. package/lib/browser/model/utils/anim.utils.d.ts.map +1 -1
  23. package/lib/browser/model/utils/anim.utils.js +10 -4
  24. package/lib/browser/model/utils/anim.utils.js.map +1 -1
  25. package/lib/browser/playground/canvas-draw.d.ts +8 -0
  26. package/lib/browser/playground/canvas-draw.d.ts.map +1 -1
  27. package/lib/browser/playground/canvas-draw.js +29 -15
  28. package/lib/browser/playground/canvas-draw.js.map +1 -1
  29. package/lib/browser/playground/canvas-layer.d.ts +10 -2
  30. package/lib/browser/playground/canvas-layer.d.ts.map +1 -1
  31. package/lib/browser/playground/canvas-layer.js +25 -2
  32. package/lib/browser/playground/canvas-layer.js.map +1 -1
  33. package/lib/browser/playground/entities/extend-entity.d.ts +10 -0
  34. package/lib/browser/playground/entities/extend-entity.d.ts.map +1 -0
  35. package/lib/browser/playground/entities/extend-entity.js +34 -0
  36. package/lib/browser/playground/entities/extend-entity.js.map +1 -0
  37. package/lib/browser/playground/entities/index.d.ts +1 -0
  38. package/lib/browser/playground/entities/index.d.ts.map +1 -1
  39. package/lib/browser/playground/entities/index.js +1 -0
  40. package/lib/browser/playground/entities/index.js.map +1 -1
  41. package/lib/browser/playground/extend-edit-layer-point-event.d.ts +30 -0
  42. package/lib/browser/playground/extend-edit-layer-point-event.d.ts.map +1 -0
  43. package/lib/browser/playground/extend-edit-layer-point-event.js +50 -0
  44. package/lib/browser/playground/extend-edit-layer-point-event.js.map +1 -0
  45. package/lib/browser/playground/extend-edit-layer.d.ts +38 -0
  46. package/lib/browser/playground/extend-edit-layer.d.ts.map +1 -0
  47. package/lib/browser/playground/extend-edit-layer.js +335 -0
  48. package/lib/browser/playground/extend-edit-layer.js.map +1 -0
  49. package/lib/browser/playground/index.d.ts +1 -0
  50. package/lib/browser/playground/index.d.ts.map +1 -1
  51. package/lib/browser/playground/index.js +1 -0
  52. package/lib/browser/playground/index.js.map +1 -1
  53. package/lib/browser/playground/path-edit-layer-move-point.d.ts +15 -0
  54. package/lib/browser/playground/path-edit-layer-move-point.d.ts.map +1 -0
  55. package/lib/browser/playground/path-edit-layer-move-point.js +47 -0
  56. package/lib/browser/playground/path-edit-layer-move-point.js.map +1 -0
  57. package/lib/browser/playground/path-edit-layer-svg-path.d.ts +11 -0
  58. package/lib/browser/playground/path-edit-layer-svg-path.d.ts.map +1 -0
  59. package/lib/browser/playground/path-edit-layer-svg-path.js +21 -0
  60. package/lib/browser/playground/path-edit-layer-svg-path.js.map +1 -0
  61. package/lib/browser/playground/path-edit-layer.d.ts +36 -0
  62. package/lib/browser/playground/path-edit-layer.d.ts.map +1 -0
  63. package/lib/browser/playground/path-edit-layer.js +257 -0
  64. package/lib/browser/playground/path-edit-layer.js.map +1 -0
  65. package/lib/browser/playground/playground-context.js.map +1 -1
  66. package/lib/browser/playground/playground-contribution.d.ts +2 -0
  67. package/lib/browser/playground/playground-contribution.d.ts.map +1 -1
  68. package/lib/browser/playground/playground-contribution.js +40 -3
  69. package/lib/browser/playground/playground-contribution.js.map +1 -1
  70. package/lib/browser/utils/snapshot.d.ts.map +1 -1
  71. package/lib/browser/utils/snapshot.js +1 -1
  72. package/lib/browser/utils/snapshot.js.map +1 -1
  73. package/package.json +9 -7
  74. package/src/browser/editor2d-ref-provider-contribution.ts +8 -8
  75. package/src/browser/model/editor2d-document.ts +278 -49
  76. package/src/browser/model/editor2d.ts +21 -5
  77. package/src/browser/model/utils/anim.utils.ts +9 -2
  78. package/src/browser/playground/canvas-draw.ts +31 -17
  79. package/src/browser/playground/canvas-layer.ts +25 -3
  80. package/src/browser/playground/entities/extend-entity.ts +37 -0
  81. package/src/browser/playground/entities/index.ts +1 -0
  82. package/src/browser/playground/extend-edit-layer-point-event.tsx +71 -0
  83. package/src/browser/playground/extend-edit-layer.tsx +442 -0
  84. package/src/browser/playground/index.ts +1 -0
  85. package/src/browser/playground/path-edit-layer-move-point.tsx +71 -0
  86. package/src/browser/playground/path-edit-layer-svg-path.tsx +50 -0
  87. package/src/browser/playground/path-edit-layer.tsx +330 -0
  88. package/src/browser/playground/playground-contribution.ts +37 -3
  89. package/src/browser/style/canvas-layer.css +16 -0
  90. package/src/browser/style/extend-edit-layer.less +127 -0
  91. package/src/browser/style/index.less +2 -1
  92. package/src/browser/style/path-edit-layer.less +72 -0
  93. package/src/browser/svg/pen+.svg +24 -0
  94. package/src/browser/utils/snapshot.ts +1 -0
  95. package/lib/browser/playground/canvas-draw-layer.d.ts +0 -22
  96. package/lib/browser/playground/canvas-draw-layer.d.ts.map +0 -1
  97. package/lib/browser/playground/canvas-draw-layer.js +0 -102
  98. package/lib/browser/playground/canvas-draw-layer.js.map +0 -1
  99. package/src/browser/playground/canvas-draw-layer.tsx +0 -88
  100. package/src/browser/style/canvas-draw-layer.less +0 -24
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gedit/editor-2d",
3
- "version": "0.1.115",
3
+ "version": "0.2.0",
4
4
  "license": "MIT",
5
5
  "main": "lib/browser/index",
6
6
  "typings": "lib/browser/index.d.ts",
@@ -9,11 +9,13 @@
9
9
  "src"
10
10
  ],
11
11
  "dependencies": {
12
- "@gedit/app-config": "^0.1.110",
13
- "@gedit/editor": "^0.1.83",
14
- "@gedit/playground": "^0.1.92",
15
- "@gedit/render-engine-ide": "^0.1.114",
16
- "@gedit/workspace-2d": "^0.1.89",
12
+ "@gedit/app-config": "^0.2.0",
13
+ "@gedit/editor": "^0.2.0",
14
+ "@gedit/playground": "^0.2.0",
15
+ "@gedit/render-engine-ide": "^0.2.0",
16
+ "@gedit/workspace-2d": "^0.2.0",
17
+ "bezier-js": "^4.0.3",
18
+ "clsx": "^1.1.1",
17
19
  "json-stringify-pretty-compact": "^2.0.0",
18
20
  "nanoid": "^3.3.2"
19
21
  },
@@ -35,5 +37,5 @@
35
37
  "nyc": {
36
38
  "extends": "../../configs/nyc.json"
37
39
  },
38
- "gitHead": "8bdf36b3a3898da871ec15be92760865fc6a182a"
40
+ "gitHead": "cc40d9ce45193e6f024f79a94b5d0518325bf3ff"
39
41
  }
@@ -3,6 +3,7 @@ import { ResourceRefError, ResourceRefInfo, ResourceRefProviderContribution } fr
3
3
  import { Editor2dDocument, Editor2dIterator, Editor2dNode } from './model';
4
4
  import { RenderEngineIDEService } from '@gedit/render-engine-ide';
5
5
  import { URI, arrayUnion } from '@gedit/utils';
6
+ import { GameResource } from '@gedit/render-engine/lib/common/game-resource';
6
7
 
7
8
  /**
8
9
  * 分析资源依赖
@@ -27,19 +28,18 @@ export class Editor2dRefProviderContribution implements ResourceRefProviderContr
27
28
  return errors;
28
29
  }
29
30
 
30
- getTextureIdRef(node: Editor2dNode): string | undefined {
31
- if (node.textureId && !node.textureId.match(/^http/)) {
32
- return `gedit/assets/${node.textureId}`;
33
- }
31
+ getTextureIdRefs(node: Editor2dNode): string[] {
32
+ const textureIds = GameResource.toTextureIdList(node.textureId);
33
+ return textureIds.map(s => s.match(/^http/) ? '' : `gedit/assets/${s}`).filter(s => s);
34
34
  }
35
35
  async getRefInfo(uri: string, document: Editor2dDocument): Promise<ResourceRefInfo> {
36
36
  const dependencies: string[] = [];
37
37
  for (const node of new Editor2dIterator(document.root!)) {
38
38
  const register = this.renderEngineService.getGameObjectIDERegister(document.engineName, node.displayType);
39
- const textureRef = this.getTextureIdRef(node);
40
- if (textureRef) {
41
- dependencies.push(textureRef);
42
- }
39
+ const textureRefs = this.getTextureIdRefs(node);
40
+ textureRefs.forEach(r => {
41
+ dependencies.push(r);
42
+ });
43
43
  if (register.getReferenceUris) {
44
44
  const newUris = register.getReferenceUris(node);
45
45
  newUris.forEach((u: string) => {
@@ -1,4 +1,4 @@
1
- import { inject, injectable } from 'inversify';
1
+ import { inject, injectable, optional } from 'inversify';
2
2
  import { EditorDocument, EditorDocumentChangeEvent } from '@gedit/editor';
3
3
  import {
4
4
  Compare,
@@ -6,9 +6,9 @@ import {
6
6
  Disposable,
7
7
  Emitter,
8
8
  Event,
9
- mapValues,
10
9
  MaybePromise,
11
10
  omit,
11
+ debounce,
12
12
  PromiseDeferred,
13
13
  URI,
14
14
  } from '@gedit/utils';
@@ -18,6 +18,7 @@ import {
18
18
  Editor2dContent,
19
19
  Editor2dModelOptions,
20
20
  Editor2dNode,
21
+ // Editor2dNodeCache,
21
22
  } from './editor2d';
22
23
  import { GameObject, GameObjectBaseType, GameObjectType } from '@gedit/render-engine';
23
24
  import { GameObjectDecoration, RenderEngineIDEService } from '@gedit/render-engine-ide';
@@ -29,10 +30,35 @@ import { WorkspaceResourceService } from '@gedit/workspace-2d';
29
30
  import { ResourceProvider, ResourceRefError } from '@gedit/resource';
30
31
  import { AppConfigService } from '@gedit/app-config';
31
32
  import { Editor2dIterator } from './editor2d-iterator';
32
- import { getAnimationKeys, getChangeAnimationData } from './utils';
33
+ // import { getAnimationKeys, getChangeAnimationData } from './utils';
34
+
35
+ export const maskShowArray: GameObjectType[] = [
36
+ GameObjectBaseType.IMAGE,
37
+ GameObjectBaseType.RECTANGLE,
38
+ GameObjectBaseType.PATH,
39
+ GameObjectBaseType.CIRCLE,
40
+ GameObjectBaseType.POLYGON,
41
+ GameObjectBaseType.TEXT,
42
+ GameObjectBaseType.TRIANGLE,
43
+ ];
44
+ export const maskEnabledArray: GameObjectType[] = [
45
+ GameObjectBaseType.GROUP,
46
+ GameObjectBaseType.PARTICLES,
47
+ ];
33
48
 
34
49
  let versionId = 0;
35
50
 
51
+ export const Editor2dComponentProvider = Symbol('Editor2dComponentProvider');
52
+
53
+ /**
54
+ * 组件内容修改后触发
55
+ */
56
+ export interface Editor2dComponentProvider {
57
+ getComponentContent(compPath: string, parentNode: Editor2dNode): Editor2dNode[] | undefined;
58
+ onComponentChanged: Event<URI>;
59
+ onLoad: Event<void>;
60
+ }
61
+
36
62
  @injectable()
37
63
  export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNode> implements Tree<Editor2dNode, Editor2dContainerNode>, EditorDocument {
38
64
  readonly type: 'Editor2dTree';
@@ -45,7 +71,7 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
45
71
  private _localVersion: number = 0;
46
72
  private _saveVersion: number = 0;
47
73
  protected errors: ResourceRefError[] = [];
48
- protected componentContents: { [key: string]: Editor2dNode } = {};
74
+ // protected componentContents: { [key: string]: Editor2dNode } = {};
49
75
  protected _snaplines: any[] = [];
50
76
  public loading = true;
51
77
 
@@ -59,11 +85,12 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
59
85
  constructor(
60
86
  @inject(MessageService) protected readonly message: MessageService,
61
87
  @inject(Editor2dModelOptions) protected readonly options: Editor2dModelOptions,
62
- @inject(ResourceProvider) protected readonly resourceProivder: ResourceProvider,
88
+ @inject(ResourceProvider) protected readonly resourceProvider: ResourceProvider,
63
89
  @inject(ResourceAutoSaveService) protected readonly resourceAutoSaveService: ResourceAutoSaveService,
64
90
  @inject(WorkspaceResourceService) protected readonly resourceService: WorkspaceResourceService,
65
91
  @inject(RenderEngineIDEService) readonly engineService: RenderEngineIDEService,
66
92
  @inject(AppConfigService) readonly appConfig: AppConfigService,
93
+ @inject(Editor2dComponentProvider) @optional() readonly componentProvider?: Editor2dComponentProvider,
67
94
  ) {
68
95
  super();
69
96
  this.toDispose.push(this.onContentChangedEmitter);
@@ -72,6 +99,21 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
72
99
  // this.toDispose.push(this.resourceAutoSaveService);
73
100
  this.toDispose.push(this.resourceAutoSaveService.onSyncContent(content => this.reloadContent(content || '')));
74
101
  this.toDispose.push(this.onSaved(event => this.resourceAutoSaveService.fireDidChangeContent(event)));
102
+ // 组件数据加载
103
+ if (this.componentProvider) {
104
+ this.toDispose.push(this.componentProvider.onLoad(() => {
105
+ this.fireContentChanged([], 'update', true);
106
+ }));
107
+ // 组件数据更新
108
+ this.toDispose.push(this.componentProvider.onComponentChanged(debounce((compUri: URI) => {
109
+ if (this.uri === compUri.toString()) {
110
+ return;
111
+ }
112
+ if (this.hasIncludesComponent(compUri)) {
113
+ this.fireContentChanged([], 'update', true);
114
+ }
115
+ }, 1000)));
116
+ }
75
117
  // TODO
76
118
  // this.toDispose.push(this.resourceService.onRefsChange(async () => {
77
119
  // await this.loadRefInfos();
@@ -79,25 +121,37 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
79
121
  // 同步数据
80
122
  this.resourceAutoSaveService.sync();
81
123
  }
124
+ protected hasIncludesComponent(compUri: URI): boolean {
125
+ if (!this.root) return false;
126
+ for (const node of new Editor2dIterator(this.root)) {
127
+ if (node !== this.root
128
+ && node.displayType === GameObjectBaseType.COMPONENT
129
+ && new URI((node as any).component?.id).displayName === compUri.displayName
130
+ ) {
131
+ return true;
132
+ }
133
+ }
134
+ return false;
135
+ }
82
136
 
83
137
  /**
84
138
  * 切换资源, 只有模板编辑器需要用到
85
139
  */
86
140
  async changeResource(uri: string): Promise<void> {
87
141
  const uriObj = new URI(uri);
88
- const resource = await this.resourceProivder(uriObj);
142
+ const resource = await this.resourceProvider(uriObj);
89
143
  this.resourceAutoSaveService.changeResource(resource);
90
144
  this.resourceAutoSaveService.sync();
91
145
  }
92
146
 
93
- /**
94
- * 获取依赖的组件的内容
95
- * @param compPath
96
- * @param parentNode
97
- */
147
+ // /**
148
+ // * 获取依赖的组件的内容
149
+ // * @param compPath
150
+ // * @param parentNode
151
+ // */
98
152
  getComponentContent(compPath: string, parentNode: Editor2dNode): Editor2dNode[] | undefined {
99
- const comp = this.componentContents[compPath];
100
- if (comp && comp.children) return comp.children.map(c => ({...c, parent: parentNode})) as Editor2dNode[];
153
+ if (!this.componentProvider) return undefined;
154
+ return this.componentProvider.getComponentContent(compPath, parentNode);
101
155
  }
102
156
 
103
157
  createDisplayNode<E extends Editor2dNode = Editor2dNode>(
@@ -203,6 +257,7 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
203
257
  this.updateNode(targetNode, { name });
204
258
  }
205
259
  addChildren(node: Editor2dNode, parentNode: Editor2dContainerNode, index: number = 0): void {
260
+ this.clearMask(node);
206
261
  if (node.parent) {
207
262
  this.delNode(node, true);
208
263
  };
@@ -210,6 +265,7 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
210
265
  parentNode.children.splice(index, 0, node);
211
266
  CompositeTreeNode.setParent(node, index, parentNode);
212
267
  (parentNode as ExpandableTreeNode).expanded = true;
268
+ this.nextMaskToNode(node);
213
269
  this.refresh(parentNode);
214
270
  this.fireContentChanged([node], node.parent ? 'update' : 'add');
215
271
  }
@@ -302,7 +358,7 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
302
358
  this._snaplines = data.snaplines;
303
359
  }
304
360
  this.refresh();
305
- this.loadRefInfos();
361
+ // this.loadRefInfos();
306
362
  this.fireContentChanged([], 'add', true);
307
363
  }
308
364
  reloadEnd(): void {
@@ -345,6 +401,173 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
345
401
  get onDirtyChanged(): Event<void> {
346
402
  return this.resourceAutoSaveService.onDirtyChanged;
347
403
  }
404
+ /**
405
+ * @mask 操作说明
406
+ * 1. 当前 isMask 为 true, 移除 prevNode 上的 mask, 移到相应的图层后再设。
407
+ * 2. 当前 isMask 为 true 且 mask 有值,只清除 mask;
408
+ * 3. 当前是 mask child,先移除 mask, 拖到指定后再判断下一个是否 mask, 再附值;
409
+ * 4. 当前不是 mask, 移到 mask 树下,,设定下一个 node 上的 mask, 如果下一个 node 是 mask, 直接附值 id;
410
+ */
411
+ protected clearMask(node: Editor2dNode): void {
412
+ // 只 mask 状态时, 移除 prevNode 上的 mask;
413
+ if (node.isMask && !node.mask) {
414
+ this.setPrevNodeMask(node.previousSibling);
415
+ }
416
+ // 当前忽略底层 mask 的,恢复上面的 mask;
417
+ if (node.mask && node.ignoreMask) {
418
+ this.setPrevNodeMask(node.previousSibling, node.mask);
419
+ }
420
+ if (node.mask) {
421
+ // 移除 mask;
422
+ node.mask = undefined;
423
+ }
424
+ }
425
+ protected nextMaskToNode(node: Editor2dNode): void {
426
+ // 判断父级是否 mask 或 maskChild, 如果是则不用设
427
+ const nextNode = node.nextSibling as Editor2dNode;
428
+ const nextIsMask = nextNode && (nextNode.isMask || nextNode.mask);
429
+ // 如果底下有 mask;
430
+ if (nextIsMask) {
431
+ node.mask = nextNode.mask || nextNode.id;
432
+ // 底层忽略 mask 又是 mask 的情况,用底层的 id;
433
+ if (nextNode.ignoreMask && nextNode.isMask) {
434
+ node.mask = nextNode.id;
435
+ }
436
+ // 忽略 mask, 清除上一层的 mask;
437
+ if (node.ignoreMask) {
438
+ this.setPrevNodeMask(node.previousSibling);
439
+ }
440
+ //
441
+ // this.fireContentChanged([node], 'update', false, true);
442
+ } else if (node.isMask) {
443
+ // 不是 mask,且当前是 mask, 设定上一层为 mask child;
444
+ this.setPrevNodeMask(node.previousSibling, node.id);
445
+ }
446
+ }
447
+
448
+ protected setPrevNodeMask(node?: TreeNode, id?: string): void {
449
+ if (!node) {
450
+ return;
451
+ }
452
+ const n = node as Editor2dNode;
453
+ // 跳出不是 mask 实列
454
+ if (!maskShowArray.concat(maskEnabledArray).includes(n.displayType)) {
455
+ return;
456
+ }
457
+ // this.updateNode(n, { mask: id });
458
+ if (id !== n.mask) {
459
+ // n.version = (n.version || 0) + 1;
460
+ n.mask = id;
461
+ // this.updateNode(n, { mask: id }, true);
462
+ // this.fireContentChanged([n], 'update');
463
+ }
464
+ /**
465
+ * 断掉蒙板条件
466
+ * 1. 上一个忽略蒙板
467
+ * 2. 上一个类型不是图形或图片
468
+ * 3. 当前是蒙板,且 id 为 undefined
469
+ */
470
+ const prevNode = node.previousSibling as Editor2dNode;
471
+ if (
472
+ prevNode &&
473
+ !n.ignoreMask &&
474
+ maskShowArray.concat(maskEnabledArray).includes(prevNode.displayType)
475
+ && !(n.isMask && typeof id === 'undefined')
476
+ ) {
477
+ this.setPrevNodeMask(node.previousSibling, id);
478
+ }
479
+ }
480
+ /**
481
+ * 切换 mask 图层;
482
+ * 多选:取最后一个当 mask, 并创建编组;
483
+ * 单选:设定同级的 previousSibling 的 isMaskChild = true;
484
+ * @param nodes
485
+ * @param mask
486
+ */
487
+ toggleMask(nodes: Editor2dNode[], mask?: boolean): void {
488
+ if (nodes.length === 1) {
489
+ const node = nodes[0];
490
+ // this.updateNode(node, { isMask: !!mask });
491
+ /**
492
+ * @设定mask
493
+ * 1. 无特殊情况直接设
494
+ * 2. 在 mask 中且没有忽略底层,只改 isMask 值;
495
+ * 3. 在 mask 中且忽略了底层,改 isMask 和上一层的值;
496
+ */
497
+ node.isMask = mask;
498
+ // 1 和 3 处理
499
+ if (node.mask && node.ignoreMask || !node.mask) {
500
+ this.setPrevNodeMask(node.previousSibling, mask ? node.id : undefined);
501
+ }
502
+ this.fireContentChanged([node], 'update');
503
+ return;
504
+ }
505
+ /**
506
+ * @多个处理
507
+ * 多个用 getSelectedNodes, 保持图层顺序
508
+ * 检查最底下一个是否是可当 mask 的元素
509
+ * 1. 是:建个分组将最后个设 mask
510
+ * 2. 不是:Enabled 设定 mask, hierarchy-contribution 里判断
511
+ */
512
+ nodes = this.getSelectedNodes();
513
+ const group = this.combineNodes(nodes);
514
+ if (!group) {
515
+ return;
516
+ }
517
+ const lastNode = nodes[nodes.length - 1];
518
+ const childNodes = nodes.splice(0, nodes.length - 1);
519
+ lastNode.isMask = true;
520
+ childNodes.forEach(c => {
521
+ if (c.mask !== lastNode.id) {
522
+ c.mask = lastNode.id;
523
+ }
524
+ });
525
+ const groupNextNode = group.nextSibling as Editor2dNode;
526
+ let id;
527
+ // 如果底层是 maskChild 且没忽略,group 同步底层的 mask
528
+ if (groupNextNode.mask && !groupNextNode.ignoreMask) {
529
+ id = groupNextNode.mask;
530
+ }
531
+ // 如果底层是 mask,且忽略了底层,group mask 设为底层 id
532
+ if (groupNextNode.isMask && groupNextNode.ignoreMask) {
533
+ id = groupNextNode.id;
534
+ }
535
+ if (id) {
536
+ group.mask = id;
537
+ }
538
+ this.fireContentChanged(childNodes.concat([lastNode, group]), 'update');
539
+ }
540
+ /**
541
+ * 忽略底层 mask
542
+ * 忽略层 mask 不删除,留着恢复用,
543
+ * 设定忽略层 ignoreMask 和 清除 prev 上的 mask;
544
+ * @param nodes length === 1, 多个忽略
545
+ * @param ignore
546
+ */
547
+ ignoreMask(nodes: Editor2dNode[], ignore?: boolean): void {
548
+ const node = nodes[0];
549
+ /**
550
+ * @忽略处理
551
+ * 1. 无特殊直接处理
552
+ * 2. 当前是 mask, 设定上一层的 mask 为当前 id;
553
+ */
554
+ if (ignore !== node.ignoreMask) {
555
+ node.ignoreMask = ignore;
556
+ }
557
+ const nextNode = node.nextSibling as Editor2dNode;
558
+ if (!ignore && nextNode && !(nextNode.mask || nextNode.isMask)) {
559
+ // 如果底层不是 mask, 清掉mask
560
+ node.mask = undefined;
561
+ }
562
+ // this.updateNode(node, { ignoreMask: ignore });
563
+ let id = ignore ? undefined : node.mask;
564
+ id = node.isMask && ignore ? node.id : id;
565
+ // id = node.isMask && !ignore ? node.mask : id;
566
+ // console.log(id, ignore);
567
+ this.setPrevNodeMask(node.previousSibling, id);
568
+
569
+ this.fireContentChanged([node], 'update');
570
+ }
348
571
  toggleVisible(nodes: Editor2dNode[], visible?: boolean): void {
349
572
  nodes.forEach(node => {
350
573
  if (this.checkDecoration(node, 'hidable')) {
@@ -400,6 +623,7 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
400
623
  */
401
624
  moveToNode(node: Editor2dNode, targetNode: Editor2dNode, toAfter?: boolean): void {
402
625
  if (Editor2dNode.isRootNode(targetNode) || TreeNode.equals(node, targetNode)) return;
626
+ this.clearMask(node);
403
627
  const parent = targetNode.parent! as Editor2dContainerNode;
404
628
  const children = parent.children! as Editor2dNode[];
405
629
  this.delNode(node, true);
@@ -438,6 +662,7 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
438
662
  });
439
663
  }
440
664
  }
665
+ this.nextMaskToNode(node);
441
666
  this.refresh(parent);
442
667
  this.fireContentChanged([node], 'update');
443
668
  }
@@ -513,13 +738,16 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
513
738
  * 合并分组
514
739
  * @param nodes
515
740
  */
516
- combineNodes(nodes: Editor2dNode[]): void {
741
+ combineNodes(n?: Editor2dNode[]): Editor2dNode | undefined {
742
+ // 合成分组保持图层顺序
743
+ const nodes = n || this.getSelectedNodes();
517
744
  if (nodes.length > 0) {
518
745
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
519
746
  const parent = nodes[0].parent as any;
520
747
  const index = CompositeTreeNode.indexOf(parent, nodes[0]);
521
748
  const group = this.createDisplayNode(GameObjectBaseType.GROUP, parent as Editor2dNode, undefined, index);
522
749
  this.moveToNodesAsChildren(nodes, group);
750
+ return group;
523
751
  }
524
752
  }
525
753
  /**
@@ -587,16 +815,17 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
587
815
  n.children && n.children.some((c: Editor2dContainerNode) => c.id === id || getNodesToChildrenById(c, id));
588
816
 
589
817
  this.animationIds = animationIds();
590
- const cache: Editor2dNode[] = this.animationIds
818
+ // 缓存移到 timeline 里处理
819
+ /* const cache: Editor2dNode[] = this.animationIds
591
820
  .map(id => this.getNodeById(id)).filter(n => !!n)
592
- .map(node => this.cloneNodeData(node as Editor2dNode));
821
+ .map(node => this.cloneNodeData(node as Editor2dNode)); */
593
822
  const toDispose = this.onContentChanged(e => {
594
823
  this.animationIds = animationIds();
595
824
  // TODO 删除动画元件后,动画面板清空数据
596
825
  if (e.nodes) {
597
- const nodes = e.nodes.filter((n: any) => {
598
- // 新建面板时,加入的元素先插入 cache 记录初始值
599
- if (n && n.animation && n.displayType === GameObjectBaseType.ANIMATION) {
826
+ const nodes = e.nodes.filter((n: any) =>
827
+ // 新建面板时,加入的元素先插入 cache 记录初始值
828
+ /* if (n && n.animation && n.displayType === GameObjectBaseType.ANIMATION) {
600
829
  const { animation = {} } = n;
601
830
  const { frames = {} } = animation || {};
602
831
  frames.forEach((c: any) => {
@@ -605,9 +834,9 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
605
834
  cache.push(node);
606
835
  }
607
836
  });
608
- }
609
- return this.animationIds.some(id => (id === n.id) || getNodesToChildrenById(n, id));
610
- });
837
+ } */
838
+ this.animationIds.some(id => (id === n.id) || getNodesToChildrenById(n, id))
839
+ );
611
840
  if (nodes.length) {
612
841
  // TODO: 音乐素材变更
613
842
  onNodeChange(nodes, e.type);
@@ -618,7 +847,7 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
618
847
  dispose: () => {
619
848
  toDispose.dispose();
620
849
  // reset node data
621
- cache.forEach(nodeData => {
850
+ /* cache.forEach(nodeData => {
622
851
  const { displayType } = nodeData;
623
852
  const currentNode = this.getNodeById(nodeData.id);
624
853
  if (!currentNode) {
@@ -635,7 +864,7 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
635
864
  const changeData: {[key: string]: any} = getChangeAnimationData(keysList, currentNode, nodeData);
636
865
  changeData.name = currentNode?.name;
637
866
  this.updateNode(nodeData.id, changeData, true);
638
- });
867
+ }); */
639
868
  // this.animationStarted = false;
640
869
  this.animationIds = [];
641
870
  }
@@ -678,30 +907,30 @@ export class Editor2dDocument extends TreeImpl<Editor2dNode, Editor2dContainerNo
678
907
  return Object.keys(this.nodes).length;
679
908
  }
680
909
 
681
- /**
682
- * 检测错误
683
- * @protected
684
- */
685
- protected async loadRefInfos(): Promise<void> {
686
- const componentContents = await this.resourceService.getDependenciesContent<Editor2dContent>(this.uri, u => !!u.match(/\.comp/));
687
- // TODO 模板模式暂时不做资源依赖检测
688
- if (!this.options.isTemplate) {
689
- this.errors = await this.resourceService.checkRefsErrors(this.uri);
690
- }
691
- const normalize = (node: Editor2dNode, version?: number, parent?: Editor2dNode) => {
692
- if (parent) {
693
- node.parent = parent as Editor2dContainerNode;
694
- }
695
- if (version !== undefined) {
696
- node.version = version;
697
- }
698
- node.children = node.children ? node.children.map(c => normalize(c as Editor2dNode, version, node)) : undefined;
699
- return node;
700
- };
701
- this.componentContents = mapValues<Editor2dNode>(componentContents, (value: Editor2dContent) => value.content ? normalize(value.content!, value.version) : undefined);
702
- await this.refresh();
703
- this.fireContentChanged([], 'add', true);
704
- }
910
+ // /**
911
+ // * 检测错误
912
+ // * @protected
913
+ // */
914
+ // protected async loadRefInfos(): Promise<void> {
915
+ // const componentContents = await this.resourceService.getDependenciesContent<Editor2dContent>(this.uri, u => !!u.match(/\.comp/));
916
+ // // 模板模式暂时不做资源依赖检测
917
+ // if (!this.options.isTemplate) {
918
+ // this.errors = await this.resourceService.checkRefsErrors(this.uri);
919
+ // }
920
+ // const normalize = (node: Editor2dNode, version?: number, parent?: Editor2dNode) => {
921
+ // if (parent) {
922
+ // node.parent = parent as Editor2dContainerNode;
923
+ // }
924
+ // if (version !== undefined) {
925
+ // node.version = version;
926
+ // }
927
+ // node.children = node.children ? node.children.map(c => normalize(c as Editor2dNode, version, node)) : undefined;
928
+ // return node;
929
+ // };
930
+ // this.componentContents = mapValues<Editor2dNode>(componentContents, (value: Editor2dContent) => value.content ? normalize(value.content!, value.version) : undefined);
931
+ // await this.refresh();
932
+ // this.fireContentChanged([], 'add', true);
933
+ // }
705
934
  getWarningDesc(node: Editor2dNode): string | undefined {
706
935
  if (node.error && node.error.message) return node.error.message;
707
936
  let uris: string[] = [];
@@ -11,6 +11,7 @@ import { PlaygroundConfig, SelectorEntityRendererProps } from '@gedit/playground
11
11
  import type { CanvasDraw } from '../playground/canvas-draw';
12
12
  import type { PlaygroundContext2d } from '../playground/playground-context';
13
13
  import { nanoid } from 'nanoid';
14
+ import { PathChild } from '@gedit/canvas-draw';
14
15
 
15
16
  const stringify = require('json-stringify-pretty-compact');
16
17
 
@@ -50,12 +51,20 @@ function omitNode(node?: Editor2dNode | Editor2dContainerNode, omitKeys: string[
50
51
 
51
52
  export namespace Editor2dContent {
52
53
  export function parseToJSON(contentData: Editor2dContent): Editor2dContent {
54
+ const content = omitNode(contentData.content, [], node => {
55
+ node.selected = false;
56
+ // console.log('>>>>>>>>>>>>>>cache', node.cache);
57
+ // 不保存动画数据,,如果有 cache 直接用 cache 的,cache 为 timeline 专属
58
+ const { cache, ...n } = node;
59
+ if (cache) {
60
+ return { ...n, ...cache };
61
+ }
62
+ return n;
63
+ });
64
+ // console.log(content);
53
65
  return {
54
66
  version: contentData.version,
55
- content: omitNode(contentData.content, [], node => {
56
- node.selected = false;
57
- return node;
58
- }),
67
+ content,
59
68
  snaplines: contentData.snaplines,
60
69
  };
61
70
  }
@@ -64,10 +73,17 @@ export namespace Editor2dContent {
64
73
  }
65
74
  }
66
75
 
76
+ export interface Editor2dNodeCache extends Omit<Editor2dNode, 'parent' | 'previousSibling' | 'nextSibling' | 'selected' | 'canvasHide' | 'version'> {
77
+ }
78
+
67
79
  export interface Editor2dNode extends TreeNode, EditorDocumentNode, Lockable, SelectableTreeNode, GameObjectData {
68
80
  canvasHide: boolean // 画布上是否展示
69
81
  version: number // 节点修改的版本,用于快速diff用, 刷新后丢失,不会存储到服务器
70
82
  parent: Editor2dContainerNode | undefined
83
+ cache?: Editor2dNodeCache;
84
+ isMask?: boolean; // 是否 mask
85
+ mask?: string; // mask 的 id
86
+ ignoreMask?: boolean; // 是否忽略底层 mask;
71
87
  }
72
88
 
73
89
  /**
@@ -75,7 +91,7 @@ export interface Editor2dNode extends TreeNode, EditorDocumentNode, Lockable, Se
75
91
  */
76
92
  export interface Editor2dPathNode extends Editor2dNode {
77
93
  [GameObjectBaseType.PATH]: {
78
- paths: { x: number, y: number }[]
94
+ paths: PathChild[]
79
95
  }
80
96
  }
81
97
 
@@ -11,9 +11,15 @@ interface KeysValue {
11
11
  }
12
12
  // 添加进时间轴动画的条件;
13
13
  const supportKeys: SchemaType[] = ['integer', 'float', 'color'];
14
+ // 三个数组 key 写死
15
+ export const animArrayKeys: {[key: string]: string} = {
16
+ 'style.color': 'FillArray',
17
+ 'style.line': 'LineArray',
18
+ 'style.lineDash': 'LineDashArray',
19
+ };
14
20
  function readAnimationKeys(
15
21
  deco: SchemaDecoration,
16
- keyList: { key: string; name: string }[],
22
+ keyList: { key: string; name: string; }[],
17
23
  currentKey?: string,
18
24
  parentName?: string,
19
25
  parentKey?: string
@@ -36,8 +42,9 @@ function readAnimationKeys(
36
42
  } else if (
37
43
  currentLabel &&
38
44
  currentKey &&
39
- supportKeys.includes(deco.type) &&
45
+ (supportKeys.includes(deco.type) &&
40
46
  !currentKey.match(/^(origin)/) // 干掉原点
47
+ || animArrayKeys[currentKey])
41
48
  ) {
42
49
  keyList.push({
43
50
  key: currentKey,