@woosh/meep-engine 2.131.35 → 2.131.37
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/build/bundle-worker-image-decoder.js +1 -1
- package/package.json +1 -1
- package/src/core/binary/BinaryBuffer.d.ts +14 -0
- package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
- package/src/core/binary/BinaryBuffer.js +27 -0
- package/src/core/binary/allocator/OffsetAllocator.d.ts +5 -0
- package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
- package/src/core/binary/allocator/OffsetAllocator.js +6 -0
- package/src/core/geom/3d/aabb/AABB3.d.ts +17 -2
- package/src/core/geom/3d/aabb/AABB3.d.ts.map +1 -1
- package/src/core/geom/3d/aabb/AABB3.js +29 -2
- package/src/core/geom/normalize_angle_rad.d.ts.map +1 -1
- package/src/core/geom/normalize_angle_rad.js +3 -0
- package/src/core/math/hash/computeHashFloatArray.d.ts +3 -2
- package/src/core/math/hash/computeHashFloatArray.d.ts.map +1 -1
- package/src/core/math/hash/computeHashFloatArray.js +2 -1
- package/src/core/process/undo/ActionProcessor.d.ts.map +1 -1
- package/src/core/process/undo/ActionProcessor.js +3 -1
- package/src/engine/animation/curve/actionProcessorOperations/applyActionChange.d.ts +34 -0
- package/src/engine/animation/curve/actionProcessorOperations/applyActionChange.d.ts.map +1 -0
- package/src/engine/animation/curve/actionProcessorOperations/applyActionChange.js +61 -0
- package/src/engine/animation/curve/actionProcessorOperations/curveActions.d.ts +107 -0
- package/src/engine/animation/curve/actionProcessorOperations/curveActions.d.ts.map +1 -0
- package/src/engine/animation/curve/actionProcessorOperations/curveActions.js +202 -0
- package/src/engine/animation/curve/compression/prototypeCurveCompression.js +24 -3
- package/src/engine/animation/curve/draw/buildReadOnlyDisplay.d.ts +3 -0
- package/src/engine/animation/curve/draw/buildReadOnlyDisplay.d.ts.map +1 -0
- package/src/engine/animation/curve/draw/buildReadOnlyDisplay.js +14 -0
- package/src/engine/animation/curve/draw/build_tangent_editor.d.ts +6 -1
- package/src/engine/animation/curve/draw/build_tangent_editor.d.ts.map +1 -1
- package/src/engine/animation/curve/draw/build_tangent_editor.js +220 -51
- package/src/engine/animation/curve/draw/displayMousePos.d.ts +7 -0
- package/src/engine/animation/curve/draw/displayMousePos.d.ts.map +1 -0
- package/src/engine/animation/curve/draw/displayMousePos.js +41 -0
- package/src/engine/animation/curve/draw/isInjectedKeyframeInBounds.d.ts +26 -0
- package/src/engine/animation/curve/draw/isInjectedKeyframeInBounds.d.ts.map +1 -0
- package/src/engine/animation/curve/draw/isInjectedKeyframeInBounds.js +93 -0
- package/src/engine/animation/curve/draw/position_canvas_to_curve.d.ts +12 -0
- package/src/engine/animation/curve/draw/position_canvas_to_curve.d.ts.map +1 -0
- package/src/engine/animation/curve/draw/position_canvas_to_curve.js +24 -0
- package/src/engine/animation/curve/draw/position_curve_to_canvas.d.ts +12 -0
- package/src/engine/animation/curve/draw/position_curve_to_canvas.d.ts.map +1 -0
- package/src/engine/animation/curve/draw/position_curve_to_canvas.js +25 -0
- package/src/engine/animation/curve/editor/CurveEditorView.d.ts +22 -0
- package/src/engine/animation/curve/editor/CurveEditorView.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/CurveEditorView.js +337 -0
- package/src/engine/animation/curve/editor/DragHandler.d.ts +17 -0
- package/src/engine/animation/curve/editor/DragHandler.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/DragHandler.js +35 -0
- package/src/engine/animation/curve/editor/KeyframeStateManager.d.ts +33 -0
- package/src/engine/animation/curve/editor/KeyframeStateManager.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/KeyframeStateManager.js +39 -0
- package/src/engine/animation/curve/editor/OperationRouter.d.ts +18 -0
- package/src/engine/animation/curve/editor/OperationRouter.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/OperationRouter.js +44 -0
- package/src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.d.ts +14 -0
- package/src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.js +63 -0
- package/src/engine/animation/curve/editor/canvas2dDrawWorldGrid.d.ts +28 -0
- package/src/engine/animation/curve/editor/canvas2dDrawWorldGrid.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/canvas2dDrawWorldGrid.js +70 -0
- package/src/engine/animation/curve/editor/canvas2dPlotCurveLine.d.ts +13 -0
- package/src/engine/animation/curve/editor/canvas2dPlotCurveLine.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/canvas2dPlotCurveLine.js +116 -0
- package/src/engine/animation/curve/editor/canvas2dPlotCurvePoints.d.ts +11 -0
- package/src/engine/animation/curve/editor/canvas2dPlotCurvePoints.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/canvas2dPlotCurvePoints.js +69 -0
- package/src/engine/animation/curve/editor/createCurveUploader.d.ts +8 -0
- package/src/engine/animation/curve/editor/createCurveUploader.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/createCurveUploader.js +25 -0
- package/src/engine/animation/curve/editor/createKeyCoordinateLabelView.d.ts +3 -0
- package/src/engine/animation/curve/editor/createKeyCoordinateLabelView.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/createKeyCoordinateLabelView.js +15 -0
- package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.d.ts +24 -0
- package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.js +142 -0
- package/src/engine/animation/curve/editor/createKeyframeMarker.d.ts +2 -0
- package/src/engine/animation/curve/editor/createKeyframeMarker.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/createKeyframeMarker.js +42 -0
- package/src/engine/animation/curve/editor/createPanTool.d.ts +11 -0
- package/src/engine/animation/curve/editor/createPanTool.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/createPanTool.js +41 -0
- package/src/engine/animation/curve/editor/createSelectionBoxTool.d.ts +14 -0
- package/src/engine/animation/curve/editor/createSelectionBoxTool.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/createSelectionBoxTool.js +93 -0
- package/src/engine/animation/curve/editor/deleteKeyframeAndResetVars.d.ts +8 -0
- package/src/engine/animation/curve/editor/deleteKeyframeAndResetVars.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/deleteKeyframeAndResetVars.js +24 -0
- package/src/engine/animation/curve/editor/determineUnitSpacing.d.ts +8 -0
- package/src/engine/animation/curve/editor/determineUnitSpacing.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/determineUnitSpacing.js +33 -0
- package/src/engine/animation/curve/editor/formatTruncDecimal.d.ts +7 -0
- package/src/engine/animation/curve/editor/formatTruncDecimal.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/formatTruncDecimal.js +14 -0
- package/src/engine/animation/curve/editor/inputEventHandlers.d.ts +32 -0
- package/src/engine/animation/curve/editor/inputEventHandlers.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/inputEventHandlers.js +125 -0
- package/src/engine/animation/curve/editor/uiContext.d.ts +10 -0
- package/src/engine/animation/curve/editor/uiContext.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/uiContext.js +18 -0
- package/src/engine/animation/curve/editor/updateAxisRange.d.ts +11 -0
- package/src/engine/animation/curve/editor/updateAxisRange.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/updateAxisRange.js +23 -0
- package/src/engine/animation/curve/editor/updateKeyframePosition.d.ts +9 -0
- package/src/engine/animation/curve/editor/updateKeyframePosition.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/updateKeyframePosition.js +38 -0
- package/src/engine/animation/curve/editor/updateMarkerPosition.d.ts +2 -0
- package/src/engine/animation/curve/editor/updateMarkerPosition.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/updateMarkerPosition.js +12 -0
- package/src/engine/animation/curve/editor/updateMarkerVisual.d.ts +9 -0
- package/src/engine/animation/curve/editor/updateMarkerVisual.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/updateMarkerVisual.js +53 -0
- package/src/engine/animation/curve/editor/uploadViaElement.d.ts +7 -0
- package/src/engine/animation/curve/editor/uploadViaElement.d.ts.map +1 -0
- package/src/engine/animation/curve/editor/uploadViaElement.js +35 -0
- package/src/engine/physics/gjk/NOTES.md +2 -0
- package/src/engine/animation/curve/draw/build_curve_editor.d.ts +0 -9
- package/src/engine/animation/curve/draw/build_curve_editor.d.ts.map +0 -1
- package/src/engine/animation/curve/draw/build_curve_editor.js +0 -362
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
import Vector2 from "../../../../core/geom/Vector2.js";
|
|
2
|
+
import AABB2 from "../../../../core/geom/2d/aabb/AABB2.js";
|
|
3
|
+
import {ActionProcessor} from "../../../../core/process/undo/ActionProcessor.js";
|
|
4
|
+
import EmptyView from "../../../../view/elements/EmptyView.js";
|
|
5
|
+
import {CanvasView} from "../../../../view/elements/CanvasView.js";
|
|
6
|
+
import {createKeyCoordinateLabelView} from "./createKeyCoordinateLabelView.js";
|
|
7
|
+
import Signal from "../../../../core/events/signal/Signal.js";
|
|
8
|
+
import KeyboardDevice from "../../../input/devices/KeyboardDevice.js";
|
|
9
|
+
import {KeyframeStateManager} from "./KeyframeStateManager.js";
|
|
10
|
+
import {keyframesContext} from "../actionProcessorOperations/curveActions.js";
|
|
11
|
+
import {createKeyframeMarker} from "./createKeyframeMarker.js";
|
|
12
|
+
import {updateMarkerPosition} from "./updateMarkerPosition.js";
|
|
13
|
+
import {updateMarkerVisual} from "./updateMarkerVisual.js";
|
|
14
|
+
import {createKeyframeDraggableAspect} from "./createKeyframeDraggableAspect.js";
|
|
15
|
+
import {
|
|
16
|
+
handleKeyDownEvents,
|
|
17
|
+
handleKeyframeSelectedByDevice,
|
|
18
|
+
handleMouseDoubleClickEvents,
|
|
19
|
+
handleMouseDownEvents
|
|
20
|
+
} from "./inputEventHandlers.js";
|
|
21
|
+
import {build_tangent_editor} from "../draw/build_tangent_editor.js";
|
|
22
|
+
import {buildReadOnlyDisplay} from "../draw/buildReadOnlyDisplay.js";
|
|
23
|
+
import {KeyboardEvents} from "../../../input/devices/events/KeyboardEvents.js";
|
|
24
|
+
import {MouseEvents} from "../../../input/devices/events/MouseEvents.js";
|
|
25
|
+
import {canvas2dPlotCurveLine} from "./canvas2dPlotCurveLine.js";
|
|
26
|
+
import {updateAxisRange} from "./updateAxisRange.js";
|
|
27
|
+
import {determineUnitSpacing} from "./determineUnitSpacing.js";
|
|
28
|
+
import {animation_curve_compute_aabb} from "../animation_curve_compute_aabb.js";
|
|
29
|
+
import {displayMousePos} from "../draw/displayMousePos.js";
|
|
30
|
+
import {PointerDevice} from "../../../input/devices/PointerDevice.js";
|
|
31
|
+
import {createSelectionBoxTool} from "./createSelectionBoxTool.js";
|
|
32
|
+
import {createPanTool} from "./createPanTool.js";
|
|
33
|
+
import {OperationRouter} from "./OperationRouter.js";
|
|
34
|
+
import {decodeMouseEventButtons} from "../../../input/devices/mouse/decodeMouseEventButtons.js";
|
|
35
|
+
import {createCurveUploader} from "./createCurveUploader.js";
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
const graphToolType = ({
|
|
39
|
+
SELECT: "select",
|
|
40
|
+
PAN: "pan",
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export class CurveEditorView extends EmptyView{
|
|
44
|
+
/**
|
|
45
|
+
*
|
|
46
|
+
* @param {AnimationCurve} curve
|
|
47
|
+
* @param {Vector2} [size]
|
|
48
|
+
* @param {Vector2} [margin] How much space to leave empty around the plotted bounds
|
|
49
|
+
* @param {boolean} [enableEdit]
|
|
50
|
+
* @param {AABB2} [validEditableBounds]
|
|
51
|
+
* @param {ActionProcessor} [actionProcessor]
|
|
52
|
+
*/
|
|
53
|
+
constructor({
|
|
54
|
+
curve,
|
|
55
|
+
size = new Vector2(400, 400),
|
|
56
|
+
margin = new Vector2(46, 46),
|
|
57
|
+
enableEdit= true,
|
|
58
|
+
validEditableBounds = new AABB2(-Infinity,-Infinity,Infinity,Infinity),
|
|
59
|
+
actionProcessor = new ActionProcessor({})
|
|
60
|
+
}) {
|
|
61
|
+
super({
|
|
62
|
+
css: {
|
|
63
|
+
pointerEvents: "auto",
|
|
64
|
+
outline: 'none',
|
|
65
|
+
overflow: 'hidden',
|
|
66
|
+
position: 'relative'
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
this.curve = curve;
|
|
70
|
+
this.size.copy(size);
|
|
71
|
+
this.margin = margin;
|
|
72
|
+
this.enableEdit = enableEdit;
|
|
73
|
+
this.validEditableBounds = validEditableBounds;
|
|
74
|
+
this.actionProcessor = actionProcessor;
|
|
75
|
+
|
|
76
|
+
this.gridSpacing = 32;
|
|
77
|
+
this.zoomLevel = 1;
|
|
78
|
+
|
|
79
|
+
this.build();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
build() {
|
|
83
|
+
this.el.setAttribute('tabindex', '-1'); //allow programmatic focus only
|
|
84
|
+
|
|
85
|
+
// ---- Interface Setup
|
|
86
|
+
const graph = new CanvasView();
|
|
87
|
+
graph.size.copy(this.size);
|
|
88
|
+
|
|
89
|
+
const frameRegion = new AABB2();
|
|
90
|
+
const offset = 0.5;
|
|
91
|
+
//Initialize the frameRegion size
|
|
92
|
+
if (this.curve.length > 1) {
|
|
93
|
+
animation_curve_compute_aabb(frameRegion, this.curve);
|
|
94
|
+
if (frameRegion.y0 === frameRegion.y1) {
|
|
95
|
+
frameRegion.y0 -= offset
|
|
96
|
+
frameRegion.y1 += offset
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
const key = this.curve.keys?.[0]
|
|
101
|
+
frameRegion.set(
|
|
102
|
+
key ? key.time - offset : 0,
|
|
103
|
+
key ? key.value - offset : 0,
|
|
104
|
+
key ? key.time + offset : 1,
|
|
105
|
+
key ? key.value + offset : 1
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const keyCoordinateDisplay = createKeyCoordinateLabelView();
|
|
110
|
+
|
|
111
|
+
// ---- Triggers
|
|
112
|
+
const frameUpdated = new Signal();
|
|
113
|
+
const keyframeChange = new Signal();
|
|
114
|
+
const curveUploadChange = createCurveUploader(this.el);
|
|
115
|
+
|
|
116
|
+
// ---- Keyboard Startup
|
|
117
|
+
const keyboardElement = new KeyboardDevice(this.el);
|
|
118
|
+
keyboardElement.start();
|
|
119
|
+
|
|
120
|
+
// Todo maybe have const uiStateManager = new UIContext(curve, size, margin, frameRegion, validEditableBounds)
|
|
121
|
+
const keyframeStateManager = new KeyframeStateManager();
|
|
122
|
+
|
|
123
|
+
// ----
|
|
124
|
+
const actionProcessorCTX = new keyframesContext({
|
|
125
|
+
curve: this.curve,
|
|
126
|
+
removeKeyframe: removeKeyframe,
|
|
127
|
+
addKeyframe: addKeyframe,
|
|
128
|
+
keyframeViews: keyframeStateManager.keyframeViews,
|
|
129
|
+
activeKeyframe: keyframeStateManager.observedActiveKeyframe,
|
|
130
|
+
selectedKeyframes: keyframeStateManager.selectedKeyframes,
|
|
131
|
+
handleCurveUpdate: handleCurveUpdate,
|
|
132
|
+
updateGraph: updateGraph
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const self = this;
|
|
136
|
+
|
|
137
|
+
function reinitCurve(newCurve) {
|
|
138
|
+
self.curve.keys.forEach(removeKeyframe);
|
|
139
|
+
self.curve.copy(newCurve)
|
|
140
|
+
self.curve.keys.forEach(addKeyframe);
|
|
141
|
+
|
|
142
|
+
handleCurveUpdate();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function handleCurveUpdate() {
|
|
146
|
+
frameUpdated.send0();
|
|
147
|
+
updateGraph();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function updateGraph() {
|
|
151
|
+
|
|
152
|
+
canvas2dPlotCurveLine({
|
|
153
|
+
curve: self.curve,
|
|
154
|
+
ctx: graph.context2d,
|
|
155
|
+
width: graph.size.x,
|
|
156
|
+
height: graph.size.y,
|
|
157
|
+
margin: self.margin,
|
|
158
|
+
range_y: [frameRegion.y0, frameRegion.y1],
|
|
159
|
+
range_x: [frameRegion.x0, frameRegion.x1],
|
|
160
|
+
spacing: self.gridSpacing
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
handleCurveUpdate()
|
|
165
|
+
/**
|
|
166
|
+
*
|
|
167
|
+
* @param {Keyframe} keyframe
|
|
168
|
+
*/
|
|
169
|
+
function addKeyframe(keyframe) {
|
|
170
|
+
|
|
171
|
+
const vContainerMarker = new EmptyView({
|
|
172
|
+
css: {
|
|
173
|
+
position: "absolute",
|
|
174
|
+
top: 0,
|
|
175
|
+
left: 0,
|
|
176
|
+
pointerEvents: "none"
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const marker = createKeyframeMarker();
|
|
181
|
+
|
|
182
|
+
const fnUpdateMarkerPosition = () => updateMarkerPosition(graph, frameRegion, self.margin, keyframe, vContainerMarker);
|
|
183
|
+
|
|
184
|
+
const fnUpdateMarkerVisual = () => updateMarkerVisual(keyframeStateManager, keyframe, vTangentEditor, marker);
|
|
185
|
+
|
|
186
|
+
if (self.enableEdit) {
|
|
187
|
+
const markerElement = marker.el;
|
|
188
|
+
|
|
189
|
+
const draggable = createKeyframeDraggableAspect({
|
|
190
|
+
markerElement: markerElement,
|
|
191
|
+
graph: graph,
|
|
192
|
+
frame: frameRegion,
|
|
193
|
+
margin: self.margin,
|
|
194
|
+
validEditableBounds: self.validEditableBounds,
|
|
195
|
+
curve: self.curve,
|
|
196
|
+
fnUpdateGraph: updateGraph,
|
|
197
|
+
keyframe: keyframe,
|
|
198
|
+
selectedKeyframes: keyframeStateManager.selectedKeyframes,
|
|
199
|
+
activeKeyframe: keyframeStateManager.observedActiveKeyframe,
|
|
200
|
+
keyCoordinateDisplay: keyCoordinateDisplay,
|
|
201
|
+
fnUpdateMarkerPosition: fnUpdateMarkerPosition,
|
|
202
|
+
frameUpdated: frameUpdated,
|
|
203
|
+
keyframeChange: keyframeChange,
|
|
204
|
+
vContainer: self,
|
|
205
|
+
actionProcessor: self.actionProcessor,
|
|
206
|
+
actionProcessorCTX: actionProcessorCTX
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
draggable.getPointer().on.down.add(() => {
|
|
210
|
+
handleKeyframeSelectedByDevice(keyboardElement, keyframe, self.actionProcessor, actionProcessorCTX, keyframeStateManager);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
marker.on.linked.add(draggable.start, draggable);
|
|
214
|
+
marker.on.unlinked.add(draggable.stop, draggable);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
marker.bindSignal(frameUpdated, fnUpdateMarkerPosition);
|
|
218
|
+
marker.bindSignal(keyframeStateManager.observedActiveKeyframe.onChanged, fnUpdateMarkerVisual);
|
|
219
|
+
marker.bindSignal(keyframeStateManager.selectedKeyframes.on.added, fnUpdateMarkerVisual);
|
|
220
|
+
marker.bindSignal(keyframeStateManager.selectedKeyframes.on.removed, fnUpdateMarkerVisual);
|
|
221
|
+
|
|
222
|
+
const vTangentEditor = build_tangent_editor({
|
|
223
|
+
keyframe: keyframe,
|
|
224
|
+
size: graph.size,
|
|
225
|
+
ctx: graph.context2d,
|
|
226
|
+
frame: frameRegion,
|
|
227
|
+
margin: self.margin,
|
|
228
|
+
enableTangentAlignment: keyframeStateManager.tangentAlignmentEnabled,
|
|
229
|
+
cbFnCurveUpdate: updateGraph,
|
|
230
|
+
funcTrigger: keyframeChange,
|
|
231
|
+
actionProcessor: self.actionProcessor,
|
|
232
|
+
actionProcessorCTX: actionProcessorCTX
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
keyframeStateManager.keyframeViews.set(keyframe, vContainerMarker);
|
|
236
|
+
|
|
237
|
+
vContainerMarker.addChild(marker);
|
|
238
|
+
self.addChild(vContainerMarker);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function removeKeyframe(keyframe) {
|
|
242
|
+
const markerView = keyframeStateManager.keyframeViews.get(keyframe);
|
|
243
|
+
self.removeChild(markerView);
|
|
244
|
+
|
|
245
|
+
keyframeStateManager.keyframeViews.delete(keyframe)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
graph.on.linked.add(() => {
|
|
249
|
+
this.curve.keys.forEach(addKeyframe);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
graph.on.unlinked.add(() => {
|
|
253
|
+
this.curve.keys.forEach(removeKeyframe);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
if (!this.enableEdit){
|
|
257
|
+
const labelReadOnly = buildReadOnlyDisplay();
|
|
258
|
+
this.addChild(labelReadOnly);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
this.el.addEventListener(KeyboardEvents.KeyDown, (event) => {
|
|
262
|
+
handleKeyDownEvents(
|
|
263
|
+
event,
|
|
264
|
+
keyboardElement,
|
|
265
|
+
this.curve,
|
|
266
|
+
keyframeStateManager,
|
|
267
|
+
this.actionProcessor,
|
|
268
|
+
actionProcessorCTX
|
|
269
|
+
);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
const graphPointer = new PointerDevice(this.el);
|
|
273
|
+
this.on.linked.add(graphPointer.start, graphPointer);
|
|
274
|
+
this.on.unlinked.add(graphPointer.stop, graphPointer);
|
|
275
|
+
|
|
276
|
+
const selectionBoxTool = new createSelectionBoxTool({
|
|
277
|
+
keyframeStateManager: keyframeStateManager,
|
|
278
|
+
graph: graph,
|
|
279
|
+
frame: frameRegion,
|
|
280
|
+
margin: this.margin,
|
|
281
|
+
fnUpdate: updateGraph,
|
|
282
|
+
actionProcessor: this.actionProcessor,
|
|
283
|
+
actionCTX: actionProcessorCTX
|
|
284
|
+
})
|
|
285
|
+
const panTool = new createPanTool({
|
|
286
|
+
graph: graph,
|
|
287
|
+
frame: frameRegion,
|
|
288
|
+
margin: this.margin,
|
|
289
|
+
fnUpdate: handleCurveUpdate,
|
|
290
|
+
})
|
|
291
|
+
const graphToolList = {
|
|
292
|
+
[graphToolType.SELECT]: selectionBoxTool,
|
|
293
|
+
[graphToolType.PAN]: panTool,
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const operationRouter = new OperationRouter(graphPointer, (event) => {
|
|
297
|
+
if (decodeMouseEventButtons(event.buttons)[0] && this.enableEdit) return graphToolList[graphToolType.SELECT];
|
|
298
|
+
if (decodeMouseEventButtons(event.buttons)[1]) return graphToolList[graphToolType.PAN];
|
|
299
|
+
return null;
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
this.el.addEventListener(MouseEvents.Down, (e) => {
|
|
303
|
+
handleMouseDownEvents(e, graph, keyboardElement, this.actionProcessor, actionProcessorCTX, keyframeStateManager);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
if (this.enableEdit) {
|
|
307
|
+
//create new keyframe at location
|
|
308
|
+
this.el.addEventListener(MouseEvents.DoubleClick, (e) => {
|
|
309
|
+
handleMouseDoubleClickEvents(e, this, graph, frameRegion, this.margin, this.curve, this.validEditableBounds, this.actionProcessor, actionProcessorCTX);
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
this.el.addEventListener(MouseEvents.Wheel, (e) => {
|
|
314
|
+
const zoomFactor = e.deltaY < 0 ? 1.2 : 1/1.2;
|
|
315
|
+
this.zoomLevel *= zoomFactor;
|
|
316
|
+
|
|
317
|
+
//Reminder: apply vertical flip to Y axis for graph coordinates
|
|
318
|
+
const cursorToGraphPos = new Vector2(e.x - this.margin.x, (graph.size.y - this.margin.y) - e.y);
|
|
319
|
+
const newX = updateAxisRange(graph.size.x - this.margin.x * 2, cursorToGraphPos.x, frameRegion.x0, frameRegion.x1, zoomFactor);
|
|
320
|
+
const newY = updateAxisRange(graph.size.y - this.margin.y * 2, cursorToGraphPos.y, frameRegion.y0, frameRegion.y1, zoomFactor);
|
|
321
|
+
|
|
322
|
+
frameRegion.set(newX[0], newY[0], newX[1], newY[1]);
|
|
323
|
+
|
|
324
|
+
this.gridSpacing = determineUnitSpacing(graph.size.x - this.margin.x * 2, this.zoomLevel);
|
|
325
|
+
handleCurveUpdate();
|
|
326
|
+
},
|
|
327
|
+
{passive: true});
|
|
328
|
+
|
|
329
|
+
graph.on.linked.add(handleCurveUpdate);
|
|
330
|
+
// graph.bindSignal(curveUploadChange, handleCurveUpdate);
|
|
331
|
+
graph.bindSignal(curveUploadChange, (data) => reinitCurve(data));
|
|
332
|
+
|
|
333
|
+
displayMousePos.call(this, graph, frameRegion);
|
|
334
|
+
|
|
335
|
+
this.addChild(graph);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export class DragHandler {
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* @param {function} [dragStart=noop]
|
|
5
|
+
* @param {(position:Vector2,delta:Vector2)=>*} [drag=noop]
|
|
6
|
+
* @param {function} [dragEnd=noop]
|
|
7
|
+
*/
|
|
8
|
+
constructor({ dragStart, drag, dragEnd }?: Function);
|
|
9
|
+
dragStartCallback: any;
|
|
10
|
+
dragCallback: any;
|
|
11
|
+
dragEndCallback: any;
|
|
12
|
+
active: boolean;
|
|
13
|
+
start(position: any): void;
|
|
14
|
+
drag(position: any, delta: any): void;
|
|
15
|
+
end(position: any): void;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=DragHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DragHandler.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/editor/DragHandler.js"],"names":[],"mappings":"AAEA;IACI;;;;;OAKG;IACH,qDAMC;IALG,uBAAkC;IAClC,kBAAwB;IACxB,qBAA8B;IAE9B,gBAAmB;IAGvB,2BAGC;IAED,sCAIC;IAED,yBAKC;CACJ"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {noop} from "../../../../core/function/noop.js";
|
|
2
|
+
|
|
3
|
+
export class DragHandler {
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {function} [dragStart=noop]
|
|
7
|
+
* @param {(position:Vector2,delta:Vector2)=>*} [drag=noop]
|
|
8
|
+
* @param {function} [dragEnd=noop]
|
|
9
|
+
*/
|
|
10
|
+
constructor({dragStart = noop, drag = noop, dragEnd = noop}) {
|
|
11
|
+
this.dragStartCallback = dragStart;
|
|
12
|
+
this.dragCallback = drag;
|
|
13
|
+
this.dragEndCallback = dragEnd;
|
|
14
|
+
|
|
15
|
+
this.active = false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
start(position) {
|
|
19
|
+
this.active = true;
|
|
20
|
+
this.dragStartCallback(position);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
drag(position, delta) {
|
|
24
|
+
if (!this.active) return;
|
|
25
|
+
|
|
26
|
+
this.dragCallback(position, delta);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
end(position) {
|
|
30
|
+
if (!this.active) return;
|
|
31
|
+
|
|
32
|
+
this.active = false;
|
|
33
|
+
this.dragEndCallback(position);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export class KeyframeStateManager {
|
|
2
|
+
/**
|
|
3
|
+
* Currently focused (active) keyframe.
|
|
4
|
+
* @type {ObservedValue<Keyframe>}
|
|
5
|
+
*/
|
|
6
|
+
observedActiveKeyframe: any;
|
|
7
|
+
/**
|
|
8
|
+
* Store currently selected keyframe(s)
|
|
9
|
+
* @type {List}
|
|
10
|
+
*/
|
|
11
|
+
selectedKeyframes: List<any>;
|
|
12
|
+
/**
|
|
13
|
+
* Target state for keyframe selection action processor
|
|
14
|
+
* @type {List}
|
|
15
|
+
*/
|
|
16
|
+
curKeyframeList: List<any>;
|
|
17
|
+
/**
|
|
18
|
+
* Snapshot of state prior to keyframe selection action processor
|
|
19
|
+
* @type {List}
|
|
20
|
+
*/
|
|
21
|
+
prevKeyframeList: List<any>;
|
|
22
|
+
keyframeViews: Map<any, any>;
|
|
23
|
+
/**
|
|
24
|
+
* Boolean for tangent alignment: free (False) or match (True)
|
|
25
|
+
* @type {ObservedBoolean}
|
|
26
|
+
*/
|
|
27
|
+
tangentAlignmentEnabled: ObservedBoolean;
|
|
28
|
+
NULL_KEYFRAME: Keyframe;
|
|
29
|
+
}
|
|
30
|
+
import List from "../../../../core/collection/list/List.js";
|
|
31
|
+
import ObservedBoolean from "../../../../core/model/ObservedBoolean.js";
|
|
32
|
+
import { Keyframe } from "../Keyframe.js";
|
|
33
|
+
//# sourceMappingURL=KeyframeStateManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyframeStateManager.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/editor/KeyframeStateManager.js"],"names":[],"mappings":"AAKA;IAEQ;;;OAGG;IACH,4BAAiD;IACjD;;;OAGG;IACH,6BAA+B;IAC/B;;;OAGG;IACH,2BAA6B;IAC7B;;;OAGG;IACH,4BAA8B;IAE9B,6BAA0B;IAE1B;;;OAGG;IACH,yBAFU,eAAe,CAEuB;IAGhD,wBAA8B;CACrC;iBApCgB,0CAA0C;4BAC/B,2CAA2C;yBAHhD,gBAAgB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {Keyframe} from "../Keyframe.js";
|
|
2
|
+
import ObservedValue from "../../../../core/model/ObservedValue.js";
|
|
3
|
+
import List from "../../../../core/collection/list/List.js";
|
|
4
|
+
import ObservedBoolean from "../../../../core/model/ObservedBoolean.js";
|
|
5
|
+
|
|
6
|
+
export class KeyframeStateManager {
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Currently focused (active) keyframe.
|
|
10
|
+
* @type {ObservedValue<Keyframe>}
|
|
11
|
+
*/
|
|
12
|
+
observedActiveKeyframe = new ObservedValue(null);
|
|
13
|
+
/**
|
|
14
|
+
* Store currently selected keyframe(s)
|
|
15
|
+
* @type {List}
|
|
16
|
+
*/
|
|
17
|
+
selectedKeyframes = new List();
|
|
18
|
+
/**
|
|
19
|
+
* Target state for keyframe selection action processor
|
|
20
|
+
* @type {List}
|
|
21
|
+
*/
|
|
22
|
+
curKeyframeList = new List();
|
|
23
|
+
/**
|
|
24
|
+
* Snapshot of state prior to keyframe selection action processor
|
|
25
|
+
* @type {List}
|
|
26
|
+
*/
|
|
27
|
+
prevKeyframeList = new List();
|
|
28
|
+
|
|
29
|
+
keyframeViews = new Map();
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Boolean for tangent alignment: free (False) or match (True)
|
|
33
|
+
* @type {ObservedBoolean}
|
|
34
|
+
*/
|
|
35
|
+
tangentAlignmentEnabled = new ObservedBoolean();
|
|
36
|
+
|
|
37
|
+
// Constants
|
|
38
|
+
NULL_KEYFRAME = new Keyframe()
|
|
39
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decide and execute the operation based on pointer device events
|
|
3
|
+
*/
|
|
4
|
+
export class OperationRouter {
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {PointerDevice} pointerDevice
|
|
8
|
+
* @param {function} resolveOperation
|
|
9
|
+
*/
|
|
10
|
+
constructor(pointerDevice: PointerDevice, resolveOperation: Function);
|
|
11
|
+
pointer: PointerDevice;
|
|
12
|
+
resolveOperation: Function;
|
|
13
|
+
activeOperation: any;
|
|
14
|
+
start(position: any, event: any): void;
|
|
15
|
+
run(position: any, origin: any, last: any, event: any): void;
|
|
16
|
+
stop(position: any, event: any): void;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=OperationRouter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OperationRouter.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/editor/OperationRouter.js"],"names":[],"mappings":"AAAA;;GAEG;AACH;IACI;;;;OAIG;IACH,sEASC;IARG,uBAA4B;IAC5B,2BAAwC;IACxC,qBAA2B;IAQ/B,uCAQC;IAED,6DAKC;IAED,sCAKC;CACJ"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decide and execute the operation based on pointer device events
|
|
3
|
+
*/
|
|
4
|
+
export class OperationRouter {
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {PointerDevice} pointerDevice
|
|
8
|
+
* @param {function} resolveOperation
|
|
9
|
+
*/
|
|
10
|
+
constructor(pointerDevice, resolveOperation) {
|
|
11
|
+
this.pointer = pointerDevice;
|
|
12
|
+
this.resolveOperation = resolveOperation;
|
|
13
|
+
this.activeOperation = null;
|
|
14
|
+
|
|
15
|
+
this.pointer.on.down.add(this.start, this);
|
|
16
|
+
this.pointer.on.drag.add(this.run, this);
|
|
17
|
+
this.pointer.on.up.add(this.stop, this);
|
|
18
|
+
this.pointer.on.dragEnd.add(this.stop, this);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
start(position, event) {
|
|
22
|
+
if (this.activeOperation) return;
|
|
23
|
+
|
|
24
|
+
const operation = this.resolveOperation(event);
|
|
25
|
+
if (!operation) return;
|
|
26
|
+
|
|
27
|
+
this.activeOperation = operation;
|
|
28
|
+
this.activeOperation.start(position, event);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
run(position, origin, last, event) {
|
|
32
|
+
if (!this.activeOperation) return;
|
|
33
|
+
|
|
34
|
+
const delta = position.clone().sub(last);
|
|
35
|
+
this.activeOperation.drag(position, delta, event);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
stop(position, event) {
|
|
39
|
+
if (!this.activeOperation) return;
|
|
40
|
+
|
|
41
|
+
this.activeOperation.end(position, event);
|
|
42
|
+
this.activeOperation = null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {CanvasRenderingContext2D} ctx
|
|
4
|
+
* @param {number} position_x0
|
|
5
|
+
* @param {number} position_y0
|
|
6
|
+
* @param {number} position_x1
|
|
7
|
+
* @param {number} position_y1
|
|
8
|
+
* @param {number} spacing
|
|
9
|
+
* @param {number} value_0
|
|
10
|
+
* @param {number} value_1
|
|
11
|
+
* @param {number} valueStep
|
|
12
|
+
*/
|
|
13
|
+
export function canvas2dDrawWorldAxisLabels({ ctx, position_x0, position_y0, position_x1, position_y1, spacing, value_0, value_1, valueStep }: CanvasRenderingContext2D): void;
|
|
14
|
+
//# sourceMappingURL=canvas2dDrawWorldAxisLabels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas2dDrawWorldAxisLabels.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,+IAVW,wBAAwB,QAwDlC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {canvas2d_draw_label} from "../../../graphics/canvas/canvas2d_draw_label.js";
|
|
2
|
+
import {formatTruncDecimal} from "./formatTruncDecimal.js";
|
|
3
|
+
import {v2_length} from "../../../../core/geom/vec2/v2_length.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {CanvasRenderingContext2D} ctx
|
|
8
|
+
* @param {number} position_x0
|
|
9
|
+
* @param {number} position_y0
|
|
10
|
+
* @param {number} position_x1
|
|
11
|
+
* @param {number} position_y1
|
|
12
|
+
* @param {number} spacing
|
|
13
|
+
* @param {number} value_0
|
|
14
|
+
* @param {number} value_1
|
|
15
|
+
* @param {number} valueStep
|
|
16
|
+
*/
|
|
17
|
+
export function canvas2dDrawWorldAxisLabels({
|
|
18
|
+
ctx,
|
|
19
|
+
position_x0, position_y0,
|
|
20
|
+
position_x1, position_y1,
|
|
21
|
+
spacing = 10,
|
|
22
|
+
value_0, value_1,
|
|
23
|
+
valueStep
|
|
24
|
+
}) {
|
|
25
|
+
|
|
26
|
+
if (spacing <= 0) {
|
|
27
|
+
throw new Error(`Spacing must be greater than 0`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// compute direction vector
|
|
31
|
+
const delta_x = position_x1 - position_x0;
|
|
32
|
+
const delta_y = position_y1 - position_y0;
|
|
33
|
+
|
|
34
|
+
const distance = v2_length(delta_x, delta_y);
|
|
35
|
+
|
|
36
|
+
if (distance === 0) {
|
|
37
|
+
throw new Error(`Distance must be greater than 0`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const direction_x = delta_x / distance;
|
|
41
|
+
const direction_y = delta_y / distance;
|
|
42
|
+
|
|
43
|
+
// number of marks
|
|
44
|
+
const mark_count = Math.ceil(distance / spacing);
|
|
45
|
+
|
|
46
|
+
for (let i = 0; i <= mark_count; i++) {
|
|
47
|
+
const offset = spacing * i;
|
|
48
|
+
|
|
49
|
+
const point_x = position_x0 + direction_x * offset;
|
|
50
|
+
const point_y = position_y0 + direction_y * offset;
|
|
51
|
+
|
|
52
|
+
// compute label value based on valueStep
|
|
53
|
+
const value = value_0 + i * valueStep;
|
|
54
|
+
|
|
55
|
+
canvas2d_draw_label({
|
|
56
|
+
ctx,
|
|
57
|
+
text: formatTruncDecimal(value),
|
|
58
|
+
x: point_x,
|
|
59
|
+
y: point_y
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param ctx
|
|
4
|
+
* @param {number} width
|
|
5
|
+
* @param {number} height
|
|
6
|
+
* @param {string} [color] CSS color specification
|
|
7
|
+
* @param {number} spacingX distance between grid lines for x-axis
|
|
8
|
+
* @param {number} spacingY distance between grid lines for y-axis
|
|
9
|
+
* @param {number} offsetX
|
|
10
|
+
* @param {number} offsetY
|
|
11
|
+
* @param {number[]} valueRangeX
|
|
12
|
+
* @param {number[]} valueRangeY
|
|
13
|
+
* @param {number} thickness
|
|
14
|
+
*/
|
|
15
|
+
export function canvas2dDrawWorldGrid({ ctx, width, height, color, spacingX, spacingY, offsetX, offsetY, valueRangeX, valueRangeY, thickness }: {
|
|
16
|
+
ctx: any;
|
|
17
|
+
width: any;
|
|
18
|
+
height: any;
|
|
19
|
+
color?: string;
|
|
20
|
+
spacingX?: number;
|
|
21
|
+
spacingY?: number;
|
|
22
|
+
offsetX?: number;
|
|
23
|
+
offsetY?: number;
|
|
24
|
+
valueRangeX?: number[];
|
|
25
|
+
valueRangeY?: number[];
|
|
26
|
+
thickness?: number;
|
|
27
|
+
}): void;
|
|
28
|
+
//# sourceMappingURL=canvas2dDrawWorldGrid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas2dDrawWorldGrid.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/editor/canvas2dDrawWorldGrid.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH;;;;;;;;;;;;SAuDC"}
|