@gedit/editor-2d 0.3.4 → 0.3.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.
Files changed (160) hide show
  1. package/LICENSE +21 -0
  2. package/lib/browser/editor2d-anim-path-selection-service.d.ts +24 -0
  3. package/lib/browser/editor2d-anim-path-selection-service.d.ts.map +1 -0
  4. package/lib/browser/editor2d-anim-path-selection-service.js +52 -0
  5. package/lib/browser/editor2d-anim-path-selection-service.js.map +1 -0
  6. package/lib/browser/editor2d-context-key-service.js +7 -10
  7. package/lib/browser/editor2d-context-key-service.js.map +1 -1
  8. package/lib/browser/editor2d-contribution.js +25 -28
  9. package/lib/browser/editor2d-contribution.js.map +1 -1
  10. package/lib/browser/editor2d-frontend-module.d.ts.map +1 -1
  11. package/lib/browser/editor2d-frontend-module.js +38 -38
  12. package/lib/browser/editor2d-frontend-module.js.map +1 -1
  13. package/lib/browser/editor2d-label-provider.js +18 -21
  14. package/lib/browser/editor2d-label-provider.js.map +1 -1
  15. package/lib/browser/editor2d-model-provider.js +16 -19
  16. package/lib/browser/editor2d-model-provider.js.map +1 -1
  17. package/lib/browser/editor2d-ref-provider-contribution.js +13 -16
  18. package/lib/browser/editor2d-ref-provider-contribution.js.map +1 -1
  19. package/lib/browser/editor2d-service.d.ts +2 -0
  20. package/lib/browser/editor2d-service.d.ts.map +1 -1
  21. package/lib/browser/editor2d-service.js +28 -27
  22. package/lib/browser/editor2d-service.js.map +1 -1
  23. package/lib/browser/index.d.ts +2 -0
  24. package/lib/browser/index.d.ts.map +1 -1
  25. package/lib/browser/index.js +6 -20
  26. package/lib/browser/index.js.map +1 -1
  27. package/lib/browser/model/editor2d-document.d.ts +22 -9
  28. package/lib/browser/model/editor2d-document.d.ts.map +1 -1
  29. package/lib/browser/model/editor2d-document.js +248 -133
  30. package/lib/browser/model/editor2d-document.js.map +1 -1
  31. package/lib/browser/model/editor2d-iterator.js +1 -5
  32. package/lib/browser/model/editor2d-iterator.js.map +1 -1
  33. package/lib/browser/model/editor2d-model-container.js +22 -26
  34. package/lib/browser/model/editor2d-model-container.js.map +1 -1
  35. package/lib/browser/model/editor2d-model.js +21 -24
  36. package/lib/browser/model/editor2d-model.js.map +1 -1
  37. package/lib/browser/model/editor2d-selection.js +7 -10
  38. package/lib/browser/model/editor2d-selection.js.map +1 -1
  39. package/lib/browser/model/editor2d-widget.js +17 -20
  40. package/lib/browser/model/editor2d-widget.js.map +1 -1
  41. package/lib/browser/model/editor2d.d.ts.map +1 -1
  42. package/lib/browser/model/editor2d.js +37 -35
  43. package/lib/browser/model/editor2d.js.map +1 -1
  44. package/lib/browser/model/index.js +7 -23
  45. package/lib/browser/model/index.js.map +1 -1
  46. package/lib/browser/model/utils/anim.utils.d.ts +2 -1
  47. package/lib/browser/model/utils/anim.utils.d.ts.map +1 -1
  48. package/lib/browser/model/utils/anim.utils.js +14 -16
  49. package/lib/browser/model/utils/anim.utils.js.map +1 -1
  50. package/lib/browser/model/utils/index.js +1 -17
  51. package/lib/browser/model/utils/index.js.map +1 -1
  52. package/lib/browser/playground/anim-path-edit-layer.d.ts +33 -0
  53. package/lib/browser/playground/anim-path-edit-layer.d.ts.map +1 -0
  54. package/lib/browser/playground/anim-path-edit-layer.js +352 -0
  55. package/lib/browser/playground/anim-path-edit-layer.js.map +1 -0
  56. package/lib/browser/playground/canvas-draw.d.ts +3 -0
  57. package/lib/browser/playground/canvas-draw.d.ts.map +1 -1
  58. package/lib/browser/playground/canvas-draw.js +57 -39
  59. package/lib/browser/playground/canvas-draw.js.map +1 -1
  60. package/lib/browser/playground/canvas-layer.d.ts.map +1 -1
  61. package/lib/browser/playground/canvas-layer.js +29 -32
  62. package/lib/browser/playground/canvas-layer.js.map +1 -1
  63. package/lib/browser/playground/entities/document-entity.js +2 -6
  64. package/lib/browser/playground/entities/document-entity.js.map +1 -1
  65. package/lib/browser/playground/entities/editor2d-entity.js +3 -7
  66. package/lib/browser/playground/entities/editor2d-entity.js.map +1 -1
  67. package/lib/browser/playground/entities/extend-entity.js +2 -6
  68. package/lib/browser/playground/entities/extend-entity.js.map +1 -1
  69. package/lib/browser/playground/entities/index.js +3 -19
  70. package/lib/browser/playground/entities/index.js.map +1 -1
  71. package/lib/browser/playground/extend-edit/gradient-conic-node.d.ts +4 -0
  72. package/lib/browser/playground/extend-edit/gradient-conic-node.d.ts.map +1 -0
  73. package/lib/browser/playground/extend-edit/gradient-conic-node.js +69 -0
  74. package/lib/browser/playground/extend-edit/gradient-conic-node.js.map +1 -0
  75. package/lib/browser/playground/{extend-edit-layer-point-event.d.ts → extend-edit/gradient-edit-layer-point-event.d.ts} +1 -1
  76. package/lib/browser/playground/extend-edit/gradient-edit-layer-point-event.d.ts.map +1 -0
  77. package/lib/browser/playground/{extend-edit-layer-point-event.js → extend-edit/gradient-edit-layer-point-event.js} +3 -28
  78. package/lib/browser/playground/extend-edit/gradient-edit-layer-point-event.js.map +1 -0
  79. package/lib/browser/playground/extend-edit/gradient-node.d.ts +13 -0
  80. package/lib/browser/playground/extend-edit/gradient-node.d.ts.map +1 -0
  81. package/lib/browser/playground/extend-edit/gradient-node.js +154 -0
  82. package/lib/browser/playground/extend-edit/gradient-node.js.map +1 -0
  83. package/lib/browser/playground/extend-edit-layer.d.ts +0 -8
  84. package/lib/browser/playground/extend-edit-layer.d.ts.map +1 -1
  85. package/lib/browser/playground/extend-edit-layer.js +30 -249
  86. package/lib/browser/playground/extend-edit-layer.js.map +1 -1
  87. package/lib/browser/playground/index.js +11 -30
  88. package/lib/browser/playground/index.js.map +1 -1
  89. package/lib/browser/playground/path-edit/anim-path-edit-svg.d.ts +17 -0
  90. package/lib/browser/playground/path-edit/anim-path-edit-svg.d.ts.map +1 -0
  91. package/lib/browser/playground/path-edit/anim-path-edit-svg.js +58 -0
  92. package/lib/browser/playground/path-edit/anim-path-edit-svg.js.map +1 -0
  93. package/lib/browser/playground/path-edit/index.js +3 -19
  94. package/lib/browser/playground/path-edit/index.js.map +1 -1
  95. package/lib/browser/playground/path-edit/path-edit-layer-move-point.d.ts +1 -1
  96. package/lib/browser/playground/path-edit/path-edit-layer-move-point.d.ts.map +1 -1
  97. package/lib/browser/playground/path-edit/path-edit-layer-move-point.js +9 -39
  98. package/lib/browser/playground/path-edit/path-edit-layer-move-point.js.map +1 -1
  99. package/lib/browser/playground/path-edit/path-edit-layer-svg-path.d.ts +2 -6
  100. package/lib/browser/playground/path-edit/path-edit-layer-svg-path.d.ts.map +1 -1
  101. package/lib/browser/playground/path-edit/path-edit-layer-svg-path.js +20 -50
  102. package/lib/browser/playground/path-edit/path-edit-layer-svg-path.js.map +1 -1
  103. package/lib/browser/playground/path-edit/utils.js +64 -100
  104. package/lib/browser/playground/path-edit/utils.js.map +1 -1
  105. package/lib/browser/playground/path-edit-layer.d.ts.map +1 -1
  106. package/lib/browser/playground/path-edit-layer.js +67 -95
  107. package/lib/browser/playground/path-edit-layer.js.map +1 -1
  108. package/lib/browser/playground/playground-context.d.ts +3 -3
  109. package/lib/browser/playground/playground-context.d.ts.map +1 -1
  110. package/lib/browser/playground/playground-context.js +48 -54
  111. package/lib/browser/playground/playground-context.js.map +1 -1
  112. package/lib/browser/playground/playground-contribution.d.ts.map +1 -1
  113. package/lib/browser/playground/playground-contribution.js +41 -42
  114. package/lib/browser/playground/playground-contribution.js.map +1 -1
  115. package/lib/browser/playground/selection-entity-manager.d.ts.map +1 -1
  116. package/lib/browser/playground/selection-entity-manager.js +26 -54
  117. package/lib/browser/playground/selection-entity-manager.js.map +1 -1
  118. package/lib/browser/playground/selector-extend-icons.js +12 -39
  119. package/lib/browser/playground/selector-extend-icons.js.map +1 -1
  120. package/lib/browser/playground/selector-extend-renderer.js +22 -52
  121. package/lib/browser/playground/selector-extend-renderer.js.map +1 -1
  122. package/lib/browser/utils/bezier.path.utils.d.ts +23 -0
  123. package/lib/browser/utils/bezier.path.utils.d.ts.map +1 -0
  124. package/lib/browser/utils/bezier.path.utils.js +64 -0
  125. package/lib/browser/utils/bezier.path.utils.js.map +1 -0
  126. package/lib/browser/utils/bounds.d.ts.map +1 -1
  127. package/lib/browser/utils/bounds.js +17 -22
  128. package/lib/browser/utils/bounds.js.map +1 -1
  129. package/lib/browser/utils/snapshot.js +17 -20
  130. package/lib/browser/utils/snapshot.js.map +1 -1
  131. package/lib/i18n/zh-CN.js +1 -3
  132. package/lib/i18n/zh-CN.js.map +1 -1
  133. package/package.json +11 -10
  134. package/src/browser/editor2d-anim-path-selection-service.ts +48 -0
  135. package/src/browser/editor2d-frontend-module.ts +2 -0
  136. package/src/browser/editor2d-service.ts +2 -0
  137. package/src/browser/index.ts +2 -1
  138. package/src/browser/model/editor2d-document.ts +198 -20
  139. package/src/browser/model/editor2d.ts +13 -2
  140. package/src/browser/model/utils/anim.utils.ts +10 -6
  141. package/src/browser/playground/anim-path-edit-layer.tsx +435 -0
  142. package/src/browser/playground/canvas-draw.ts +37 -2
  143. package/src/browser/playground/canvas-layer.ts +1 -0
  144. package/src/browser/playground/extend-edit/gradient-conic-node.tsx +106 -0
  145. package/src/browser/playground/extend-edit/gradient-node.tsx +232 -0
  146. package/src/browser/playground/extend-edit-layer.tsx +32 -312
  147. package/src/browser/playground/path-edit/anim-path-edit-svg.tsx +168 -0
  148. package/src/browser/playground/path-edit/path-edit-layer-move-point.tsx +1 -1
  149. package/src/browser/playground/path-edit/path-edit-layer-svg-path.tsx +3 -7
  150. package/src/browser/playground/path-edit/utils.tsx +1 -1
  151. package/src/browser/playground/path-edit-layer.tsx +4 -4
  152. package/src/browser/playground/playground-context.ts +2 -6
  153. package/src/browser/playground/playground-contribution.ts +2 -0
  154. package/src/browser/playground/selection-entity-manager.tsx +7 -7
  155. package/src/browser/style/path-edit-layer.less +13 -5
  156. package/src/browser/utils/bezier.path.utils.ts +89 -0
  157. package/src/browser/utils/bounds.ts +0 -1
  158. package/lib/browser/playground/extend-edit-layer-point-event.d.ts.map +0 -1
  159. package/lib/browser/playground/extend-edit-layer-point-event.js.map +0 -1
  160. /package/src/browser/playground/{extend-edit-layer-point-event.tsx → extend-edit/gradient-edit-layer-point-event.tsx} +0 -0
