@woosh/meep-engine 2.131.34 → 2.131.36

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 (118) hide show
  1. package/build/bundle-worker-image-decoder.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/binary/BinaryBuffer.d.ts +14 -0
  4. package/src/core/binary/BinaryBuffer.d.ts.map +1 -1
  5. package/src/core/binary/BinaryBuffer.js +27 -0
  6. package/src/core/binary/allocator/OffsetAllocator.d.ts +5 -0
  7. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  8. package/src/core/binary/allocator/OffsetAllocator.js +6 -0
  9. package/src/core/bvh2/bvh3/ebvh_optimize_treelet.d.ts.map +1 -1
  10. package/src/core/bvh2/bvh3/ebvh_optimize_treelet.js +77 -20
  11. package/src/core/geom/3d/aabb/AABB3.d.ts +14 -0
  12. package/src/core/geom/3d/aabb/AABB3.d.ts.map +1 -1
  13. package/src/core/geom/3d/aabb/AABB3.js +24 -0
  14. package/src/core/math/hash/computeHashFloatArray.d.ts +3 -2
  15. package/src/core/math/hash/computeHashFloatArray.d.ts.map +1 -1
  16. package/src/core/math/hash/computeHashFloatArray.js +2 -1
  17. package/src/core/process/undo/ActionProcessor.d.ts.map +1 -1
  18. package/src/core/process/undo/ActionProcessor.js +3 -1
  19. package/src/engine/animation/curve/actionProcessorOperations/applyActionChange.d.ts +34 -0
  20. package/src/engine/animation/curve/actionProcessorOperations/applyActionChange.d.ts.map +1 -0
  21. package/src/engine/animation/curve/actionProcessorOperations/applyActionChange.js +61 -0
  22. package/src/engine/animation/curve/actionProcessorOperations/curveActions.d.ts +107 -0
  23. package/src/engine/animation/curve/actionProcessorOperations/curveActions.d.ts.map +1 -0
  24. package/src/engine/animation/curve/actionProcessorOperations/curveActions.js +202 -0
  25. package/src/engine/animation/curve/compression/prototypeCurveCompression.js +24 -3
  26. package/src/engine/animation/curve/draw/buildReadOnlyDisplay.d.ts +3 -0
  27. package/src/engine/animation/curve/draw/buildReadOnlyDisplay.d.ts.map +1 -0
  28. package/src/engine/animation/curve/draw/buildReadOnlyDisplay.js +14 -0
  29. package/src/engine/animation/curve/draw/build_tangent_editor.d.ts +6 -1
  30. package/src/engine/animation/curve/draw/build_tangent_editor.d.ts.map +1 -1
  31. package/src/engine/animation/curve/draw/build_tangent_editor.js +220 -51
  32. package/src/engine/animation/curve/draw/displayMousePos.d.ts +7 -0
  33. package/src/engine/animation/curve/draw/displayMousePos.d.ts.map +1 -0
  34. package/src/engine/animation/curve/draw/displayMousePos.js +41 -0
  35. package/src/engine/animation/curve/draw/isInjectedKeyframeInBounds.d.ts +26 -0
  36. package/src/engine/animation/curve/draw/isInjectedKeyframeInBounds.d.ts.map +1 -0
  37. package/src/engine/animation/curve/draw/isInjectedKeyframeInBounds.js +93 -0
  38. package/src/engine/animation/curve/draw/position_canvas_to_curve.d.ts +12 -0
  39. package/src/engine/animation/curve/draw/position_canvas_to_curve.d.ts.map +1 -0
  40. package/src/engine/animation/curve/draw/position_canvas_to_curve.js +24 -0
  41. package/src/engine/animation/curve/draw/position_curve_to_canvas.d.ts +12 -0
  42. package/src/engine/animation/curve/draw/position_curve_to_canvas.d.ts.map +1 -0
  43. package/src/engine/animation/curve/draw/position_curve_to_canvas.js +25 -0
  44. package/src/engine/animation/curve/editor/CurveEditorView.d.ts +22 -0
  45. package/src/engine/animation/curve/editor/CurveEditorView.d.ts.map +1 -0
  46. package/src/engine/animation/curve/editor/CurveEditorView.js +337 -0
  47. package/src/engine/animation/curve/editor/DragHandler.d.ts +17 -0
  48. package/src/engine/animation/curve/editor/DragHandler.d.ts.map +1 -0
  49. package/src/engine/animation/curve/editor/DragHandler.js +35 -0
  50. package/src/engine/animation/curve/editor/KeyframeStateManager.d.ts +33 -0
  51. package/src/engine/animation/curve/editor/KeyframeStateManager.d.ts.map +1 -0
  52. package/src/engine/animation/curve/editor/KeyframeStateManager.js +39 -0
  53. package/src/engine/animation/curve/editor/OperationRouter.d.ts +18 -0
  54. package/src/engine/animation/curve/editor/OperationRouter.d.ts.map +1 -0
  55. package/src/engine/animation/curve/editor/OperationRouter.js +44 -0
  56. package/src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.d.ts +14 -0
  57. package/src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.d.ts.map +1 -0
  58. package/src/engine/animation/curve/editor/canvas2dDrawWorldAxisLabels.js +63 -0
  59. package/src/engine/animation/curve/editor/canvas2dDrawWorldGrid.d.ts +28 -0
  60. package/src/engine/animation/curve/editor/canvas2dDrawWorldGrid.d.ts.map +1 -0
  61. package/src/engine/animation/curve/editor/canvas2dDrawWorldGrid.js +70 -0
  62. package/src/engine/animation/curve/editor/canvas2dPlotCurveLine.d.ts +13 -0
  63. package/src/engine/animation/curve/editor/canvas2dPlotCurveLine.d.ts.map +1 -0
  64. package/src/engine/animation/curve/editor/canvas2dPlotCurveLine.js +116 -0
  65. package/src/engine/animation/curve/editor/canvas2dPlotCurvePoints.d.ts +11 -0
  66. package/src/engine/animation/curve/editor/canvas2dPlotCurvePoints.d.ts.map +1 -0
  67. package/src/engine/animation/curve/editor/canvas2dPlotCurvePoints.js +69 -0
  68. package/src/engine/animation/curve/editor/createCurveUploader.d.ts +8 -0
  69. package/src/engine/animation/curve/editor/createCurveUploader.d.ts.map +1 -0
  70. package/src/engine/animation/curve/editor/createCurveUploader.js +25 -0
  71. package/src/engine/animation/curve/editor/createKeyCoordinateLabelView.d.ts +3 -0
  72. package/src/engine/animation/curve/editor/createKeyCoordinateLabelView.d.ts.map +1 -0
  73. package/src/engine/animation/curve/editor/createKeyCoordinateLabelView.js +15 -0
  74. package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.d.ts +24 -0
  75. package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.d.ts.map +1 -0
  76. package/src/engine/animation/curve/editor/createKeyframeDraggableAspect.js +142 -0
  77. package/src/engine/animation/curve/editor/createKeyframeMarker.d.ts +2 -0
  78. package/src/engine/animation/curve/editor/createKeyframeMarker.d.ts.map +1 -0
  79. package/src/engine/animation/curve/editor/createKeyframeMarker.js +42 -0
  80. package/src/engine/animation/curve/editor/createPanTool.d.ts +11 -0
  81. package/src/engine/animation/curve/editor/createPanTool.d.ts.map +1 -0
  82. package/src/engine/animation/curve/editor/createPanTool.js +41 -0
  83. package/src/engine/animation/curve/editor/createSelectionBoxTool.d.ts +14 -0
  84. package/src/engine/animation/curve/editor/createSelectionBoxTool.d.ts.map +1 -0
  85. package/src/engine/animation/curve/editor/createSelectionBoxTool.js +93 -0
  86. package/src/engine/animation/curve/editor/deleteKeyframeAndResetVars.d.ts +8 -0
  87. package/src/engine/animation/curve/editor/deleteKeyframeAndResetVars.d.ts.map +1 -0
  88. package/src/engine/animation/curve/editor/deleteKeyframeAndResetVars.js +24 -0
  89. package/src/engine/animation/curve/editor/determineUnitSpacing.d.ts +8 -0
  90. package/src/engine/animation/curve/editor/determineUnitSpacing.d.ts.map +1 -0
  91. package/src/engine/animation/curve/editor/determineUnitSpacing.js +33 -0
  92. package/src/engine/animation/curve/editor/formatTruncDecimal.d.ts +7 -0
  93. package/src/engine/animation/curve/editor/formatTruncDecimal.d.ts.map +1 -0
  94. package/src/engine/animation/curve/editor/formatTruncDecimal.js +14 -0
  95. package/src/engine/animation/curve/editor/inputEventHandlers.d.ts +32 -0
  96. package/src/engine/animation/curve/editor/inputEventHandlers.d.ts.map +1 -0
  97. package/src/engine/animation/curve/editor/inputEventHandlers.js +125 -0
  98. package/src/engine/animation/curve/editor/uiContext.d.ts +10 -0
  99. package/src/engine/animation/curve/editor/uiContext.d.ts.map +1 -0
  100. package/src/engine/animation/curve/editor/uiContext.js +18 -0
  101. package/src/engine/animation/curve/editor/updateAxisRange.d.ts +11 -0
  102. package/src/engine/animation/curve/editor/updateAxisRange.d.ts.map +1 -0
  103. package/src/engine/animation/curve/editor/updateAxisRange.js +23 -0
  104. package/src/engine/animation/curve/editor/updateKeyframePosition.d.ts +9 -0
  105. package/src/engine/animation/curve/editor/updateKeyframePosition.d.ts.map +1 -0
  106. package/src/engine/animation/curve/editor/updateKeyframePosition.js +38 -0
  107. package/src/engine/animation/curve/editor/updateMarkerPosition.d.ts +2 -0
  108. package/src/engine/animation/curve/editor/updateMarkerPosition.d.ts.map +1 -0
  109. package/src/engine/animation/curve/editor/updateMarkerPosition.js +12 -0
  110. package/src/engine/animation/curve/editor/updateMarkerVisual.d.ts +9 -0
  111. package/src/engine/animation/curve/editor/updateMarkerVisual.d.ts.map +1 -0
  112. package/src/engine/animation/curve/editor/updateMarkerVisual.js +53 -0
  113. package/src/engine/animation/curve/editor/uploadViaElement.d.ts +7 -0
  114. package/src/engine/animation/curve/editor/uploadViaElement.d.ts.map +1 -0
  115. package/src/engine/animation/curve/editor/uploadViaElement.js +35 -0
  116. package/src/engine/animation/curve/draw/build_curve_editor.d.ts +0 -9
  117. package/src/engine/animation/curve/draw/build_curve_editor.d.ts.map +0 -1
  118. package/src/engine/animation/curve/draw/build_curve_editor.js +0 -362
