@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,18 @@
1
+ import {CanvasView} from "../../../../view/elements/CanvasView.js";
2
+ import AABB2 from "../../../../core/geom/2d/aabb/AABB2.js";
3
+
4
+ export class UIContext{
5
+
6
+ constructor(curve, size, margin){
7
+
8
+ this.curve = curve
9
+
10
+ this.margin = margin
11
+
12
+ this.graph = new CanvasView();
13
+ this.graph.size.copy(size)
14
+
15
+ this.frame = new AABB2();
16
+
17
+ }
18
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Modify the axis start and end value based on given scaling
3
+ * @param {number} axisLength
4
+ * @param {number} cursorToGraphPos
5
+ * @param {number} axisStart
6
+ * @param {number} axisEnd
7
+ * @param {number} scaling
8
+ * @returns {(number|*)[]}
9
+ */
10
+ export function updateAxisRange(axisLength: number, cursorToGraphPos: number, axisStart: number, axisEnd: number, scaling: number): (number | any)[];
11
+ //# sourceMappingURL=updateAxisRange.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateAxisRange.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/editor/updateAxisRange.js"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,4CAPW,MAAM,oBACN,MAAM,aACN,MAAM,WACN,MAAM,WACN,MAAM,GACJ,CAAC,MAAM,MAAE,CAAC,EAAE,CAaxB"}
@@ -0,0 +1,23 @@
1
+
2
+
3
+ /**
4
+ * Modify the axis start and end value based on given scaling
5
+ * @param {number} axisLength
6
+ * @param {number} cursorToGraphPos
7
+ * @param {number} axisStart
8
+ * @param {number} axisEnd
9
+ * @param {number} scaling
10
+ * @returns {(number|*)[]}
11
+ */
12
+ export function updateAxisRange(axisLength,cursorToGraphPos, axisStart, axisEnd, scaling){
13
+
14
+ let axisRange = axisEnd - axisStart;
15
+ const ratioCursorToGraphX = cursorToGraphPos / axisLength;
16
+ const axisCentre = axisStart + (ratioCursorToGraphX * axisRange);
17
+
18
+ axisRange = (axisEnd - axisStart) / scaling;
19
+ axisStart = axisCentre - (ratioCursorToGraphX * axisRange);
20
+ axisEnd = axisCentre + (1 - ratioCursorToGraphX) * axisRange;
21
+
22
+ return [axisStart, axisEnd];
23
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ *
3
+ * @param {Keyframe} selectedKeyframe
4
+ * @param {Vector2} deltaPosition
5
+ * @param {AnimationCurve} curve
6
+ */
7
+ export function updateKeyframePosition(selectedKeyframe: Keyframe, deltaPosition: Vector2, curve: AnimationCurve): void;
8
+ import Vector2 from "../../../../core/geom/Vector2.js";
9
+ //# sourceMappingURL=updateKeyframePosition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateKeyframePosition.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/editor/updateKeyframePosition.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,yDAJW,QAAQ,iBACR,OAAO,+BAOjB;oBAZmB,kCAAkC"}
@@ -0,0 +1,38 @@
1
+ import Vector2 from "../../../../core/geom/Vector2.js";
2
+
3
+ /**
4
+ *
5
+ * @param {Keyframe} selectedKeyframe
6
+ * @param {Vector2} deltaPosition
7
+ * @param {AnimationCurve} curve
8
+ */
9
+ export function updateKeyframePosition(selectedKeyframe, deltaPosition, curve) {
10
+ selectedKeyframe.time += deltaPosition.x;
11
+ selectedKeyframe.value += deltaPosition.y;
12
+ updateKeyFrameIndexes(curve, selectedKeyframe);
13
+ }
14
+
15
+ /**
16
+ *
17
+ * @param {AnimationCurve} curve
18
+ * @param {Keyframe} keyframe
19
+ */
20
+ function updateKeyFrameIndexes(curve, keyframe) {
21
+ let keyframeIndex = curve.keys.indexOf(keyframe);
22
+
23
+ if (keyframeIndex < (curve.keys.length - 1) && keyframe.time > curve.keys[keyframeIndex + 1].time) {
24
+ const nextIndex = keyframeIndex + 1;
25
+ const next = curve.keys[nextIndex];
26
+
27
+ curve.keys[nextIndex] = keyframe;
28
+ curve.keys[keyframeIndex] = next;
29
+
30
+ } else if (keyframeIndex > 0 && keyframe.time < curve.keys[keyframeIndex - 1].time) {
31
+ const prevIndex = keyframeIndex - 1;
32
+ const prev = curve.keys[prevIndex];
33
+
34
+ curve.keys[prevIndex] = keyframe;
35
+ curve.keys[keyframeIndex] = prev;
36
+
37
+ }
38
+ }
@@ -0,0 +1,2 @@
1
+ export function updateMarkerPosition(graph: any, frame: any, margin: any, keyframe: any, vContainerMarker: any): void;
2
+ //# sourceMappingURL=updateMarkerPosition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateMarkerPosition.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/editor/updateMarkerPosition.js"],"names":[],"mappings":"AAEA,sHASC"}
@@ -0,0 +1,12 @@
1
+ import {position_curve_to_canvas} from "../draw/position_curve_to_canvas.js";
2
+
3
+ export function updateMarkerPosition(graph, frame, margin, keyframe, vContainerMarker) {
4
+ const canvasCoordinates = position_curve_to_canvas(
5
+ graph.size,
6
+ frame,
7
+ margin,
8
+ keyframe.time,
9
+ keyframe.value
10
+ );
11
+ vContainerMarker.position.copy(canvasCoordinates);
12
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ *
3
+ * @param {KeyframeStateManager} keyframeStateManager
4
+ * @param {Keyframe} keyframe
5
+ * @param {EmptyView} vTangentEditor
6
+ * @param {View} marker
7
+ */
8
+ export function updateMarkerVisual(keyframeStateManager: KeyframeStateManager, keyframe: Keyframe, vTangentEditor: EmptyView, marker: View): void;
9
+ //# sourceMappingURL=updateMarkerVisual.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateMarkerVisual.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/editor/updateMarkerVisual.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,yFAJW,QAAQ,iDAalB"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ *
3
+ * @param {KeyframeStateManager} keyframeStateManager
4
+ * @param {Keyframe} keyframe
5
+ * @param {EmptyView} vTangentEditor
6
+ * @param {View} marker
7
+ */
8
+ export function updateMarkerVisual(keyframeStateManager, keyframe, vTangentEditor, marker) {
9
+ const markerView = keyframeStateManager.keyframeViews.get(keyframe);
10
+ const markerColour = getKeyframeMarkerColour(keyframeStateManager, keyframe);
11
+
12
+ updateTangentMarker(keyframeStateManager, keyframe, markerView, vTangentEditor)
13
+
14
+ marker.css({
15
+ background: markerColour
16
+ });
17
+ }
18
+
19
+ /**
20
+ * Acquire the pre-defined colour for marker(keyframe) based on the keyframe selection state
21
+ * @param {KeyframeStateManager} keyframeStateManager
22
+ * @param {Keyframe} keyframe
23
+ * @returns {string}
24
+ */
25
+ function getKeyframeMarkerColour(keyframeStateManager, keyframe) {
26
+ const activeKeyframe = keyframeStateManager.observedActiveKeyframe;
27
+ const selectedKeyframes = keyframeStateManager.selectedKeyframes;
28
+
29
+ if (activeKeyframe.get() === keyframe) {
30
+ return '#FFFFFF'
31
+ } else if (selectedKeyframes.find(kf => kf === keyframe)) {
32
+ return '#B700FFFF'
33
+ } else {
34
+ return '#00ff00'
35
+ }
36
+ }
37
+
38
+ function updateTangentMarker(keyframeStateManager, keyframe, markerView, vTangentEditor) {
39
+ const activeKeyframe = keyframeStateManager.observedActiveKeyframe;
40
+ const selectedKeyframes = keyframeStateManager.selectedKeyframes;
41
+
42
+ if (activeKeyframe.get() === keyframe) {
43
+ if (!markerView.hasChild(vTangentEditor))
44
+ markerView.addChild(vTangentEditor);
45
+ } else if (selectedKeyframes.find(kf => kf === keyframe)) { //Todo remove if covered by else condition
46
+ if (markerView.hasChild(vTangentEditor))
47
+ markerView.removeChild(vTangentEditor);
48
+ } else {
49
+ if (markerView.hasChild(vTangentEditor))
50
+ markerView.removeChild(vTangentEditor);
51
+ }
52
+ }
53
+
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Attaches drag & drop to an element
3
+ * @param {HTMLElement} el
4
+ * @param {(data: any) => void} data
5
+ */
6
+ export function uploadViaElement(el: HTMLElement, data: (data: any) => void): void;
7
+ //# sourceMappingURL=uploadViaElement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploadViaElement.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/editor/uploadViaElement.js"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,qCAHW,WAAW,eACJ,GAAG,KAAK,IAAI,QA6B7B"}
@@ -0,0 +1,35 @@
1
+ import {DragEvents} from "../../../input/devices/events/DragEvents.js";
2
+
3
+ /**
4
+ * Attaches drag & drop to an element
5
+ * @param {HTMLElement} el
6
+ * @param {(data: any) => void} data
7
+ */
8
+ export function uploadViaElement(el, data) {
9
+ if (!el) throw new Error("Element is required");
10
+
11
+ el.addEventListener(DragEvents.DragOver, (e) => {
12
+ // console.log("dragging over element");
13
+ e.preventDefault(); // prevent browser from opening file
14
+ });
15
+
16
+ el.addEventListener(DragEvents.Drop, (e) => {
17
+ e.preventDefault();
18
+
19
+ const file = e.dataTransfer.files[0];
20
+ if (!file) return;
21
+
22
+ const reader = new FileReader();
23
+ reader.readAsText(file);
24
+ reader.onload = () => {
25
+ try {
26
+ const text = String(reader.result).replace(/^\uFEFF/, '').trim();
27
+ data(text);
28
+ // console.log("Imported data: ", text);
29
+
30
+ } catch (err) {
31
+ console.error("Error reading file: ", err);
32
+ }
33
+ };
34
+ });
35
+ }
@@ -1,9 +0,0 @@
1
- /**
2
- *
3
- * @param {AnimationCurve} curve
4
- * @param {Vector2} [size]
5
- * @param {Vector2} [margin] How much space to leave empty around the plotted bounds
6
- * @returns {View}
7
- */
8
- export function build_curve_editor({ curve, size, margin }: AnimationCurve): View;
9
- //# sourceMappingURL=build_curve_editor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build_curve_editor.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/animation/curve/draw/build_curve_editor.js"],"names":[],"mappings":"AAiEA;;;;;;GAMG;AACH,kFAiSC"}
@@ -1,362 +0,0 @@
1
- import Signal from "../../../../core/events/signal/Signal.js";
2
- import AABB2 from "../../../../core/geom/2d/aabb/AABB2.js";
3
- import Vector2 from "../../../../core/geom/Vector2.js";
4
- import ObservedValue from "../../../../core/model/ObservedValue.js";
5
- import { number_pretty_print } from "../../../../core/primitives/numbers/number_pretty_print.js";
6
- import LabelView from "../../../../view/common/LabelView.js";
7
- import { CSS_ABSOLUTE_POSITIONING } from "../../../../view/CSS_ABSOLUTE_POSITIONING.js";
8
- import { CanvasView } from "../../../../view/elements/CanvasView.js";
9
- import EmptyView from "../../../../view/elements/EmptyView.js";
10
- import { canvas2d_plot_data_line } from "../../../graphics/canvas/canvas2d_plot_data_line.js";
11
- import { MouseEvents } from "../../../input/devices/events/MouseEvents.js";
12
- import { readPositionFromMouseEvent } from "../../../input/devices/PointerDevice.js";
13
- import { DraggableAspect } from "../../../ui/DraggableAspect.js";
14
- import { animation_curve_compute_aabb } from "../animation_curve_compute_aabb.js";
15
- import { sample_animation_curve_to_float_array } from "../compression/sample_animation_curve_to_float_array.js";
16
- import { Keyframe } from "../Keyframe.js";
17
- import { build_tangent_editor } from "./build_tangent_editor.js";
18
-
19
- /**
20
- *
21
- * @param {Vector2} size
22
- * @param {AABB2} frame
23
- * @param {Vector2} margin
24
- * @param {number} x
25
- * @param {number} y
26
- * @return {Vector2}
27
- */
28
- function position_curve_to_canvas(size, frame, margin, x, y) {
29
- const width = size.x;
30
- const height = size.y;
31
-
32
- const curve_width = frame.getWidth();
33
- const curve_width_multiplier = curve_width > 0 ? 1 / curve_width : 0;
34
- const u = (x - frame.x0) * curve_width_multiplier;
35
-
36
- const curve_height = frame.getHeight();
37
- const curve_height_multiplier = curve_height > 0 ? 1 / curve_height : 0;
38
- const v = 1 - (y - frame.y0) * curve_height_multiplier;
39
-
40
- return new Vector2(margin.x + (u * (width - margin.x * 2)), margin.y + v * (height - margin.y * 2));
41
- }
42
-
43
- /**
44
- *
45
- * @param {Vector2} size
46
- * @param {AABB2} frame
47
- * @param {Vector2} margin
48
- * @param {number} x
49
- * @param {number} y
50
- * @return {Vector2}
51
- */
52
- function position_canvas_to_curve(size, frame, margin, x, y) {
53
-
54
- const width = size.x;
55
- const height = size.y;
56
-
57
- const u = (x - margin.x) / (width - margin.x * 2);
58
- const v = 1 - (y - margin.y) / (height - margin.y * 2);
59
-
60
- return new Vector2(
61
- u * frame.getWidth() + frame.x0,
62
- v * frame.getHeight() + frame.y0
63
- );
64
- }
65
-
66
- /**
67
- *
68
- * @param {AnimationCurve} curve
69
- * @param {Vector2} [size]
70
- * @param {Vector2} [margin] How much space to leave empty around the plotted bounds
71
- * @returns {View}
72
- */
73
- export function build_curve_editor({
74
- curve,
75
- size = new Vector2(300, 300),
76
- margin = new Vector2(36, 36)
77
- }) {
78
-
79
- const vContainer = new EmptyView({
80
- css: {
81
- pointerEvents: "auto"
82
- }
83
- });
84
-
85
- const graph = new CanvasView();
86
- graph.size.copy(size);
87
-
88
- const frame = new AABB2();
89
-
90
- const frame_updated = new Signal();
91
-
92
- /**
93
- *
94
- * @type {ObservedValue<Keyframe>}
95
- */
96
- const active_keyframe = new ObservedValue(null);
97
-
98
- const vCoordinate = new LabelView("", {
99
- css: {
100
- ...CSS_ABSOLUTE_POSITIONING,
101
- zIndex: 1000,
102
- background: `rgba(0, 0, 0, 0.4)`,
103
- padding: '4px 6px',
104
- color: 'white',
105
- font: '12px Tahoma, monospaced'
106
- }
107
- });
108
-
109
- function handle_curve_update() {
110
- animation_curve_compute_aabb(frame, curve);
111
-
112
- frame_updated.send0();
113
-
114
- update_graph();
115
- }
116
-
117
-
118
- function update_graph() {
119
- const width = graph.size.x;
120
- const data = new Float32Array(width);
121
-
122
- sample_animation_curve_to_float_array(data, 0, curve, data.length);
123
-
124
- canvas2d_plot_data_line({
125
- data,
126
- ctx: graph.context2d,
127
- width: width,
128
- height: graph.size.y,
129
- margin: margin,
130
- range_y: [frame.y0, frame.y1],
131
- range_x: [frame.x0, frame.x1],
132
- });
133
- }
134
-
135
- const keyframe_views = new Map();
136
-
137
- /**
138
- *
139
- * @param {Keyframe} keyframe
140
- */
141
- function add_keyframe(keyframe) {
142
- const vContainerMarker = new EmptyView({
143
- css: {
144
- position: "absolute",
145
- top: 0,
146
- left: 0,
147
- pointerEvents: "none"
148
- }
149
- });
150
-
151
- const marker_size = 8;
152
- const marker = new EmptyView({
153
- css: {
154
- width: `${marker_size}px`,
155
- height: `${marker_size}px`,
156
- background: "#00ff00",
157
- border: "none",
158
- position: "absolute",
159
- top: `-${marker_size / 2}px`,
160
- left: `-${marker_size / 2}px`,
161
- pointerEvents: "auto",
162
- borderRadius: `${marker_size}px`
163
- }
164
- });
165
-
166
- // add extra element for mouse event capture to make it easier to click on the marker
167
- const marker_hit_pad_size = 24;
168
- marker.addChild(new EmptyView({
169
- css: {
170
- opacity: 0,
171
- width: `${marker_hit_pad_size}px`,
172
- height: `${marker_hit_pad_size}px`,
173
- borderRadius: `${marker_hit_pad_size}px`,
174
- // background: 'rgba(255,0,0,0.2)',
175
- position: "absolute",
176
- top: `-${(marker_hit_pad_size - marker_size) / 2}px`,
177
- left: `-${(marker_hit_pad_size - marker_size) / 2}px`
178
- }
179
- }))
180
-
181
- function updatePosition() {
182
- const canvas_coordinates = position_curve_to_canvas(
183
- graph.size,
184
- frame,
185
- margin,
186
- keyframe.time,
187
- keyframe.value
188
- );
189
- vContainerMarker.position.copy(canvas_coordinates);
190
- }
191
-
192
- function updateActiveState() {
193
- if (active_keyframe.get() === keyframe) {
194
- marker.css({
195
- background: '#FFFFFF'
196
- });
197
- } else {
198
- marker.css({
199
- background: '#00ff00'
200
- });
201
- }
202
- }
203
-
204
- updatePosition();
205
-
206
- const marker_el = marker.el;
207
-
208
- const previous = new Vector2();
209
- const draggable = new DraggableAspect({
210
- el: marker_el,
211
- drag(position) {
212
- const delta = new Vector2();
213
- delta.subVectors(position, previous);
214
-
215
- const keyframe_coord = position_canvas_to_curve(
216
- graph.size,
217
- frame,
218
- margin,
219
- position.x,
220
- position.y
221
- );
222
-
223
- // console.log(keyframe_coord);
224
-
225
- keyframe.time = keyframe_coord.x;
226
- keyframe.value = keyframe_coord.y;
227
-
228
- vCoordinate.updateText(`${number_pretty_print(keyframe_coord.x)}, ${number_pretty_print(keyframe_coord.y)}`);
229
- vCoordinate.position.set(
230
- position.x,
231
- position.y - 24
232
- );
233
-
234
- let keyframe_index = curve.keys.indexOf(keyframe);
235
-
236
- if (keyframe_index < (curve.keys.length - 1) && keyframe.time > curve.keys[keyframe_index + 1].time) {
237
- const next_index = keyframe_index + 1;
238
- const next = curve.keys[next_index];
239
-
240
- curve.keys[next_index] = keyframe;
241
- curve.keys[keyframe_index] = next;
242
-
243
- keyframe_index = next_index;
244
- } else if (keyframe_index > 0 && keyframe.time < curve.keys[keyframe_index - 1].time) {
245
- const prev_index = keyframe_index - 1;
246
- const prev = curve.keys[prev_index];
247
-
248
- curve.keys[prev_index] = keyframe;
249
- curve.keys[keyframe_index] = prev;
250
-
251
- keyframe_index = prev_index;
252
- }
253
-
254
- curve.alignTangents(keyframe_index);
255
- curve.smoothTangents(keyframe_index, 1);
256
-
257
- if (keyframe_index > 0) {
258
- curve.alignTangents(keyframe_index - 1);
259
- curve.smoothTangents(keyframe_index - 1, 1);
260
- }
261
- if (keyframe_index < curve.keys.length - 1) {
262
- curve.alignTangents(keyframe_index + 1);
263
- curve.smoothTangents(keyframe_index + 1, 1);
264
- }
265
-
266
- updatePosition();
267
- update_graph();
268
-
269
- previous.copy(position);
270
- },
271
- dragStart(position) {
272
- previous.copy(position);
273
-
274
- active_keyframe.set(keyframe);
275
-
276
- vContainer.addChild(vCoordinate);
277
- },
278
- dragEnd() {
279
- handle_curve_update();
280
-
281
- vContainer.removeChild(vCoordinate);
282
- }
283
- });
284
-
285
- draggable.getPointer().on.tap.add(
286
- /**
287
- *
288
- * @param position
289
- * @param {MouseEvent} event
290
- */
291
- (position, event) => {
292
- // make active
293
- active_keyframe.set(keyframe);
294
-
295
- if (event.ctrlKey) {
296
- // remove
297
- curve.remove(keyframe);
298
- remove_keyframe(keyframe);
299
- update_graph();
300
- }
301
- });
302
-
303
- marker.on.linked.add(draggable.start, draggable);
304
- marker.on.unlinked.add(draggable.stop, draggable);
305
-
306
- marker.bindSignal(frame_updated, updatePosition);
307
- marker.bindSignal(active_keyframe.onChanged, updateActiveState);
308
-
309
- const vTangentEditor = build_tangent_editor({
310
- keyframe: keyframe,
311
- size: graph.size,
312
- ctx: graph.context2d,
313
- frame,
314
- margin
315
- });
316
- vContainerMarker.addChild(vTangentEditor);
317
-
318
- vContainerMarker.addChild(marker);
319
-
320
- keyframe_views.set(keyframe, vContainerMarker);
321
-
322
- vContainer.addChild(vContainerMarker);
323
- }
324
-
325
- function remove_keyframe(keyframe) {
326
- const marker_view = keyframe_views.get(keyframe);
327
-
328
- vContainer.removeChild(marker_view);
329
- }
330
-
331
- graph.on.linked.add(() => {
332
- curve.keys.forEach(add_keyframe);
333
- });
334
-
335
- graph.on.unlinked.add(() => {
336
- curve.keys.forEach(remove_keyframe);
337
- });
338
-
339
- vContainer.el.addEventListener(MouseEvents.DoubleClick, (e) => {
340
-
341
- const mouse_position = new Vector2();
342
-
343
- readPositionFromMouseEvent(mouse_position, e, vContainer.el);
344
-
345
- const curve_position = position_canvas_to_curve(graph.size, frame, margin, mouse_position.x, mouse_position.y);
346
-
347
- const key = Keyframe.from(curve_position.x, curve_position.y);
348
- const key_index = curve.add(key);
349
-
350
- curve.alignTangents(key_index);
351
- curve.smoothTangents(key_index, 1);
352
-
353
- add_keyframe(key);
354
- update_graph();
355
- });
356
-
357
- graph.on.linked.add(handle_curve_update);
358
-
359
- vContainer.addChild(graph);
360
-
361
- return vContainer;
362
- }