@@ -0,0 +1,435 @@
1
+ import * as React from 'react';
2
+ import {
3
+ able,
4
+ EditorStateConfigEntity,
5
+ Entity,
6
+ entity,
7
+ Layer,
8
+ Selectable,
9
+ SelectState,
10
+ EditorState,
11
+ } from '@gedit/playground';
12
+ import { Disposable } from '@gedit/utils';
13
+ import { domUtils } from '@gedit/utils/lib/browser';
14
+ import { PlaygroundContext2d } from './playground-context';
15
+ import { DocumentEntity, Editor2dEntity, ExtendEntity } from './entities';
16
+ import { Editor2dDocument, Editor2dNode } from '../model';
17
+ import { AnimSvgPath } from './path-edit/anim-path-edit-svg';
18
+ import { setBezierMovePoint } from './path-edit';
19
+ import type { PathPointSelection } from '@gedit/playground';
20
+ import { getPointsToPath, PathChild, toFixedValue } from '@gedit/canvas-draw';
21
+ import {
22
+ FrameChild,
23
+ TimelineData,
24
+ TimelineFrame,
25
+ } from '@gedit/render-engine-ide';
26
+ import TweenOne from 'tween-one';
27
+
28
+ const fixPointPosition = ({
29
+ item,
30
+ frameData,
31
+ path,
32
+ key,
33
+ }: {
34
+ key: 'x' | 'y';
35
+ item: PathChild & { id: number };
36
+ frameData: FrameChild[];
37
+ path: PathChild[];
38
+ }) => {
39
+ const currentTime =
40
+ typeof item.id === 'string' ? parseFloat(item.id) : item.id;
41
+ const preFrame = frameData
42
+ .filter(d => d.time < currentTime && d.key === `position.${key}`)
43
+ .pop();
44
+ const pre = path.find(d => d.id === preFrame?.time);
45
+ const nextFrame = frameData
46
+ .filter(d => d.time > currentTime && d.key === `position.${key}`)
47
+ .shift();
48
+ const next = path.find(d => d.id === nextFrame?.time);
49
+ if (!preFrame || !nextFrame || !pre || !next) {
50
+ return {
51
+ [key]: item?.y ?? pre?.y ?? next?.y ?? 0,
52
+ };
53
+ }
54
+ const time = nextFrame.time - preFrame.time;
55
+ const moment = currentTime - preFrame.time;
56
+ const p = getPointsToPath([pre, next]);
57
+ const obj: { [key: string]: number } = {};
58
+ TweenOne(obj, {
59
+ animation: {
60
+ PathMotion: { path: p },
61
+ duration: time,
62
+ },
63
+ moment,
64
+ paused: true,
65
+ });
66
+ // item.y = obj.y;
67
+ return obj;
68
+ };
69
+
70
+ /**
71
+ * 扩展编辑
72
+ */
73
+ export class AnimPathEditLayer extends Layer<PlaygroundContext2d> {
74
+ node = domUtils.createDivWithClass('gedit-anim-path-edit-layer');
75
+ id = 'animPathEditLayer';
76
+ @entity(EditorStateConfigEntity)
77
+ protected editorState: EditorStateConfigEntity;
78
+ @entity(DocumentEntity) documentEntity: DocumentEntity;
79
+ @entity(ExtendEntity) extendEntity: ExtendEntity;
80
+ @able(Selectable) protected selectableNodes: Entity[];
81
+
82
+ get document(): Editor2dDocument | undefined {
83
+ return this.documentEntity.config.document;
84
+ }
85
+ get selectedEntity(): Editor2dEntity | undefined {
86
+ const nodes = this.selectableNodes.filter(
87
+ node => node.getData<SelectState>(SelectState)?.selected
88
+ );
89
+ // 只考虑单选模式
90
+ return nodes.length === 1 ? (nodes[0] as Editor2dEntity) : undefined;
91
+ }
92
+
93
+ get isEnabled(): boolean {
94
+ return this.editorState.is(EditorState.STATE_SELECT.id);
95
+ }
96
+
97
+ addDispose(disposable: Disposable[]): void {
98
+ this.toDispose.pushAll(disposable);
99
+ }
100
+
101
+ onReady(): void {
102
+ this.addDispose([
103
+ this.editorState.onStateChange(() => {
104
+ const animId = this.document?.timelineService?.currentTimelineData?.id;
105
+ // 如果动画面板打开,状态变更,清空选中
106
+ if (!this.isEnabled && animId) {
107
+ this.context.animPathSelection?.clearSelection();
108
+ }
109
+ }),
110
+ // this.selectionService!.onSelectionChanged(e => {
111
+ // }),
112
+ this.context.animPathSelection.onSelectionChanged(() => {
113
+ this.draw();
114
+ }),
115
+ ]);
116
+ }
117
+
118
+ onZoom(scale: number): void {
119
+ domUtils.setStyle(this.node, {
120
+ transform: `scale(${scale})`,
121
+ });
122
+ }
123
+ getCurrentFrameData(
124
+ id: string | number,
125
+ animData: TimelineData
126
+ ): { currentFrame?: FrameChild[]; frameNode?: TimelineFrame } {
127
+ const node = this.selectedEntity;
128
+
129
+ if (!node || !animData) {
130
+ return {};
131
+ }
132
+ const frameNode = animData.frames.find((c: any) => c.id === node?.node?.id);
133
+ const currentFrame = frameNode?.frame.value.filter(
134
+ (c: any) => c.time === id
135
+ );
136
+ return {
137
+ currentFrame,
138
+ frameNode,
139
+ };
140
+ }
141
+
142
+ onPointMouseDown(
143
+ e: React.MouseEvent<SVGCircleElement>,
144
+ currentPoint: PathChild
145
+ // paths: PathChild[]
146
+ ): void {
147
+ if (e.buttons !== 1) {
148
+ return;
149
+ }
150
+ // 如果在 selection 里拖动所有点, 没有则切换当前 selection 里的点
151
+ const { animPathSelection } = this.context;
152
+ const animData = this.document?.timelineService?.currentTimelineData;
153
+ if (!animPathSelection || !animData || !currentPoint.id) {
154
+ return;
155
+ }
156
+ const selectionNode = [
157
+ {
158
+ pointId: currentPoint.id as number,
159
+ },
160
+ ];
161
+
162
+ animPathSelection.selection = selectionNode;
163
+ const { currentFrame, frameNode } = this.getCurrentFrameData(
164
+ currentPoint.id,
165
+ animData
166
+ );
167
+
168
+ const timeObj = {
169
+ totalTime: animData.totalTime,
170
+ regionStartTime: animData.regionStartTime,
171
+ regionEndTime: animData.regionEndTime,
172
+ };
173
+
174
+ if (!currentFrame || !frameNode) {
175
+ return;
176
+ }
177
+
178
+ this.startDrag(e.clientX, e.clientY, {
179
+ // 拖动
180
+ onDrag: dragEvent => {
181
+ let { x, y } = dragEvent.endPos;
182
+ x /= this.config?.finalScale || 1;
183
+ y /= this.config?.finalScale || 1;
184
+ if (currentFrame.length === 1) {
185
+ const c = currentFrame[0];
186
+ const v = {
187
+ key: `position.${c.key === 'position.x' ? 'y' : 'x'}`,
188
+ time: currentPoint.id as number,
189
+ value: 0, // 这里只是占位,下面会改数据;
190
+ };
191
+ const index = frameNode.frame.value.findIndex(d => d === c);
192
+ frameNode.frame.value.splice(index, 0, v);
193
+ this.document?.timelineService?.saveTimelineData(
194
+ animData,
195
+ timeObj,
196
+ true
197
+ );
198
+ const node = this.document?.getNodeById(animData.id);
199
+ // 更新时间轴上的帧数据;
200
+ if (node) {
201
+ this.document?.timelineService?.changeTimelineData(node);
202
+ }
203
+ currentFrame.push(v);
204
+ }
205
+ currentFrame.forEach((c: any) => {
206
+ const keys = c.key.split('.');
207
+ const key = keys[1] as 'x' | 'y';
208
+ const value = toFixedValue(key === 'x' ? x : y, 4);
209
+ const diff = currentPoint[key] - value;
210
+ c.value = value;
211
+ if ('bezierSV' in c) {
212
+ c.bezierSV = (currentPoint[`${key}1`] || 0) - diff;
213
+ }
214
+ if ('bezierEV' in c) {
215
+ c.bezierEV = (currentPoint[`${key}2`] || 0) - diff;
216
+ }
217
+ });
218
+ // 更新当前帧数据
219
+ frameNode.frame.current =
220
+ this.document?.timelineService?.getNodeCurrentFrame(frameNode) ||
221
+ frameNode.frame.current;
222
+ this.document?.timelineService?.saveTimelineData(
223
+ animData,
224
+ timeObj,
225
+ true,
226
+ true
227
+ );
228
+ // this.document?.updateNode(animNode, { ...animNode }, true);
229
+ },
230
+ onDragEnd: () => {
231
+ this.document?.timelineService?.saveTimelineData(
232
+ animData,
233
+ timeObj,
234
+ true
235
+ );
236
+ },
237
+ });
238
+ this.draw();
239
+ }
240
+
241
+ onBezierPointMouseDown(
242
+ e: React.MouseEvent<SVGCircleElement>,
243
+ currentPoint: PathChild,
244
+ key: 'left' | 'right'
245
+ ): void {
246
+ if (e.buttons !== 1) {
247
+ return;
248
+ }
249
+ // 如果在 selection 里拖动所有点, 没有则切换当前 selection 里的点
250
+ const { animPathSelection } = this.context;
251
+ const animData = this.document?.timelineService?.currentTimelineData;
252
+ if (!animPathSelection || !animData || !currentPoint.id) {
253
+ return;
254
+ }
255
+ const selectionNode = [
256
+ {
257
+ pointId: currentPoint.id as number,
258
+ bezierKey: key,
259
+ },
260
+ ];
261
+
262
+ animPathSelection.selection = selectionNode;
263
+
264
+ const { currentFrame, frameNode } = this.getCurrentFrameData(
265
+ currentPoint.id,
266
+ animData
267
+ );
268
+
269
+ const timeObj = {
270
+ totalTime: animData.totalTime,
271
+ regionStartTime: animData.regionStartTime,
272
+ regionEndTime: animData.regionEndTime,
273
+ };
274
+
275
+ if (!currentFrame || !frameNode) {
276
+ return;
277
+ }
278
+ this.startDrag(e.clientX, e.clientY, {
279
+ onDrag: dragEvent => {
280
+ let { x, y } = dragEvent.endPos;
281
+ x /= this.config?.finalScale || 1;
282
+ y /= this.config?.finalScale || 1;
283
+ const p = setBezierMovePoint(currentPoint, key, {
284
+ x,
285
+ y,
286
+ });
287
+ currentFrame.forEach((c: any) => {
288
+ const keys = c.key.split('.');
289
+ const bezierKey = keys[1] as 'x' | 'y';
290
+ switch (bezierKey) {
291
+ case 'x':
292
+ c.bezierSV = p.x1;
293
+ c.bezierEV = p.x2;
294
+ break;
295
+ case 'y':
296
+ c.bezierSV = p.y1;
297
+ c.bezierEV = p.y2;
298
+ break;
299
+ default:
300
+ break;
301
+ }
302
+ });
303
+ // 更新当前帧数据
304
+ frameNode.frame.current =
305
+ this.document?.timelineService?.getNodeCurrentFrame(frameNode) ||
306
+ frameNode.frame.current;
307
+ this.document?.timelineService?.saveTimelineData(
308
+ {
309
+ id: animData.id,
310
+ frames: animData.frames,
311
+ },
312
+ timeObj,
313
+ true,
314
+ true
315
+ );
316
+ // this.document?.updateNode(animNode, { ...animNode }, true);
317
+ },
318
+ onDragEnd: () => {
319
+ animPathSelection.selection = [
320
+ {
321
+ pointId: currentPoint.id as number,
322
+ },
323
+ ];
324
+ this.document?.timelineService?.saveTimelineData(
325
+ {
326
+ id: animData.id,
327
+ frames: animData.frames,
328
+ },
329
+ timeObj
330
+ );
331
+ },
332
+ });
333
+ this.draw();
334
+ }
335
+
336
+ draw(): JSX.Element {
337
+ const node = this.selectedEntity;
338
+ const animId = this.document?.timelineService?.currentTimelineData?.id;
339
+ if (
340
+ !this.document ||
341
+ !node ||
342
+ !(animId && node.node?.useAnimationId === animId) ||
343
+ !this.isEnabled
344
+ ) {
345
+ return <></>;
346
+ }
347
+
348
+ // const { currentTime = 0 } = this.document.timelineService || {};
349
+ const animNode = this.document.getNodeById(animId) as Editor2dNode & {
350
+ animation: any;
351
+ };
352
+ const currentNode = node.node;
353
+ // 判断是否有 position 属性动画;
354
+ const frameNode = animNode.animation.frames.find(
355
+ (c: any) => c.id === currentNode.id
356
+ );
357
+ const { frame, attrSplit = [] } = frameNode;
358
+ const frameData = frame.value.filter((c: any) =>
359
+ c.key.match(/^position/)
360
+ ) as FrameChild[];
361
+
362
+ let path: PathChild[] = [];
363
+
364
+ frameData.forEach((c: any) => {
365
+ const inPath = path.find(d => d.id === c.time);
366
+ const item = inPath || ({ id: c.time } as PathChild);
367
+ const keys = c.key.split('.');
368
+ const key = keys[1] as 'x' | 'y';
369
+ item[key] = c.value;
370
+ if ('bezierSV' in c) {
371
+ item[`${key}1`] = c.bezierSV;
372
+ }
373
+ if ('bezierEV' in c) {
374
+ item[`${key}2`] = c.bezierEV;
375
+ }
376
+ if ('pathFuncType' in c) {
377
+ item.type = c.pathFuncType;
378
+ }
379
+ if (!inPath) {
380
+ path.push(item);
381
+ }
382
+ });
383
+ // 保证有值,如果当前帧没有值,取前后两帧的中间值
384
+ path = path.map((c: PathChild, index) => {
385
+ if ('x' in c && 'y' in c) {
386
+ return c;
387
+ }
388
+ const item = c as PathChild;
389
+ if (!item.id) {
390
+ return {
391
+ ...item,
392
+ x: item.x || 0,
393
+ y: item.y || 0,
394
+ };
395
+ }
396
+
397
+ // 计算百分比
398
+ if (!('y' in c) && item.id) {
399
+ const { y } = fixPointPosition({
400
+ item: item as PathChild & { id: number },
401
+ frameData,
402
+ path,
403
+ key: 'y',
404
+ });
405
+ item.y = y;
406
+ return item;
407
+ }
408
+ const { x } = fixPointPosition({
409
+ item: item as PathChild & { id: number },
410
+ frameData,
411
+ path,
412
+ key: 'x',
413
+ });
414
+ item.x = x;
415
+ return item;
416
+ });
417
+
418
+ return (
419
+ <AnimSvgPath
420
+ width={this.config.config.pageBounds?.width || 300}
421
+ height={this.config.config.pageBounds?.height || 300}
422
+ scale={this.config.finalScale}
423
+ paths={path}
424
+ noBezier={attrSplit.includes('position')}
425
+ selection={this.context.animPathSelection?.selection as PathPointSelection<number>[]}
426
+ onPointMouseDown={this.onPointMouseDown.bind(this)}
427
+ onBezierPointMouseDown={this.onBezierPointMouseDown.bind(this)}
428
+ onCancelSelection={() => {
429
+ this.context.animPathSelection?.clearSelection();
430
+ this.draw();
431
+ }}
432
+ />
433
+ );
434
+ }
435
+ }
@@ -5,6 +5,7 @@ import {
5
5
  GameObjectBaseType,
6
6
  GameObjectData,
7
7
  GameObjectError,
8
+ TimelineFrame,
8
9
  } from '@gedit/render-engine';