@@ -0,0 +1,41 @@
1
+ import {PointerDevice} from "../../../input/devices/PointerDevice.js";
2
+ import {position_canvas_to_curve} from "./position_canvas_to_curve.js";
3
+ import LabelView from "../../../../view/common/LabelView.js";
4
+ import {CSS_ABSOLUTE_POSITIONING} from "../../../../view/CSS_ABSOLUTE_POSITIONING.js";
5
+ import {detectClosestCurveTimePoint} from "./isInjectedKeyframeInBounds.js";
6
+ import {formatTruncDecimal} from "../editor/formatTruncDecimal.js";
7
+
8
+ /**
9
+ * Display the mouse position in respect to the graph
10
+ * @param {CanvasView} graph
11
+ * @param {AABB2} frameRegion
12
+ */
13
+ export function displayMousePos(graph, frameRegion) {
14
+ const myPointerGlobal = new PointerDevice(window);
15
+ myPointerGlobal.start();
16
+ myPointerGlobal.on.move.add((position, e) => {
17
+ const curveCord = position_canvas_to_curve(graph.size, frameRegion, this.margin, position.x, position.y)
18
+
19
+ let label = "x: --.--, y: --.--";
20
+ if (e.buttons === 0) {
21
+ const timeSplicePosition = detectClosestCurveTimePoint(this.curve, graph, frameRegion, this.margin, curveCord, position);
22
+ if (timeSplicePosition !== Infinity) {
23
+ label = `x: ${formatTruncDecimal(timeSplicePosition)}, y: ${formatTruncDecimal(this.curve.evaluate(timeSplicePosition))}`;
24
+ }
25
+ }
26
+
27
+ mouseCord.updateText(label)
28
+ });
29
+ const mouseCord = new LabelView("x: --.--, y: --.--", {
30
+ css: {
31
+ background: `rgba(0, 0, 0)`,
32
+ ...CSS_ABSOLUTE_POSITIONING,
33
+ color: 'white',
34
+ font: '12px Tahoma, monospaced',
35
+ top: '5px',
36
+ right: '5px',
37
+ left: 'auto'
38
+ }
39
+ });
40
+ this.addChild(mouseCord);
41
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Check if new keyframe is in valid bounds
3
+ * @param {CanvasView} graph
4
+ * @param {AABB2} frame
5
+ * @param {Vector2} margin
6
+ * @param {AnimationCurve} curve
7
+ * @param {AABB2} validEditableBounds
8
+ * @param {Vector2} newCanvasPosition
9
+ * @param {Keyframe} newKeyframeContainer
10
+ * @returns {boolean}
11
+ */
12
+ export function isInjectedKeyframeInBounds(graph: CanvasView, frame: AABB2, margin: Vector2, curve: AnimationCurve, validEditableBounds: AABB2, newCanvasPosition: Vector2, newKeyframeContainer: Keyframe): boolean;
13
+ /**
14
+ *
15
+ * @param {AnimationCurve} curve
16
+ * @param {CanvasView} graph
17
+ * @param {AABB2} frame
18
+ * @param {Vector2} margin
19
+ * @param {Vector2} curvePosition
20
+ * @param {Vector2} mousePosition
21
+ * @returns {number}
22
+ */
23
+ export function detectClosestCurveTimePoint(curve: AnimationCurve, graph: CanvasView, frame: AABB2, margin: Vector2, curvePosition: Vector2, mousePosition: Vector2): number;
24
+ import Vector2 from "../../../../core/geom/Vector2.js";
25
+ import { Keyframe } from "../Keyframe.js";
26
+ //# sourceMappingURL=isInjectedKeyframeInBounds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isInjectedKeyframeInBounds.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/draw/isInjectedKeyframeInBounds.js"],"names":[],"mappings":"AAQA;;;;;;;;;;GAUG;AACH,oFAPW,OAAO,wEAGP,OAAO,wBACP,QAAQ,GACN,OAAO,CAqBnB;AAED;;;;;;;;;GASG;AACH,4GALW,OAAO,iBACP,OAAO,iBACP,OAAO,GACL,MAAM,CAclB;oBAzDmB,kCAAkC;yBAJ/B,gBAAgB"}
@@ -0,0 +1,93 @@
1
+ import {position_canvas_to_curve} from "./position_canvas_to_curve.js";
2
+ import {Keyframe} from "../Keyframe.js";
3
+ import {assert} from "../../../../core/assert.js";
4
+ import {animation_curve_subdivide} from "../animation_curve_subdivide.js";
5
+ import {animation_curve_nearest_point} from "../animation_curve_nearest_point.js";
6
+ import Vector2 from "../../../../core/geom/Vector2.js";
7
+ import {position_curve_to_canvas} from "./position_curve_to_canvas.js";
8
+
9
+ /**
10
+ * Check if new keyframe is in valid bounds
11
+ * @param {CanvasView} graph
12
+ * @param {AABB2} frame
13
+ * @param {Vector2} margin
14
+ * @param {AnimationCurve} curve
15
+ * @param {AABB2} validEditableBounds
16
+ * @param {Vector2} newCanvasPosition
17
+ * @param {Keyframe} newKeyframeContainer
18
+ * @returns {boolean}
19
+ */
20
+ export function isInjectedKeyframeInBounds(graph, frame, margin, curve, validEditableBounds, newCanvasPosition, newKeyframeContainer) {
21
+ const curvePosition = position_canvas_to_curve(graph.size, frame, margin, newCanvasPosition.x, newCanvasPosition.y);
22
+ const curveTimePos = curvePosition.x;
23
+
24
+ //New keyframe is within the curve range
25
+ const isWithinCurveTimeBounds = curveTimePos > curve.keys[0].time && curveTimePos < curve.keys[curve.length - 1].time
26
+ if (isWithinCurveTimeBounds) {
27
+ const timeSplicePosition = detectClosestCurveTimePoint(curve, graph, frame, margin, curvePosition, newCanvasPosition);
28
+ if (timeSplicePosition !== Infinity) {
29
+ acquireInjectedKeyframePosition(curve, timeSplicePosition, newKeyframeContainer);
30
+ return true;
31
+ }
32
+ } else if (validEditableBounds.containsPoint(curvePosition.x, curvePosition.y)) {
33
+ //New keyframe is within the bounds limit
34
+ newKeyframeContainer.time = curvePosition.x;
35
+ newKeyframeContainer.value = curvePosition.y;
36
+ return true;
37
+ }
38
+ return false;
39
+ }
40
+
41
+ /**
42
+ *
43
+ * @param {AnimationCurve} curve
44
+ * @param {CanvasView} graph
45
+ * @param {AABB2} frame
46
+ * @param {Vector2} margin
47
+ * @param {Vector2} curvePosition
48
+ * @param {Vector2} mousePosition
49
+ * @returns {number}
50
+ */
51
+ export function detectClosestCurveTimePoint(curve, graph, frame, margin, curvePosition, mousePosition) {
52
+ const distTolerance = 10;
53
+
54
+ const nearestTimePoint = animation_curve_nearest_point(curve, curvePosition.x, curvePosition.y)
55
+ const foundCurvePoint = new Vector2(nearestTimePoint, curve.evaluate(nearestTimePoint));
56
+ const canvasPositionOfFoundCurvePoint = position_curve_to_canvas(graph.size, frame, margin, foundCurvePoint.x, foundCurvePoint.y)
57
+
58
+ let closestPoint = Infinity;
59
+ if (mousePosition.distanceTo(canvasPositionOfFoundCurvePoint) <= distTolerance) {
60
+ closestPoint = nearestTimePoint;
61
+ }
62
+ return closestPoint;
63
+ }
64
+
65
+ /**
66
+ *
67
+ * @param {AnimationCurve} curve
68
+ * @param {number} timeSplicePosition
69
+ * @param {Keyframe} newKeyframeContainer
70
+ */
71
+ function acquireInjectedKeyframePosition(curve, timeSplicePosition, newKeyframeContainer) {
72
+ const prevKeyframeRef = new Keyframe();
73
+ const nextKeyframeRef = new Keyframe();
74
+
75
+ curve.keys.forEach((kf) => {
76
+ if (kf.time <= timeSplicePosition && kf.time >= prevKeyframeRef.time) {
77
+ prevKeyframeRef.copy(kf);
78
+ }
79
+ if (kf.time >= timeSplicePosition && nextKeyframeRef.time === 0) {
80
+ nextKeyframeRef.copy(kf);
81
+ }
82
+ });
83
+
84
+ assert.notEqual(nextKeyframeRef.time, 0, "Invalid next keyframe value");
85
+ assert.notEqual(prevKeyframeRef.time, nextKeyframeRef.time, "Invalid keyframes value")
86
+
87
+ const segmentTimeDiff = nextKeyframeRef.time - prevKeyframeRef.time;
88
+ const segmentTimeTravel = timeSplicePosition - prevKeyframeRef.time;
89
+ const segmentTimeSplitRatio = segmentTimeTravel / segmentTimeDiff;
90
+
91
+ animation_curve_subdivide(newKeyframeContainer, prevKeyframeRef, nextKeyframeRef, segmentTimeSplitRatio);
92
+ }
93
+
@@ -0,0 +1,12 @@
1
+ /**
2
+ *
3
+ * @param {Vector2} size
4
+ * @param {AABB2} frame
5
+ * @param {Vector2} margin
6
+ * @param {number} x
7
+ * @param {number} y
8
+ * @return {Vector2}
9
+ */
10
+ export function position_canvas_to_curve(size: Vector2, frame: AABB2, margin: Vector2, x: number, y: number): Vector2;
11
+ import Vector2 from "../../../../core/geom/Vector2.js";
12
+ //# sourceMappingURL=position_canvas_to_curve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"position_canvas_to_curve.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/draw/position_canvas_to_curve.js"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,+CAPW,OAAO,wBAEP,OAAO,KACP,MAAM,KACN,MAAM,GACL,OAAO,CAclB;oBAvBmB,kCAAkC"}
@@ -0,0 +1,24 @@
1
+ import Vector2 from "../../../../core/geom/Vector2.js";
2
+
3
+ /**
4
+ *
5
+ * @param {Vector2} size
6
+ * @param {AABB2} frame
7
+ * @param {Vector2} margin
8
+ * @param {number} x
9
+ * @param {number} y
10
+ * @return {Vector2}
11
+ */
12
+ export function position_canvas_to_curve(size, frame, margin, x, y) {
13
+
14
+ const width = size.x;
15
+ const height = size.y;
16
+
17
+ const u = (x - margin.x) / (width - margin.x * 2);
18
+ const v = 1 - (y - margin.y) / (height - margin.y * 2);
19
+
20
+ return new Vector2(
21
+ u * frame.getWidth() + frame.x0,
22
+ v * frame.getHeight() + frame.y0
23
+ );
24
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ *
3
+ * @param {Vector2} size
4
+ * @param {AABB2} frame
5
+ * @param {Vector2} margin
6
+ * @param {number} x
7
+ * @param {number} y
8
+ * @return {Vector2}
9
+ */
10
+ export function position_curve_to_canvas(size: Vector2, frame: AABB2, margin: Vector2, x: number, y: number): Vector2;
11
+ import Vector2 from "../../../../core/geom/Vector2.js";
12
+ //# sourceMappingURL=position_curve_to_canvas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"position_curve_to_canvas.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/draw/position_curve_to_canvas.js"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,+CAPW,OAAO,wBAEP,OAAO,KACP,MAAM,KACN,MAAM,GACL,OAAO,CAelB;oBAxBmB,kCAAkC"}
@@ -0,0 +1,25 @@
1
+ import Vector2 from "../../../../core/geom/Vector2.js";
2
+
3
+ /**
4
+ *
5
+ * @param {Vector2} size
6
+ * @param {AABB2} frame
7
+ * @param {Vector2} margin
8
+ * @param {number} x
9
+ * @param {number} y
10
+ * @return {Vector2}
11
+ */
12
+ export function position_curve_to_canvas(size, frame, margin, x, y) {
13
+ const width = size.x;
14
+ const height = size.y;
15
+
16
+ const curve_width = frame.getWidth();
17
+ const curve_width_multiplier = curve_width > 0 ? 1 / curve_width : 0;
18
+ const u = (x - frame.x0) * curve_width_multiplier;
19
+
20
+ const curve_height = frame.getHeight();
21
+ const curve_height_multiplier = curve_height > 0 ? 1 / curve_height : 0;
22
+ const v = 1 - (y - frame.y0) * curve_height_multiplier;
23
+
24
+ return new Vector2(margin.x + (u * (width - margin.x * 2)), margin.y + v * (height - margin.y * 2));
25
+ }
@@ -0,0 +1,22 @@
1
+ export class CurveEditorView extends EmptyView {
2
+ /**
3
+ *
4
+ * @param {AnimationCurve} curve
5
+ * @param {Vector2} [size]
6
+ * @param {Vector2} [margin] How much space to leave empty around the plotted bounds
7
+ * @param {boolean} [enableEdit]
8
+ * @param {AABB2} [validEditableBounds]
9
+ * @param {ActionProcessor} [actionProcessor]
10
+ */
11
+ constructor({ curve, size, margin, enableEdit, validEditableBounds, actionProcessor }: AnimationCurve);
12
+ curve: AnimationCurve;
13
+ margin: AnimationCurve;
14
+ enableEdit: AnimationCurve;
15
+ validEditableBounds: AnimationCurve;
16
+ actionProcessor: AnimationCurve;
17
+ gridSpacing: number;
18
+ zoomLevel: number;
19
+ build(): void;
20
+ }
21
+ import EmptyView from "../../../../view/elements/EmptyView.js";
22
+ //# sourceMappingURL=CurveEditorView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CurveEditorView.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/editor/CurveEditorView.js"],"names":[],"mappings":"AA0CA;IACI;;;;;;;;OAQG;IACH,uGA2BC;IAXG,sBAAkB;IAElB,uBAAoB;IACpB,2BAA4B;IAC5B,oCAA8C;IAC9C,gCAAsC;IAEtC,oBAAqB;IACrB,kBAAkB;IAKtB,cA8PC;CACJ;sBA7UqB,wCAAwC"}
@@ -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
+ }