chrome-devtools-frontend 1.0.930993 → 1.0.932348
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/config/gni/devtools_grd_files.gni +6 -2
- package/front_end/core/common/ParsedURL.ts +12 -10
- package/front_end/core/host/InspectorFrontendHostAPI.ts +8 -6
- package/front_end/core/i18n/locales/en-US.json +345 -12
- package/front_end/core/i18n/locales/en-XL.json +345 -12
- package/front_end/core/platform/DevToolsPath.ts +34 -0
- package/front_end/core/platform/platform.ts +2 -0
- package/front_end/core/protocol_client/NodeURL.ts +2 -1
- package/front_end/core/sdk/CSSStyleSheetHeader.ts +4 -2
- package/front_end/core/sdk/ChildTargetManager.ts +2 -0
- package/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +4 -2
- package/front_end/core/sdk/DebuggerModel.ts +4 -3
- package/front_end/core/sdk/NetworkRequest.ts +3 -2
- package/front_end/core/sdk/Resource.ts +6 -5
- package/front_end/core/sdk/Script.ts +4 -2
- package/front_end/core/sdk/Target.ts +4 -0
- package/front_end/core/sdk/TracingModel.ts +8 -17
- package/front_end/entrypoint_template.html +1 -1
- package/front_end/entrypoints/formatter_worker/ESTreeWalker.ts +1 -1
- package/front_end/models/bindings/BreakpointManager.ts +6 -3
- package/front_end/models/bindings/ResourceMapping.ts +2 -1
- package/front_end/models/bindings/StylesSourceMapping.ts +2 -1
- package/front_end/models/emulation/DeviceModeModel.ts +1 -1
- package/front_end/models/persistence/IsolatedFileSystem.ts +9 -7
- package/front_end/models/persistence/IsolatedFileSystemManager.ts +8 -7
- package/front_end/models/persistence/PersistenceActions.ts +1 -1
- package/front_end/models/persistence/PlatformFileSystem.ts +4 -3
- package/front_end/models/text_utils/ContentProvider.ts +2 -1
- package/front_end/models/text_utils/StaticContentProvider.ts +4 -2
- package/front_end/models/workspace/UISourceCode.ts +3 -2
- package/front_end/panels/animation/AnimationGroupPreviewUI.ts +25 -25
- package/front_end/panels/animation/AnimationModel.ts +157 -156
- package/front_end/panels/animation/AnimationScreenshotPopover.ts +26 -26
- package/front_end/panels/animation/AnimationTimeline.ts +274 -260
- package/front_end/panels/animation/AnimationUI.ts +155 -145
- package/front_end/panels/application/BackForwardCacheStrings.ts +621 -0
- package/front_end/panels/application/BackForwardCacheView.ts +24 -8
- package/front_end/panels/application/ReportingApiReportsView.ts +3 -2
- package/front_end/panels/application/ReportingApiView.ts +1 -2
- package/front_end/panels/application/backForwardCacheView.css +10 -0
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +48 -40
- package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +37 -37
- package/front_end/panels/browser_debugger/ObjectEventListenersSidebarPane.ts +23 -19
- package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +56 -56
- package/front_end/panels/changes/ChangesView.ts +42 -225
- package/front_end/panels/changes/changes-legacy.ts +0 -2
- package/front_end/panels/changes/changes.ts +0 -6
- package/front_end/panels/changes/changesView.css +2 -69
- package/front_end/panels/changes/module.json +1 -1
- package/front_end/panels/console/ConsolePinPane.ts +80 -75
- package/front_end/panels/console/ConsoleView.ts +1 -9
- package/front_end/panels/console/consolePinPane.css +4 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +2 -1
- package/front_end/panels/security/mainView.css +2 -1
- package/front_end/panels/snippets/ScriptSnippetFileSystem.ts +2 -1
- package/front_end/panels/sources/NavigatorView.ts +5 -2
- package/front_end/panels/sources/SourcesPanel.ts +28 -1
- package/front_end/panels/sources/sources-meta.ts +1 -4
- package/front_end/third_party/codemirror.next/bundle.ts +6 -4
- package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -1
- package/front_end/third_party/codemirror.next/codemirror.next.d.ts +30 -1
- package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
- package/front_end/third_party/codemirror.next/package.json +4 -3
- package/front_end/ui/components/buttons/Button.ts +22 -6
- package/front_end/ui/components/buttons/button.css +50 -4
- package/front_end/ui/components/diff_view/DiffView.ts +288 -0
- package/front_end/ui/components/diff_view/diffView.css +73 -0
- package/front_end/ui/components/diff_view/diff_view.ts +5 -0
- package/front_end/ui/components/docs/button/basic.html +28 -0
- package/front_end/ui/components/docs/button/basic.ts +43 -2
- package/front_end/ui/components/report_view/report.css +1 -0
- package/front_end/ui/components/text_editor/config.ts +34 -1
- package/front_end/ui/legacy/ForwardedInputEventHandler.ts +5 -3
- package/front_end/ui/legacy/components/color_picker/spectrum.css +2 -4
- package/front_end/ui/legacy/themeColors.css +4 -0
- package/package.json +1 -1
- package/scripts/build/generate_css_js_files.js +1 -0
- package/scripts/migration/class-fields/migrate.js +1 -3
- package/front_end/panels/changes/ChangesHighlighter.ts +0 -179
- package/front_end/panels/changes/ChangesTextEditor.ts +0 -96
|
@@ -40,53 +40,53 @@ type CachedElement = {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
export class AnimationUI {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
43
|
+
#animationInternal: AnimationImpl;
|
|
44
|
+
#timeline: AnimationTimeline;
|
|
45
|
+
readonly #parentElement: Element;
|
|
46
|
+
#keyframes?: KeyframeStyle[];
|
|
47
|
+
#nameElement: HTMLElement;
|
|
48
|
+
readonly #svg: Element;
|
|
49
|
+
#activeIntervalGroup: Element;
|
|
50
|
+
#cachedElements: CachedElement[];
|
|
51
|
+
#movementInMs: number;
|
|
52
|
+
#keyboardMovementRateMs: number;
|
|
53
|
+
#color: string;
|
|
54
|
+
#node?: SDK.DOMModel.DOMNode|null;
|
|
55
|
+
#delayLine?: Element;
|
|
56
|
+
#endDelayLine?: Element;
|
|
57
|
+
#tailGroup?: Element;
|
|
58
|
+
#mouseEventType?: Events;
|
|
59
|
+
#keyframeMoved?: number|null;
|
|
60
|
+
#downMouseX?: number;
|
|
61
61
|
|
|
62
62
|
constructor(animation: AnimationImpl, timeline: AnimationTimeline, parentElement: Element) {
|
|
63
|
-
this
|
|
64
|
-
this
|
|
65
|
-
this
|
|
63
|
+
this.#animationInternal = animation;
|
|
64
|
+
this.#timeline = timeline;
|
|
65
|
+
this.#parentElement = parentElement;
|
|
66
66
|
|
|
67
|
-
const keyframesRule = this
|
|
67
|
+
const keyframesRule = this.#animationInternal.source().keyframesRule();
|
|
68
68
|
if (keyframesRule) {
|
|
69
|
-
this
|
|
69
|
+
this.#keyframes = keyframesRule.keyframes();
|
|
70
70
|
}
|
|
71
|
-
this
|
|
72
|
-
this
|
|
71
|
+
this.#nameElement = (parentElement.createChild('div', 'animation-name') as HTMLElement);
|
|
72
|
+
this.#nameElement.textContent = this.#animationInternal.name();
|
|
73
73
|
|
|
74
|
-
this
|
|
75
|
-
this
|
|
76
|
-
(this
|
|
77
|
-
this
|
|
78
|
-
this
|
|
74
|
+
this.#svg = UI.UIUtils.createSVGChild(parentElement, 'svg', 'animation-ui');
|
|
75
|
+
this.#svg.setAttribute('height', Options.AnimationSVGHeight.toString());
|
|
76
|
+
(this.#svg as HTMLElement).style.marginLeft = '-' + Options.AnimationMargin + 'px';
|
|
77
|
+
this.#svg.addEventListener('contextmenu', this.onContextMenu.bind(this));
|
|
78
|
+
this.#activeIntervalGroup = UI.UIUtils.createSVGChild(this.#svg, 'g');
|
|
79
79
|
UI.UIUtils.installDragHandle(
|
|
80
|
-
this
|
|
80
|
+
this.#activeIntervalGroup, this.mouseDown.bind(this, Events.AnimationDrag, null), this.mouseMove.bind(this),
|
|
81
81
|
this.mouseUp.bind(this), '-webkit-grabbing', '-webkit-grab');
|
|
82
82
|
AnimationUI.installDragHandleKeyboard(
|
|
83
|
-
this
|
|
83
|
+
this.#activeIntervalGroup, this.keydownMove.bind(this, Events.AnimationDrag, null));
|
|
84
84
|
|
|
85
|
-
this
|
|
85
|
+
this.#cachedElements = [];
|
|
86
86
|
|
|
87
|
-
this
|
|
88
|
-
this
|
|
89
|
-
this
|
|
87
|
+
this.#movementInMs = 0;
|
|
88
|
+
this.#keyboardMovementRateMs = 50;
|
|
89
|
+
this.#color = AnimationUI.colorForAnimation(this.#animationInternal);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
static colorForAnimation(animation: AnimationImpl): string {
|
|
@@ -106,11 +106,19 @@ export class AnimationUI {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
animation(): AnimationImpl {
|
|
109
|
-
return this
|
|
109
|
+
return this.#animationInternal;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
get nameElement(): HTMLElement {
|
|
113
|
+
return this.#nameElement;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
get svg(): Element {
|
|
117
|
+
return this.#svg;
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
setNode(node: SDK.DOMModel.DOMNode|null): void {
|
|
113
|
-
this
|
|
121
|
+
this.#node = node;
|
|
114
122
|
}
|
|
115
123
|
|
|
116
124
|
private createLine(parentElement: HTMLElement, className: string): Element {
|
|
@@ -118,12 +126,12 @@ export class AnimationUI {
|
|
|
118
126
|
line.setAttribute('x1', Options.AnimationMargin.toString());
|
|
119
127
|
line.setAttribute('y1', Options.AnimationHeight.toString());
|
|
120
128
|
line.setAttribute('y2', Options.AnimationHeight.toString());
|
|
121
|
-
(line as HTMLElement).style.stroke = this
|
|
129
|
+
(line as HTMLElement).style.stroke = this.#color;
|
|
122
130
|
return line;
|
|
123
131
|
}
|
|
124
132
|
|
|
125
133
|
private drawAnimationLine(iteration: number, parentElement: HTMLElement): void {
|
|
126
|
-
const cache = this
|
|
134
|
+
const cache = this.#cachedElements[iteration];
|
|
127
135
|
if (!cache.animationLine) {
|
|
128
136
|
cache.animationLine = (this.createLine(parentElement, 'animation-line') as HTMLElement);
|
|
129
137
|
}
|
|
@@ -132,36 +140,38 @@ export class AnimationUI {
|
|
|
132
140
|
}
|
|
133
141
|
|
|
134
142
|
cache.animationLine.setAttribute(
|
|
135
|
-
'x2', (this.duration() * this
|
|
143
|
+
'x2', (this.duration() * this.#timeline.pixelMsRatio() + Options.AnimationMargin).toFixed(2));
|
|
136
144
|
}
|
|
137
145
|
|
|
138
146
|
private drawDelayLine(parentElement: HTMLElement): void {
|
|
139
|
-
if (!this
|
|
140
|
-
this
|
|
141
|
-
this
|
|
147
|
+
if (!this.#delayLine || !this.#endDelayLine) {
|
|
148
|
+
this.#delayLine = this.createLine(parentElement, 'animation-delay-line');
|
|
149
|
+
this.#endDelayLine = this.createLine(parentElement, 'animation-delay-line');
|
|
142
150
|
}
|
|
143
|
-
const fill = this
|
|
144
|
-
this
|
|
151
|
+
const fill = this.#animationInternal.source().fill();
|
|
152
|
+
this.#delayLine.classList.toggle('animation-fill', fill === 'backwards' || fill === 'both');
|
|
145
153
|
const margin = Options.AnimationMargin;
|
|
146
|
-
this
|
|
147
|
-
this
|
|
154
|
+
this.#delayLine.setAttribute('x1', margin.toString());
|
|
155
|
+
this.#delayLine.setAttribute('x2', (this.delay() * this.#timeline.pixelMsRatio() + margin).toFixed(2));
|
|
148
156
|
const forwardsFill = fill === 'forwards' || fill === 'both';
|
|
149
|
-
this
|
|
157
|
+
this.#endDelayLine.classList.toggle('animation-fill', forwardsFill);
|
|
150
158
|
const leftMargin = Math.min(
|
|
151
|
-
this
|
|
152
|
-
(this.delay() + this.duration() * this
|
|
153
|
-
|
|
154
|
-
this
|
|
155
|
-
this
|
|
159
|
+
this.#timeline.width(),
|
|
160
|
+
(this.delay() + this.duration() * this.#animationInternal.source().iterations()) *
|
|
161
|
+
this.#timeline.pixelMsRatio());
|
|
162
|
+
(this.#endDelayLine as HTMLElement).style.transform = 'translateX(' + leftMargin.toFixed(2) + 'px)';
|
|
163
|
+
this.#endDelayLine.setAttribute('x1', margin.toString());
|
|
164
|
+
this.#endDelayLine.setAttribute(
|
|
156
165
|
'x2',
|
|
157
|
-
forwardsFill ?
|
|
158
|
-
|
|
166
|
+
forwardsFill ?
|
|
167
|
+
(this.#timeline.width() - leftMargin + margin).toFixed(2) :
|
|
168
|
+
(this.#animationInternal.source().endDelay() * this.#timeline.pixelMsRatio() + margin).toFixed(2));
|
|
159
169
|
}
|
|
160
170
|
|
|
161
171
|
private drawPoint(iteration: number, parentElement: Element, x: number, keyframeIndex: number, attachEvents: boolean):
|
|
162
172
|
void {
|
|
163
|
-
if (this
|
|
164
|
-
this
|
|
173
|
+
if (this.#cachedElements[iteration].keyframePoints[keyframeIndex]) {
|
|
174
|
+
this.#cachedElements[iteration].keyframePoints[keyframeIndex].setAttribute('cx', x.toFixed(2));
|
|
165
175
|
return;
|
|
166
176
|
}
|
|
167
177
|
|
|
@@ -171,7 +181,7 @@ export class AnimationUI {
|
|
|
171
181
|
HTMLElement);
|
|
172
182
|
circle.setAttribute('cx', x.toFixed(2));
|
|
173
183
|
circle.setAttribute('cy', Options.AnimationHeight.toString());
|
|
174
|
-
circle.style.stroke = this
|
|
184
|
+
circle.style.stroke = this.#color;
|
|
175
185
|
circle.setAttribute('r', (Options.AnimationMargin / 2).toString());
|
|
176
186
|
circle.tabIndex = 0;
|
|
177
187
|
UI.ARIAUtils.setAccessibleName(
|
|
@@ -180,9 +190,9 @@ export class AnimationUI {
|
|
|
180
190
|
i18nString(UIStrings.animationKeyframeSlider));
|
|
181
191
|
|
|
182
192
|
if (keyframeIndex <= 0) {
|
|
183
|
-
circle.style.fill = this
|
|
193
|
+
circle.style.fill = this.#color;
|
|
184
194
|
}
|
|
185
|
-
this
|
|
195
|
+
this.#cachedElements[iteration].keyframePoints[keyframeIndex] = (circle as HTMLElement);
|
|
186
196
|
|
|
187
197
|
if (!attachEvents) {
|
|
188
198
|
return;
|
|
@@ -215,7 +225,7 @@ export class AnimationUI {
|
|
|
215
225
|
}
|
|
216
226
|
|
|
217
227
|
const bezier = UI.Geometry.CubicBezier.parse(easing);
|
|
218
|
-
const cache = this
|
|
228
|
+
const cache = this.#cachedElements[iteration].keyframeRender;
|
|
219
229
|
if (!cache[keyframeIndex]) {
|
|
220
230
|
const svg = bezier ? UI.UIUtils.createSVGChild(parentElement, 'path', 'animation-keyframe') :
|
|
221
231
|
UI.UIUtils.createSVGChild(parentElement, 'g', 'animation-keyframe-step');
|
|
@@ -223,16 +233,16 @@ export class AnimationUI {
|
|
|
223
233
|
}
|
|
224
234
|
const group = cache[keyframeIndex];
|
|
225
235
|
group.tabIndex = 0;
|
|
226
|
-
UI.ARIAUtils.setAccessibleName(group, i18nString(UIStrings.sSlider, {PH1: this
|
|
236
|
+
UI.ARIAUtils.setAccessibleName(group, i18nString(UIStrings.sSlider, {PH1: this.#animationInternal.name()}));
|
|
227
237
|
group.style.transform = 'translateX(' + leftDistance.toFixed(2) + 'px)';
|
|
228
238
|
|
|
229
239
|
if (easing === 'linear') {
|
|
230
|
-
group.style.fill = this
|
|
240
|
+
group.style.fill = this.#color;
|
|
231
241
|
const height = InlineEditor.BezierUI.Height;
|
|
232
242
|
group.setAttribute(
|
|
233
243
|
'd', ['M', 0, height, 'L', 0, 5, 'L', width.toFixed(2), 5, 'L', width.toFixed(2), height, 'Z'].join(' '));
|
|
234
244
|
} else if (bezier) {
|
|
235
|
-
group.style.fill = this
|
|
245
|
+
group.style.fill = this.#color;
|
|
236
246
|
InlineEditor.BezierUI.BezierUI.drawVelocityChart(bezier, group, width);
|
|
237
247
|
} else {
|
|
238
248
|
const stepFunction = StepTimingFunction.parse(easing);
|
|
@@ -241,42 +251,42 @@ export class AnimationUI {
|
|
|
241
251
|
if (stepFunction) {
|
|
242
252
|
const offsetWeight = offsetMap[stepFunction.stepAtPosition];
|
|
243
253
|
for (let i = 0; i < stepFunction.steps; i++) {
|
|
244
|
-
createStepLine(group, (i + offsetWeight) * width / stepFunction.steps, this
|
|
254
|
+
createStepLine(group, (i + offsetWeight) * width / stepFunction.steps, this.#color);
|
|
245
255
|
}
|
|
246
256
|
}
|
|
247
257
|
}
|
|
248
258
|
}
|
|
249
259
|
|
|
250
260
|
redraw(): void {
|
|
251
|
-
const maxWidth = this
|
|
261
|
+
const maxWidth = this.#timeline.width() - Options.AnimationMargin;
|
|
252
262
|
|
|
253
|
-
this
|
|
254
|
-
(this
|
|
255
|
-
'translateX(' + (this.delay() * this
|
|
263
|
+
this.#svg.setAttribute('width', (maxWidth + 2 * Options.AnimationMargin).toFixed(2));
|
|
264
|
+
(this.#activeIntervalGroup as HTMLElement).style.transform =
|
|
265
|
+
'translateX(' + (this.delay() * this.#timeline.pixelMsRatio()).toFixed(2) + 'px)';
|
|
256
266
|
|
|
257
|
-
this
|
|
258
|
-
'translateX(' + (this.delay() * this
|
|
259
|
-
this
|
|
260
|
-
this.drawDelayLine((this
|
|
267
|
+
this.#nameElement.style.transform =
|
|
268
|
+
'translateX(' + (this.delay() * this.#timeline.pixelMsRatio() + Options.AnimationMargin).toFixed(2) + 'px)';
|
|
269
|
+
this.#nameElement.style.width = (this.duration() * this.#timeline.pixelMsRatio()).toFixed(2) + 'px';
|
|
270
|
+
this.drawDelayLine((this.#svg as HTMLElement));
|
|
261
271
|
|
|
262
|
-
if (this
|
|
272
|
+
if (this.#animationInternal.type() === 'CSSTransition') {
|
|
263
273
|
this.renderTransition();
|
|
264
274
|
return;
|
|
265
275
|
}
|
|
266
276
|
|
|
267
|
-
this.renderIteration(this
|
|
268
|
-
if (!this
|
|
269
|
-
this
|
|
277
|
+
this.renderIteration(this.#activeIntervalGroup, 0);
|
|
278
|
+
if (!this.#tailGroup) {
|
|
279
|
+
this.#tailGroup = UI.UIUtils.createSVGChild(this.#activeIntervalGroup, 'g', 'animation-tail-iterations');
|
|
270
280
|
}
|
|
271
|
-
const iterationWidth = this.duration() * this
|
|
281
|
+
const iterationWidth = this.duration() * this.#timeline.pixelMsRatio();
|
|
272
282
|
let iteration;
|
|
273
|
-
for (iteration = 1; iteration < this
|
|
274
|
-
iterationWidth * (iteration - 1) < this
|
|
283
|
+
for (iteration = 1; iteration < this.#animationInternal.source().iterations() &&
|
|
284
|
+
iterationWidth * (iteration - 1) < this.#timeline.width();
|
|
275
285
|
iteration++) {
|
|
276
|
-
this.renderIteration(this
|
|
286
|
+
this.renderIteration(this.#tailGroup, iteration);
|
|
277
287
|
}
|
|
278
|
-
while (iteration < this
|
|
279
|
-
const poppedElement = this
|
|
288
|
+
while (iteration < this.#cachedElements.length) {
|
|
289
|
+
const poppedElement = this.#cachedElements.pop();
|
|
280
290
|
if (poppedElement && poppedElement.group) {
|
|
281
291
|
poppedElement.group.remove();
|
|
282
292
|
}
|
|
@@ -284,82 +294,82 @@ export class AnimationUI {
|
|
|
284
294
|
}
|
|
285
295
|
|
|
286
296
|
private renderTransition(): void {
|
|
287
|
-
const activeIntervalGroup = (this
|
|
288
|
-
if (!this
|
|
289
|
-
this
|
|
297
|
+
const activeIntervalGroup = (this.#activeIntervalGroup as HTMLElement);
|
|
298
|
+
if (!this.#cachedElements[0]) {
|
|
299
|
+
this.#cachedElements[0] = {animationLine: null, keyframePoints: {}, keyframeRender: {}, group: null};
|
|
290
300
|
}
|
|
291
301
|
this.drawAnimationLine(0, activeIntervalGroup);
|
|
292
302
|
this.renderKeyframe(
|
|
293
|
-
0, 0, activeIntervalGroup, Options.AnimationMargin, this.duration() * this
|
|
294
|
-
this
|
|
303
|
+
0, 0, activeIntervalGroup, Options.AnimationMargin, this.duration() * this.#timeline.pixelMsRatio(),
|
|
304
|
+
this.#animationInternal.source().easing());
|
|
295
305
|
this.drawPoint(0, activeIntervalGroup, Options.AnimationMargin, 0, true);
|
|
296
306
|
this.drawPoint(
|
|
297
|
-
0, activeIntervalGroup, this.duration() * this
|
|
307
|
+
0, activeIntervalGroup, this.duration() * this.#timeline.pixelMsRatio() + Options.AnimationMargin, -1, true);
|
|
298
308
|
}
|
|
299
309
|
|
|
300
310
|
private renderIteration(parentElement: Element, iteration: number): void {
|
|
301
|
-
if (!this
|
|
302
|
-
this
|
|
311
|
+
if (!this.#cachedElements[iteration]) {
|
|
312
|
+
this.#cachedElements[iteration] = {
|
|
303
313
|
animationLine: null,
|
|
304
314
|
keyframePoints: {},
|
|
305
315
|
keyframeRender: {},
|
|
306
316
|
group: (UI.UIUtils.createSVGChild(parentElement, 'g') as HTMLElement),
|
|
307
317
|
};
|
|
308
318
|
}
|
|
309
|
-
const group = this
|
|
319
|
+
const group = this.#cachedElements[iteration].group;
|
|
310
320
|
if (!group) {
|
|
311
321
|
return;
|
|
312
322
|
}
|
|
313
323
|
|
|
314
324
|
group.style.transform =
|
|
315
|
-
'translateX(' + (iteration * this.duration() * this
|
|
325
|
+
'translateX(' + (iteration * this.duration() * this.#timeline.pixelMsRatio()).toFixed(2) + 'px)';
|
|
316
326
|
this.drawAnimationLine(iteration, group);
|
|
317
|
-
if (this
|
|
318
|
-
for (let i = 0; i < this
|
|
319
|
-
const leftDistance = this.offset(i) * this.duration() * this
|
|
320
|
-
const width = this.duration() * (this.offset(i + 1) - this.offset(i)) * this
|
|
321
|
-
this.renderKeyframe(iteration, i, group, leftDistance, width, this
|
|
327
|
+
if (this.#keyframes && this.#keyframes.length > 1) {
|
|
328
|
+
for (let i = 0; i < this.#keyframes.length - 1; i++) {
|
|
329
|
+
const leftDistance = this.offset(i) * this.duration() * this.#timeline.pixelMsRatio() + Options.AnimationMargin;
|
|
330
|
+
const width = this.duration() * (this.offset(i + 1) - this.offset(i)) * this.#timeline.pixelMsRatio();
|
|
331
|
+
this.renderKeyframe(iteration, i, group, leftDistance, width, this.#keyframes[i].easing());
|
|
322
332
|
if (i || (!i && iteration === 0)) {
|
|
323
333
|
this.drawPoint(iteration, group, leftDistance, i, iteration === 0);
|
|
324
334
|
}
|
|
325
335
|
}
|
|
326
336
|
}
|
|
327
337
|
this.drawPoint(
|
|
328
|
-
iteration, group, this.duration() * this
|
|
338
|
+
iteration, group, this.duration() * this.#timeline.pixelMsRatio() + Options.AnimationMargin, -1,
|
|
329
339
|
iteration === 0);
|
|
330
340
|
}
|
|
331
341
|
|
|
332
342
|
private delay(): number {
|
|
333
|
-
let delay = this
|
|
334
|
-
if (this
|
|
335
|
-
delay += this
|
|
343
|
+
let delay = this.#animationInternal.source().delay();
|
|
344
|
+
if (this.#mouseEventType === Events.AnimationDrag || this.#mouseEventType === Events.StartEndpointMove) {
|
|
345
|
+
delay += this.#movementInMs;
|
|
336
346
|
}
|
|
337
347
|
// FIXME: add support for negative start delay
|
|
338
348
|
return Math.max(0, delay);
|
|
339
349
|
}
|
|
340
350
|
|
|
341
351
|
private duration(): number {
|
|
342
|
-
let duration = this
|
|
343
|
-
if (this
|
|
344
|
-
duration += this
|
|
345
|
-
} else if (this
|
|
346
|
-
duration -= Math.max(this
|
|
352
|
+
let duration = this.#animationInternal.source().duration();
|
|
353
|
+
if (this.#mouseEventType === Events.FinishEndpointMove) {
|
|
354
|
+
duration += this.#movementInMs;
|
|
355
|
+
} else if (this.#mouseEventType === Events.StartEndpointMove) {
|
|
356
|
+
duration -= Math.max(this.#movementInMs, -this.#animationInternal.source().delay());
|
|
347
357
|
// Cannot have negative delay
|
|
348
358
|
}
|
|
349
359
|
return Math.max(0, duration);
|
|
350
360
|
}
|
|
351
361
|
|
|
352
362
|
private offset(i: number): number {
|
|
353
|
-
if (!this
|
|
363
|
+
if (!this.#keyframes) {
|
|
354
364
|
throw new Error('Unable to calculate offset; keyframes do not exist');
|
|
355
365
|
}
|
|
356
366
|
|
|
357
|
-
let offset = this
|
|
358
|
-
if (this
|
|
359
|
-
console.assert(i > 0 && i < this
|
|
360
|
-
offset += this
|
|
361
|
-
offset = Math.max(offset, this
|
|
362
|
-
offset = Math.min(offset, this
|
|
367
|
+
let offset = this.#keyframes[i].offsetAsNumber();
|
|
368
|
+
if (this.#mouseEventType === Events.KeyframeMove && i === this.#keyframeMoved) {
|
|
369
|
+
console.assert(i > 0 && i < this.#keyframes.length - 1, 'First and last keyframe cannot be moved');
|
|
370
|
+
offset += this.#movementInMs / this.#animationInternal.source().duration();
|
|
371
|
+
offset = Math.max(offset, this.#keyframes[i - 1].offsetAsNumber());
|
|
372
|
+
offset = Math.min(offset, this.#keyframes[i + 1].offsetAsNumber());
|
|
363
373
|
}
|
|
364
374
|
return offset;
|
|
365
375
|
}
|
|
@@ -369,80 +379,80 @@ export class AnimationUI {
|
|
|
369
379
|
if (mouseEvent.buttons === 2) {
|
|
370
380
|
return false;
|
|
371
381
|
}
|
|
372
|
-
if (this
|
|
382
|
+
if (this.#svg.enclosingNodeOrSelfWithClass('animation-node-removed')) {
|
|
373
383
|
return false;
|
|
374
384
|
}
|
|
375
|
-
this
|
|
376
|
-
this
|
|
377
|
-
this
|
|
385
|
+
this.#mouseEventType = mouseEventType;
|
|
386
|
+
this.#keyframeMoved = keyframeIndex;
|
|
387
|
+
this.#downMouseX = mouseEvent.clientX;
|
|
378
388
|
event.consume(true);
|
|
379
|
-
if (this
|
|
380
|
-
Common.Revealer.reveal(this
|
|
389
|
+
if (this.#node) {
|
|
390
|
+
Common.Revealer.reveal(this.#node);
|
|
381
391
|
}
|
|
382
392
|
return true;
|
|
383
393
|
}
|
|
384
394
|
|
|
385
395
|
private mouseMove(event: Event): void {
|
|
386
396
|
const mouseEvent = (event as MouseEvent);
|
|
387
|
-
this.setMovementAndRedraw((mouseEvent.clientX - (this
|
|
397
|
+
this.setMovementAndRedraw((mouseEvent.clientX - (this.#downMouseX || 0)) / this.#timeline.pixelMsRatio());
|
|
388
398
|
}
|
|
389
399
|
|
|
390
400
|
private setMovementAndRedraw(movement: number): void {
|
|
391
|
-
this
|
|
392
|
-
if (this.delay() + this.duration() > this
|
|
393
|
-
this
|
|
401
|
+
this.#movementInMs = movement;
|
|
402
|
+
if (this.delay() + this.duration() > this.#timeline.duration() * 0.8) {
|
|
403
|
+
this.#timeline.setDuration(this.#timeline.duration() * 1.2);
|
|
394
404
|
}
|
|
395
405
|
this.redraw();
|
|
396
406
|
}
|
|
397
407
|
|
|
398
408
|
private mouseUp(event: Event): void {
|
|
399
409
|
const mouseEvent = (event as MouseEvent);
|
|
400
|
-
this
|
|
410
|
+
this.#movementInMs = (mouseEvent.clientX - (this.#downMouseX || 0)) / this.#timeline.pixelMsRatio();
|
|
401
411
|
|
|
402
412
|
// Commit changes
|
|
403
|
-
if (this
|
|
404
|
-
if (this
|
|
405
|
-
this
|
|
413
|
+
if (this.#mouseEventType === Events.KeyframeMove) {
|
|
414
|
+
if (this.#keyframes && this.#keyframeMoved !== null && typeof this.#keyframeMoved !== 'undefined') {
|
|
415
|
+
this.#keyframes[this.#keyframeMoved].setOffset(this.offset(this.#keyframeMoved));
|
|
406
416
|
}
|
|
407
417
|
} else {
|
|
408
|
-
this
|
|
418
|
+
this.#animationInternal.setTiming(this.duration(), this.delay());
|
|
409
419
|
}
|
|
410
420
|
|
|
411
|
-
this
|
|
421
|
+
this.#movementInMs = 0;
|
|
412
422
|
this.redraw();
|
|
413
423
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
424
|
+
this.#mouseEventType = undefined;
|
|
425
|
+
this.#downMouseX = undefined;
|
|
426
|
+
this.#keyframeMoved = undefined;
|
|
417
427
|
}
|
|
418
428
|
|
|
419
429
|
private keydownMove(mouseEventType: Events, keyframeIndex: number|null, event: Event): void {
|
|
420
430
|
const keyboardEvent = (event as KeyboardEvent);
|
|
421
|
-
this
|
|
422
|
-
this
|
|
431
|
+
this.#mouseEventType = mouseEventType;
|
|
432
|
+
this.#keyframeMoved = keyframeIndex;
|
|
423
433
|
switch (keyboardEvent.key) {
|
|
424
434
|
case 'ArrowLeft':
|
|
425
435
|
case 'ArrowUp':
|
|
426
|
-
this
|
|
436
|
+
this.#movementInMs = -this.#keyboardMovementRateMs;
|
|
427
437
|
break;
|
|
428
438
|
case 'ArrowRight':
|
|
429
439
|
case 'ArrowDown':
|
|
430
|
-
this
|
|
440
|
+
this.#movementInMs = this.#keyboardMovementRateMs;
|
|
431
441
|
break;
|
|
432
442
|
default:
|
|
433
443
|
return;
|
|
434
444
|
}
|
|
435
|
-
if (this
|
|
436
|
-
if (this
|
|
437
|
-
this
|
|
445
|
+
if (this.#mouseEventType === Events.KeyframeMove) {
|
|
446
|
+
if (this.#keyframes && this.#keyframeMoved !== null) {
|
|
447
|
+
this.#keyframes[this.#keyframeMoved].setOffset(this.offset(this.#keyframeMoved));
|
|
438
448
|
}
|
|
439
449
|
} else {
|
|
440
|
-
this
|
|
450
|
+
this.#animationInternal.setTiming(this.duration(), this.delay());
|
|
441
451
|
}
|
|
442
452
|
this.setMovementAndRedraw(0);
|
|
443
453
|
|
|
444
|
-
|
|
445
|
-
|
|
454
|
+
this.#mouseEventType = undefined;
|
|
455
|
+
this.#keyframeMoved = undefined;
|
|
446
456
|
|
|
447
457
|
event.consume(true);
|
|
448
458
|
}
|
|
@@ -457,7 +467,7 @@ export class AnimationUI {
|
|
|
457
467
|
contextMenu.show();
|
|
458
468
|
}
|
|
459
469
|
|
|
460
|
-
this
|
|
470
|
+
this.#animationInternal.remoteObjectPromise().then(showContextMenu);
|
|
461
471
|
event.consume(true);
|
|
462
472
|
}
|
|
463
473
|
}
|