9
10
  import { Editor2dNode, omitNode } from '../model/editor2d';
10
11
  import {
@@ -22,6 +23,7 @@ import {
22
23
  URI,
23
24
  } from '@gedit/utils';
24
25
  import { EntityManager, SnaplineConfigEntity } from '@gedit/playground';
26
+ import { TimelineService } from '../model';
25
27
 
26
28
  const WAIT_TO_DISPOSE_TIME = 30000; // 延迟删除, 这样tab在频繁切换时候不会有延迟
27
29
  const SCENE_KEY = 'boot';
@@ -41,6 +43,7 @@ export interface CanvasDrawOpts {
41
43
  parentNode?: Editor2dNode,
42
44
  getParent?: boolean
43
45
  ) => Editor2dNode[] | undefined;
46
+ getTimelineService?: () => TimelineService | undefined;
44
47
  isSnapshot?: boolean;
45
48
  isTemplate?: boolean;
46
49
  }
@@ -134,6 +137,7 @@ export class CanvasDraw extends DisposableImpl {
134
137
  protected lastRenderKeys: string[] = [];
135
138
  protected renderWidgetDispose: Disposable | undefined;
136
139
  protected pixelArt: boolean;
140
+ protected multiplyAlpha: boolean = false;
137
141
  renderWidget?: GameWidgetIDE;
138
142
  private allCount = -1;
139
143
  private currentSymbols: GameConfig.Symbol[] = [];
@@ -175,12 +179,17 @@ export class CanvasDraw extends DisposableImpl {
175
179
  this.waitToDispose = undefined;
176
180
  }
177
181
  // pixlerArt 更新的话则重新创建
178
- if (appConfig.pixelArt !== this.pixelArt && this.renderWidget) {
182
+ if (
183
+ (appConfig.pixelArt !== this.pixelArt ||
184
+ appConfig.multiplyAlpha !== this.multiplyAlpha) &&
185
+ this.renderWidget
186
+ ) {
179
187
  this.renderWidget.dispose();
180
188
  }
181
189
  const isScene = new URI(this.data?.uri).path.ext === '.scene';
182
190
  // 组件模式用透明
183
191
  const backgroundColor = isScene ? appConfig.backgroundColor : '';
192
+ this.multiplyAlpha = appConfig.multiplyAlpha;
184
193
  this.pixelArt = appConfig.pixelArt;
185
194
  if (visible && !this.renderWidget) {
186
195
  const element = window.document.createElement(
@@ -410,7 +419,9 @@ export class CanvasDraw extends DisposableImpl {
410
419
  const currentDepth = depth;
411
420
  const oldNode = this.nodeCache.get(nodePath);
412
421
  const nodeStr = JSON.stringify(omitNode(node, ['children']));
413
- const oldNodeStr = oldNode ? JSON.stringify(omitNode(oldNode, ['children'])) : '';
422
+ const oldNodeStr = oldNode
423
+ ? JSON.stringify(omitNode(oldNode, ['children']))
424
+ : '';
414
425
  const nodeChanged = nodeStr !== oldNodeStr;
415
426
  let gameObject = gameObjectCache.get(nodePath);
416
427
  // 节点重置
@@ -528,12 +539,15 @@ export class CanvasDraw extends DisposableImpl {
528
539
  this.fireLoading();
529
540
  });
530
541
  scene.onGameObjectError(gameObject, error => {
542
+ // 创建失败,版本也需要记录,否则加载进步不对;
543
+ this.nodeVersionCache.set(nodePath, newVersion);
531
544
  this.onGameObjectChangeEmitter.fire({
532
545
  type: GameObjectEventType.ERROR,
533
546
  gameObject: gameObject!,
534
547
  node: this.nodeCache.get(nodePath)!,
535
548
  error,
536
549
  });
550
+ this.fireLoading();
537
551
  });
538
552
  this.onGameObjectChangeEmitter.fire({
539
553
  type: GameObjectEventType.CREATE,
@@ -575,6 +589,7 @@ export class CanvasDraw extends DisposableImpl {
575
589
  }).component.id;
576
590
  isComponentUpdate = oldCompId !== newCompId;
577
591
  }
592
+ let timeoutAnimId: NodeJS.Timeout | undefined;
578
593
  const update = () => {
579
594
  const oldVersion = this.nodeVersionCache.get(nodePath);
580
595
  const oldMask = this.maskCache.get(nodePath);
@@ -613,6 +628,26 @@ export class CanvasDraw extends DisposableImpl {
613
628
  isMask: node.isMask,
614
629
  ignoreMask: node.ignoreMask,
615
630
  });
631
+ // 如果元素在动画中,则更新动画
632
+ const timelineService = this.opts.getTimelineService?.();
633
+ if (
634
+ timelineService?.currentTimelineData &&
635
+ d.useAnimationId === timelineService.currentTimelineData.id
636
+ ) {
637
+ clearTimeout(timeoutAnimId);
638
+ timeoutAnimId = setTimeout(() => {
639
+ const animItem = timelineService.animationNode as GameObject<
640
+ GameObjectData & { animation: { frames: TimelineFrame[] } }
641
+ >;
642
+ animItem?.update({
643
+ ...animItem.data,
644
+ animation: {
645
+ ...animItem.data.animation,
646
+ frames: timelineService.currentTimelineData?.frames || [],
647
+ },
648
+ } as GameObjectData & { animation: { frames: TimelineFrame[] } });
649
+ });
650
+ }
616
651
  }
617
652
  };
618
653
  if ((!firstCreate && gameObject?.created) || isComponentUpdate) {
@@ -100,6 +100,7 @@ export class CanvasLayer extends Layer<PlaygroundContext2d> {
100
100
  getComponentContent: (compId, parentNode, getParent) =>
101
101
  this.document?.getComponentContent(compId, parentNode, getParent),
102
102
  isTemplate: this.context.options.isTemplate,
103
+ getTimelineService: () => this.document?.timelineService,
103
104
  });
104
105
  this.toDispose.pushAll([
105
106
  this.canvasDrawer,
@@ -0,0 +1,106 @@
1
+ import * as React from 'react';
2
+ import clsx from 'clsx';
3
+ import { asVec, defaultGradientRange } from '@gedit/canvas-draw';
4
+ import PointEvent from './gradient-edit-layer-point-event';
5
+ import { GradientNodeProps } from './gradient-node';
6
+
7
+ export const GradientConicNode = (props: GradientNodeProps): JSX.Element => {
8
+ const { width, height, data, extendEntity, onChange } = props;
9
+ const { range, colors } = data;
10
+ const {
11
+ angle = defaultGradientRange.angle,
12
+ cx = defaultGradientRange.cx,
13
+ cy = defaultGradientRange.cy,
14
+ } = range || {};
15
+ const r2 = Math.max(width, height);
16
+ const r = r2 / 2;
17
+ return (
18
+ <>
19
+ <div
20
+ className="gedit-extend-radial-box gedit-extend-circle-box"
21
+ style={{
22
+ width: r2,
23
+ height: r2,
24
+ left: -r,
25
+ top: -r,
26
+ transform: `translate(${cx * width}px, ${
27
+ cy * height
28
+ }px) rotate(${angle}deg)`,
29
+ }}
30
+ >
31
+ <PointEvent
32
+ className="gedit-extend-angle-wrapper"
33
+ pointClassName="gedit-extend-angle"
34
+ style={{ transform: `translate(${r2}px, ${r}px)` }}
35
+ onChange={d => {
36
+ const sx = r + r * Math.cos((angle * Math.PI) / 180);
37
+ const sy = r + r * Math.sin((angle * Math.PI) / 180);
38
+ const nx = sx + d.x;
39
+ const ny = sy + d.y;
40
+ const newVec = asVec({ x: r, y: r }, { x: nx, y: ny });
41
+ const newAngle = ((newVec.ang / Math.PI) * 180 + 360) % 360;
42
+ const newRange = data.range || {};
43
+ newRange.angle = parseFloat(newAngle.toFixed(4));
44
+ data.range = newRange;
45
+ onChange(data);
46
+ }}
47
+ />
48
+ {colors.map((item, i) => {
49
+ const { offset, color, uuid } = item;
50
+ const x = r + r * Math.cos(offset * Math.PI * 2);
51
+ const y = r + r * Math.sin(offset * Math.PI * 2);
52
+ return (
53
+ <PointEvent
54
+ key={uuid}
55
+ className="gedit-extend-color-point"
56
+ pointClassName={clsx({
57
+ 'gedit-extend-color-point-active': extendEntity.config
58
+ .selectColorUUid
59
+ ? item.uuid === extendEntity.config.selectColorUUid
60
+ : !i,
61
+ })}
62
+ pointStyle={{ backgroundColor: color }}
63
+ style={{
64
+ transform: `translate(${x}px, ${y}px)`,
65
+ }}
66
+ onChange={d => {
67
+ const currentVec = asVec({ x: r, y: r }, { x, y });
68
+ const sx =
69
+ r + r * Math.cos(currentVec.ang + (angle * Math.PI) / 180);
70
+ const sy =
71
+ r + r * Math.sin(currentVec.ang + (angle * Math.PI) / 180);
72
+ const nx = sx + d.x;
73
+ const ny = sy + d.y;
74
+ const newVec = asVec({ x: r, y: r }, { x: nx, y: ny });
75
+ const newAngle =
76
+ (newVec.ang - (angle * Math.PI) / 180 + Math.PI * 2) %
77
+ (Math.PI * 2);
78
+ const newOffset = newAngle / (Math.PI * 2);
79
+ item.offset = newOffset;
80
+ data.colors = colors.sort((a, b) => a.offset - b.offset);
81
+ onChange(data);
82
+ }}
83
+ onMouseDown={() => {
84
+ extendEntity.updateConfig({ selectColorUUid: uuid });
85
+ }}
86
+ />
87
+ );
88
+ })}
89
+ </div>
90
+ <PointEvent
91
+ className="gedit-extend-origin-wrapper"
92
+ style={{
93
+ transform: `translate(${cx * width}px, ${cy * height}px)`,
94
+ }}
95
+ pointClassName="gedit-extend-origin"
96
+ onChange={d => {
97
+ const newRange = data.range || {};
98
+ newRange.cx = parseFloat((cx + d.x / width).toFixed(4));
99
+ newRange.cy = parseFloat((cy + d.y / height).toFixed(4));
100
+ data.range = newRange;
101
+ onChange(data);
102
+ }}
103
+ />
104
+ </>
105
+ );
106
+ };