plotboilerplate 1.24.0 → 1.26.0
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/README.md +14 -1
- package/dist/index.esm.js +433 -162
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.min.js +1 -1
- package/dist/index.esm.min.js.map +1 -1
- package/dist/plotboilerplate.browser.min.js +1 -1
- package/dist/plotboilerplate.browser.min.js.map +1 -1
- package/dist/plotboilerplate.js +12312 -12041
- package/dist/plotboilerplate.min.js +1 -1
- package/package.json +9 -5
- package/src/cjs/Bounds.d.ts +79 -25
- package/src/cjs/Bounds.js +102 -29
- package/src/cjs/Bounds.js.map +1 -1
- package/src/cjs/CircleSector.d.ts +3 -0
- package/src/cjs/CircleSector.js +28 -1
- package/src/cjs/CircleSector.js.map +1 -1
- package/src/cjs/PlotBoilerplate.d.ts +37 -6
- package/src/cjs/PlotBoilerplate.js +222 -116
- package/src/cjs/PlotBoilerplate.js.map +1 -1
- package/src/cjs/Polygon.d.ts +26 -7
- package/src/cjs/Polygon.js +56 -10
- package/src/cjs/Polygon.js.map +1 -1
- package/src/cjs/Triangle.js +2 -2
- package/src/cjs/Triangle.js.map +1 -1
- package/src/cjs/Vertex.d.ts +15 -3
- package/src/cjs/Vertex.js +18 -1
- package/src/cjs/Vertex.js.map +1 -1
- package/src/cjs/drawutilssvg.d.ts +2 -1
- package/src/cjs/drawutilssvg.js +9 -3
- package/src/cjs/drawutilssvg.js.map +1 -1
- package/src/cjs/interfaces/core.d.ts +28 -0
- package/src/cjs/interfaces/core.js +2 -0
- package/src/cjs/interfaces/core.js.map +1 -1
- package/src/cjs/utils/LissajousFigure.d.ts +34 -0
- package/src/cjs/utils/LissajousFigure.js +100 -0
- package/src/cjs/utils/LissajousFigure.js.map +1 -0
- package/src/cjs/utils/PerlinNoise.d.ts +19 -0
- package/src/cjs/utils/PerlinNoise.js +352 -0
- package/src/cjs/utils/PerlinNoise.js.map +1 -0
- package/src/cjs/utils/SVGPathUtils.d.ts +22 -0
- package/src/cjs/utils/SVGPathUtils.js +45 -0
- package/src/cjs/utils/SVGPathUtils.js.map +1 -0
- package/src/cjs/utils/algorithms/pixelCornersToRoundPaths.d.ts +23 -0
- package/src/cjs/utils/algorithms/pixelCornersToRoundPaths.js +270 -0
- package/src/cjs/utils/algorithms/pixelCornersToRoundPaths.js.map +1 -0
- package/src/cjs/utils/datastructures/Color.d.ts +147 -1
- package/src/cjs/utils/datastructures/Color.js +385 -41
- package/src/cjs/utils/datastructures/Color.js.map +1 -1
- package/src/cjs/utils/datastructures/ColorGradient.d.ts +79 -0
- package/src/cjs/utils/datastructures/ColorGradient.js +171 -0
- package/src/cjs/utils/datastructures/ColorGradient.js.map +1 -0
- package/src/cjs/utils/datastructures/DataGrid2d.d.ts +6 -0
- package/src/cjs/utils/datastructures/DataGrid2dArrayMatrix.d.ts +88 -0
- package/src/cjs/utils/datastructures/DataGrid2dArrayMatrix.js +155 -0
- package/src/cjs/utils/datastructures/DataGrid2dArrayMatrix.js.map +1 -0
- package/src/cjs/utils/datastructures/DataGrid2dListAdapter.d.ts +1 -7
- package/src/cjs/utils/datastructures/DataGrid2dListAdapter.js +3 -3
- package/src/cjs/utils/datastructures/DataGrid2dListAdapter.js.map +1 -1
- package/src/cjs/utils/datastructures/GeometryMesh.d.ts +49 -0
- package/src/cjs/utils/datastructures/GeometryMesh.js +58 -0
- package/src/cjs/utils/datastructures/GeometryMesh.js.map +1 -0
- package/src/cjs/utils/detectDarkMode.js +16 -7
- package/src/cjs/utils/detectDarkMode.js.map +1 -1
- package/src/cjs/utils/dom/components/ColorGradientPicker.d.ts +246 -0
- package/src/cjs/utils/dom/components/ColorGradientPicker.js +667 -0
- package/src/cjs/utils/dom/components/ColorGradientPicker.js.map +1 -0
- package/src/cjs/utils/dom/components/ColorGradientPickerJSX.d.ts +129 -0
- package/src/cjs/utils/dom/components/ColorGradientPickerJSX.js +520 -0
- package/src/cjs/utils/dom/components/ColorGradientPickerJSX.js.map +1 -0
- package/src/cjs/utils/dom/components/ColorGradientSelector.d.ts +118 -0
- package/src/cjs/utils/dom/components/ColorGradientSelector.js +327 -0
- package/src/cjs/utils/dom/components/ColorGradientSelector.js.map +1 -0
- package/src/cjs/utils/dom/components/Test.d.ts +7 -0
- package/src/cjs/utils/dom/components/Test.js +30 -0
- package/src/cjs/utils/dom/components/Test.js.map +1 -0
- package/src/cjs/utils/dom/guiSizeToggler.js +1 -1
- package/src/cjs/utils/dom/guiSizeToggler.js.map +1 -1
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.d.ts +9 -3
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js +20 -13
- package/src/cjs/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/cjs/utils/helpers/CircleHelper.d.ts +10 -1
- package/src/cjs/utils/helpers/CircleHelper.js +13 -2
- package/src/cjs/utils/helpers/CircleHelper.js.map +1 -1
- package/src/cjs/utils/helpers/CircleSectorHelper.d.ts +2 -2
- package/src/cjs/utils/helpers/CircleSectorHelper.js +1 -0
- package/src/cjs/utils/helpers/CircleSectorHelper.js.map +1 -1
- package/src/cjs/utils/helpers/TriangleHelper.d.ts +57 -0
- package/src/cjs/utils/helpers/TriangleHelper.js +83 -0
- package/src/cjs/utils/helpers/TriangleHelper.js.map +1 -0
- package/src/cjs/utils/helpers/VEllipseHelper.d.ts +6 -4
- package/src/cjs/utils/helpers/VEllipseHelper.js +4 -2
- package/src/cjs/utils/helpers/VEllipseHelper.js.map +1 -1
- package/src/cjs/utils/helpers/VEllipseSectorHelper.d.ts +3 -2
- package/src/cjs/utils/helpers/VEllipseSectorHelper.js +1 -0
- package/src/cjs/utils/helpers/VEllipseSectorHelper.js.map +1 -1
- package/src/cjs/utils/parsers/LinearColorGradientParser.d.ts +78 -0
- package/src/cjs/utils/parsers/LinearColorGradientParser.js +224 -0
- package/src/cjs/utils/parsers/LinearColorGradientParser.js.map +1 -0
- package/src/cjs/utils/parsers/svg/types.d.ts +8 -8
- package/src/createDemoDrawables.js +1 -0
- package/src/esm/Bounds.d.ts +79 -25
- package/src/esm/Bounds.js +102 -29
- package/src/esm/Bounds.js.map +1 -1
- package/src/esm/CircleSector.d.ts +3 -0
- package/src/esm/CircleSector.js +28 -1
- package/src/esm/CircleSector.js.map +1 -1
- package/src/esm/PlotBoilerplate.d.ts +37 -6
- package/src/esm/PlotBoilerplate.js +222 -116
- package/src/esm/PlotBoilerplate.js.map +1 -1
- package/src/esm/Polygon.d.ts +26 -7
- package/src/esm/Polygon.js +53 -10
- package/src/esm/Polygon.js.map +1 -1
- package/src/esm/Triangle.js +2 -2
- package/src/esm/Triangle.js.map +1 -1
- package/src/esm/Vertex.d.ts +15 -3
- package/src/esm/Vertex.js +18 -1
- package/src/esm/Vertex.js.map +1 -1
- package/src/esm/drawutilssvg.d.ts +2 -1
- package/src/esm/drawutilssvg.js +9 -3
- package/src/esm/drawutilssvg.js.map +1 -1
- package/src/esm/interfaces/core.d.ts +28 -0
- package/src/esm/interfaces/core.js +2 -0
- package/src/esm/interfaces/core.js.map +1 -1
- package/src/esm/utils/LissajousFigure.d.ts +34 -0
- package/src/esm/utils/LissajousFigure.js +95 -0
- package/src/esm/utils/LissajousFigure.js.map +1 -0
- package/src/esm/utils/PerlinNoise.d.ts +19 -0
- package/src/esm/utils/PerlinNoise.js +346 -0
- package/src/esm/utils/PerlinNoise.js.map +1 -0
- package/src/esm/utils/SVGPathUtils.d.ts +22 -0
- package/src/esm/utils/SVGPathUtils.js +42 -0
- package/src/esm/utils/SVGPathUtils.js.map +1 -0
- package/src/esm/utils/algorithms/pixelCornersToRoundPaths.d.ts +23 -0
- package/src/esm/utils/algorithms/pixelCornersToRoundPaths.js +266 -0
- package/src/esm/utils/algorithms/pixelCornersToRoundPaths.js.map +1 -0
- package/src/esm/utils/datastructures/Color.d.ts +147 -1
- package/src/esm/utils/datastructures/Color.js +386 -42
- package/src/esm/utils/datastructures/Color.js.map +1 -1
- package/src/esm/utils/datastructures/ColorGradient.d.ts +79 -0
- package/src/esm/utils/datastructures/ColorGradient.js +166 -0
- package/src/esm/utils/datastructures/ColorGradient.js.map +1 -0
- package/src/esm/utils/datastructures/DataGrid2d.d.ts +6 -0
- package/src/esm/utils/datastructures/DataGrid2dArrayMatrix.d.ts +88 -0
- package/src/esm/utils/datastructures/DataGrid2dArrayMatrix.js +150 -0
- package/src/esm/utils/datastructures/DataGrid2dArrayMatrix.js.map +1 -0
- package/src/esm/utils/datastructures/DataGrid2dListAdapter.d.ts +1 -7
- package/src/esm/utils/datastructures/DataGrid2dListAdapter.js +3 -3
- package/src/esm/utils/datastructures/DataGrid2dListAdapter.js.map +1 -1
- package/src/esm/utils/datastructures/GeometryMesh.d.ts +49 -0
- package/src/esm/utils/datastructures/GeometryMesh.js +53 -0
- package/src/esm/utils/datastructures/GeometryMesh.js.map +1 -0
- package/src/esm/utils/detectDarkMode.js +16 -7
- package/src/esm/utils/detectDarkMode.js.map +1 -1
- package/src/esm/utils/dom/components/ColorGradientPicker.d.ts +246 -0
- package/src/esm/utils/dom/components/ColorGradientPicker.js +743 -0
- package/src/esm/utils/dom/components/ColorGradientPicker.js.map +1 -0
- package/src/esm/utils/dom/components/ColorGradientPickerJSX.d.ts +129 -0
- package/src/esm/utils/dom/components/ColorGradientPickerJSX.js +582 -0
- package/src/esm/utils/dom/components/ColorGradientPickerJSX.js.map +1 -0
- package/src/esm/utils/dom/components/ColorGradientSelector.d.ts +118 -0
- package/src/esm/utils/dom/components/ColorGradientSelector.js +339 -0
- package/src/esm/utils/dom/components/ColorGradientSelector.js.map +1 -0
- package/src/esm/utils/dom/components/Test.d.ts +7 -0
- package/src/esm/utils/dom/components/Test.js +26 -0
- package/src/esm/utils/dom/components/Test.js.map +1 -0
- package/src/esm/utils/dom/guiSizeToggler.js +1 -1
- package/src/esm/utils/dom/guiSizeToggler.js.map +1 -1
- package/src/esm/utils/helpers/BezierPathInteractionHelper.d.ts +9 -3
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js +20 -13
- package/src/esm/utils/helpers/BezierPathInteractionHelper.js.map +1 -1
- package/src/esm/utils/helpers/CircleHelper.d.ts +10 -1
- package/src/esm/utils/helpers/CircleHelper.js +13 -2
- package/src/esm/utils/helpers/CircleHelper.js.map +1 -1
- package/src/esm/utils/helpers/CircleSectorHelper.d.ts +2 -2
- package/src/esm/utils/helpers/CircleSectorHelper.js +1 -0
- package/src/esm/utils/helpers/CircleSectorHelper.js.map +1 -1
- package/src/esm/utils/helpers/TriangleHelper.d.ts +57 -0
- package/src/esm/utils/helpers/TriangleHelper.js +78 -0
- package/src/esm/utils/helpers/TriangleHelper.js.map +1 -0
- package/src/esm/utils/helpers/VEllipseHelper.d.ts +6 -4
- package/src/esm/utils/helpers/VEllipseHelper.js +4 -2
- package/src/esm/utils/helpers/VEllipseHelper.js.map +1 -1
- package/src/esm/utils/helpers/VEllipseSectorHelper.d.ts +3 -2
- package/src/esm/utils/helpers/VEllipseSectorHelper.js +1 -0
- package/src/esm/utils/helpers/VEllipseSectorHelper.js.map +1 -1
- package/src/esm/utils/parsers/LinearColorGradientParser.d.ts +78 -0
- package/src/esm/utils/parsers/LinearColorGradientParser.js +217 -0
- package/src/esm/utils/parsers/LinearColorGradientParser.js.map +1 -0
- package/src/esm/utils/parsers/svg/types.d.ts +8 -8
- package/src/external.d.ts +9 -0
- package/src/ts/Bounds.ts +107 -22
- package/src/ts/CircleSector.ts +39 -6
- package/src/ts/PlotBoilerplate.ts +233 -105
- package/src/ts/Polygon.ts +68 -14
- package/src/ts/Triangle.ts +2 -2
- package/src/ts/Vertex.ts +21 -3
- package/src/ts/drawutilssvg.ts +8 -3
- package/src/ts/interfaces/core.ts +31 -0
- package/src/ts/utils/LissajousFigure.ts +110 -0
- package/src/ts/utils/PerlinNoise.ts +368 -0
- package/src/ts/utils/SVGPathUtils.ts +55 -0
- package/src/ts/utils/algorithms/pixelCornersToRoundPaths.ts +379 -0
- package/src/ts/utils/datastructures/Color.ts +423 -44
- package/src/ts/utils/datastructures/ColorGradient.ts +196 -0
- package/src/ts/utils/datastructures/DataGrid2d.ts +7 -0
- package/src/ts/utils/datastructures/DataGrid2dArrayMatrix.ts +182 -0
- package/src/ts/utils/datastructures/DataGrid2dListAdapter.ts +4 -11
- package/src/ts/utils/datastructures/GeometryMesh.ts +79 -0
- package/src/ts/utils/detectDarkMode.ts +17 -8
- package/src/ts/utils/dom/components/ColorGradientPicker.tsx +889 -0
- package/src/ts/utils/dom/components/ColorGradientSelector.tsx +452 -0
- package/src/ts/utils/dom/components/Test.tsx +44 -0
- package/src/ts/utils/dom/components/_ColorGradientPicker_raw.ts_ +392 -0
- package/src/ts/utils/dom/guiSizeToggler.ts +1 -1
- package/src/ts/utils/helpers/BezierPathInteractionHelper.ts +25 -15
- package/src/ts/utils/helpers/CircleHelper.ts +17 -3
- package/src/ts/utils/helpers/CircleSectorHelper.ts +4 -2
- package/src/ts/utils/helpers/TriangleHelper.ts +102 -0
- package/src/ts/utils/helpers/VEllipseHelper.ts +6 -4
- package/src/ts/utils/helpers/VEllipseSectorHelper.ts +3 -2
- package/src/ts/utils/parsers/LinearColorGradientParser.ts +297 -0
- package/src/ts/utils/parsers/svg/types.ts +8 -8
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @author Ikaros Kappler
|
|
3
|
+
* @date 2025-06-07
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export class ColorGradientPicker {
|
|
8
|
+
private baseID: number;
|
|
9
|
+
|
|
10
|
+
private container: HTMLElement;
|
|
11
|
+
private sliderElements: Array<HTMLInputElement>;
|
|
12
|
+
private colorInput: HTMLInputElement;
|
|
13
|
+
private indicatorContainer: HTMLDivElement;
|
|
14
|
+
private colorIndicatorButton: HTMLButtonElement;
|
|
15
|
+
private sliderMin: number = 0;
|
|
16
|
+
private sliderMax: number = 100;
|
|
17
|
+
private indicatorWidth_num = 1.0;
|
|
18
|
+
private indicatorWidth = "1em";
|
|
19
|
+
private indicatorWidth_half = "0.5em";
|
|
20
|
+
private indicatorHeight = "1em";
|
|
21
|
+
|
|
22
|
+
private COLORSET: Array<string> = ["red", "orange", "yellow", "green", "blue", "purple"];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The constructor.
|
|
26
|
+
*
|
|
27
|
+
* Pass a container ID or nothing – in the latter case the constructor will create
|
|
28
|
+
* a new DIV element.
|
|
29
|
+
*
|
|
30
|
+
* @param {string?} containerID
|
|
31
|
+
*/
|
|
32
|
+
constructor(containerID?: string) {
|
|
33
|
+
if (containerID) {
|
|
34
|
+
const cont = document.getElementById(containerID);
|
|
35
|
+
if (!cont) {
|
|
36
|
+
throw "Cannot create ColorGradientPicker. Component ID does not exist.";
|
|
37
|
+
}
|
|
38
|
+
this.container = cont;
|
|
39
|
+
} else {
|
|
40
|
+
this.container = document.createElement("div");
|
|
41
|
+
}
|
|
42
|
+
// console.log("created", this.container);
|
|
43
|
+
this.baseID = Math.floor(Math.random() * 65535);
|
|
44
|
+
|
|
45
|
+
this.__init();
|
|
46
|
+
this.__updateBackgroundGradient();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Init the container contents.
|
|
51
|
+
*
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
private __init() {
|
|
55
|
+
this.__addCustomStyles();
|
|
56
|
+
this.__setContainerLayout();
|
|
57
|
+
console.log("Init");
|
|
58
|
+
const stepCount: number = 6;
|
|
59
|
+
this.sliderElements = [];
|
|
60
|
+
for (var i = 0; i < stepCount; i++) {
|
|
61
|
+
this.__createRangeSlider((100 / (stepCount - 1)) * i, i);
|
|
62
|
+
}
|
|
63
|
+
this.__createColorIndicator();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Apply style settings to the main container.
|
|
68
|
+
*
|
|
69
|
+
* @private
|
|
70
|
+
*/
|
|
71
|
+
private __setContainerLayout() {
|
|
72
|
+
this.container.style.display = "flex";
|
|
73
|
+
this.container.style.flexDirection = "column";
|
|
74
|
+
this.container.style.width = "100%";
|
|
75
|
+
this.container.style.height = "32px";
|
|
76
|
+
this.container.style.position = "relative";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Create a new range slider for this color gradient picker.
|
|
81
|
+
*
|
|
82
|
+
* @param {number} initialValue
|
|
83
|
+
* @param {number} index
|
|
84
|
+
*/
|
|
85
|
+
private __createRangeSlider(initialValue: number, index: number) {
|
|
86
|
+
const initialColor: string = this.COLORSET[index % this.COLORSET.length];
|
|
87
|
+
|
|
88
|
+
const rangeSlider = document.createElement("input");
|
|
89
|
+
rangeSlider.setAttribute("id", `rage-slider-${this.baseID}-${index}`);
|
|
90
|
+
rangeSlider.setAttribute("type", "range");
|
|
91
|
+
rangeSlider.setAttribute("min", `${this.sliderMin}`);
|
|
92
|
+
rangeSlider.setAttribute("max", `${this.sliderMax}`);
|
|
93
|
+
rangeSlider.setAttribute("value", `${initialValue}`);
|
|
94
|
+
this.container.appendChild(rangeSlider);
|
|
95
|
+
this.sliderElements.push(rangeSlider);
|
|
96
|
+
|
|
97
|
+
rangeSlider.style.position = "absolute";
|
|
98
|
+
rangeSlider.style.left = "0";
|
|
99
|
+
rangeSlider.style.top = "0";
|
|
100
|
+
rangeSlider.style.width = "100%";
|
|
101
|
+
|
|
102
|
+
rangeSlider.dataset["rangeSliderIndex"] = `${index}`;
|
|
103
|
+
rangeSlider.dataset["colorValue"] = initialColor;
|
|
104
|
+
const sliderHandler = this.__createSliderChangeHandler();
|
|
105
|
+
// rangeSlider.addEventListener("change", this.__createSliderChangeHandler());
|
|
106
|
+
rangeSlider.addEventListener("change", sliderHandler);
|
|
107
|
+
rangeSlider.addEventListener("click", sliderHandler);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private __createColorIndicator() {
|
|
111
|
+
this.indicatorContainer = document.createElement("div");
|
|
112
|
+
this.indicatorContainer.style["width"] = "100%";
|
|
113
|
+
// this.indicatorContainer.style["position"] = "100%";
|
|
114
|
+
|
|
115
|
+
this.colorIndicatorButton = document.createElement("button");
|
|
116
|
+
this.colorIndicatorButton.style["position"] = "absolute";
|
|
117
|
+
this.colorIndicatorButton.style["bottom"] = "0";
|
|
118
|
+
this.colorIndicatorButton.style["left"] = "0%";
|
|
119
|
+
this.colorIndicatorButton.style["background-color"] = "grey";
|
|
120
|
+
this.colorIndicatorButton.style["border-radius"] = "3px";
|
|
121
|
+
this.colorIndicatorButton.style["border"] = "1px solid grey";
|
|
122
|
+
this.colorIndicatorButton.style["width"] = this.indicatorWidth;
|
|
123
|
+
this.colorIndicatorButton.style["height"] = this.indicatorHeight;
|
|
124
|
+
this.colorIndicatorButton.style["transform"] = "translate(-50%,100%)";
|
|
125
|
+
|
|
126
|
+
this.colorInput = document.createElement("input");
|
|
127
|
+
this.colorInput.setAttribute("type", "color");
|
|
128
|
+
this.colorInput.style["visibility"] = "hidden";
|
|
129
|
+
this.colorInput.dataset["activeSliderIndex"] = "";
|
|
130
|
+
this.colorInput.addEventListener("input", this.__colorChangeHandler());
|
|
131
|
+
|
|
132
|
+
const _self = this;
|
|
133
|
+
this.colorIndicatorButton.addEventListener("click", () => {
|
|
134
|
+
console.log("clicked");
|
|
135
|
+
// _self.colorInput.dispatchEvent(new Event("input"));
|
|
136
|
+
_self.colorInput.click();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
this.indicatorContainer.appendChild(this.colorIndicatorButton);
|
|
140
|
+
this.container.appendChild(this.indicatorContainer);
|
|
141
|
+
this.container.appendChild(this.colorInput);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Get a color gradient CSS value string from the current editor settings.
|
|
146
|
+
*
|
|
147
|
+
* @instance
|
|
148
|
+
* @memberof ColorGradientPicker
|
|
149
|
+
* @returns {string}
|
|
150
|
+
*/
|
|
151
|
+
public getColorGradient(): string {
|
|
152
|
+
// Example:
|
|
153
|
+
// linear-gradient(90deg,rgba(42, 123, 155, 1) 0%, rgba(87, 199, 133, 1) 38%, rgba(161, 210, 108, 1) 68%, rgba(237, 221, 83, 1) 100%)
|
|
154
|
+
const buffer: Array<string | undefined> = ["linear-gradient( 90deg, "];
|
|
155
|
+
for (var i = 0; i < this.sliderElements.length; i++) {
|
|
156
|
+
if (i > 0) {
|
|
157
|
+
buffer.push(",");
|
|
158
|
+
}
|
|
159
|
+
const colorValue: string = this.__getSliderColor(i, "black");
|
|
160
|
+
buffer.push(colorValue);
|
|
161
|
+
// const sliderValue: number = this.__getSliderValue(i, 0.0);
|
|
162
|
+
// const percentage: number = (this.sliderMin + sliderValue) / (this.sliderMax - this.sliderMin);
|
|
163
|
+
const percentage = this.__getSliderPercentage(i);
|
|
164
|
+
buffer.push(`${percentage * 100}%`);
|
|
165
|
+
}
|
|
166
|
+
buffer.push(")");
|
|
167
|
+
|
|
168
|
+
return buffer.join(" ");
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Creates a callback function for range slider.
|
|
173
|
+
*
|
|
174
|
+
* @returns
|
|
175
|
+
*/
|
|
176
|
+
private __createSliderChangeHandler(): (e: Event) => boolean {
|
|
177
|
+
const _self = this;
|
|
178
|
+
return (e: Event): boolean => {
|
|
179
|
+
const targetSlider: HTMLInputElement = e.target as HTMLInputElement;
|
|
180
|
+
console.log("Clicked", targetSlider ? targetSlider.getAttribute("id") : null);
|
|
181
|
+
if (!targetSlider) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
const currentSliderValue: number = Number.parseFloat(targetSlider.value);
|
|
185
|
+
const rangeSliderIndexRaw: string | undefined = targetSlider.dataset["rangeSliderIndex"];
|
|
186
|
+
if (!rangeSliderIndexRaw) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
const rangeSliderIndex: number = Number.parseInt(rangeSliderIndexRaw);
|
|
190
|
+
var leftSliderValue = this.__getSliderValue(rangeSliderIndex - 1, _self.sliderMin);
|
|
191
|
+
var rightSliderValue = this.__getSliderValue(rangeSliderIndex + 1, _self.sliderMax);
|
|
192
|
+
if (leftSliderValue >= currentSliderValue) {
|
|
193
|
+
targetSlider.value = `${leftSliderValue}`;
|
|
194
|
+
_self.__updateBackgroundGradient();
|
|
195
|
+
_self.__updateColorIndicator(rangeSliderIndex);
|
|
196
|
+
return false;
|
|
197
|
+
} else if (rightSliderValue <= currentSliderValue) {
|
|
198
|
+
targetSlider.value = `${rightSliderValue}`;
|
|
199
|
+
_self.__updateBackgroundGradient();
|
|
200
|
+
_self.__updateColorIndicator(rangeSliderIndex);
|
|
201
|
+
|
|
202
|
+
return false;
|
|
203
|
+
} else {
|
|
204
|
+
_self.__updateBackgroundGradient();
|
|
205
|
+
_self.__updateColorIndicator(rangeSliderIndex);
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private __colorChangeHandler(): (_evt: Event) => boolean {
|
|
212
|
+
const _self = this;
|
|
213
|
+
return (_evt: Event): boolean => {
|
|
214
|
+
// const colorInput : HTMLInputElement | null = evt.target;
|
|
215
|
+
const activeSliderIndex_raw = this.colorInput.dataset["activeSliderIndex"];
|
|
216
|
+
if (!activeSliderIndex_raw) {
|
|
217
|
+
console.warn("Cannot update color indicator; no active range slider set.");
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
const activeSliderIndex = Number.parseInt(activeSliderIndex_raw);
|
|
221
|
+
if (Number.isNaN(activeSliderIndex) || activeSliderIndex < 0 || activeSliderIndex >= _self.sliderElements.length) {
|
|
222
|
+
console.warn("Cannot update color indicator; active index invalid or out of bounds.", activeSliderIndex);
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const newColor: string = _self.colorInput.value;
|
|
227
|
+
const rangeSlider: HTMLInputElement = _self.sliderElements[activeSliderIndex];
|
|
228
|
+
rangeSlider.dataset["colorValue"] = newColor;
|
|
229
|
+
// rangeSlider.dataset["colorValue"] = newColor;
|
|
230
|
+
this.colorIndicatorButton.style["background-color"] = newColor;
|
|
231
|
+
_self.__updateBackgroundGradient();
|
|
232
|
+
|
|
233
|
+
return true;
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Updates the container's background to display the configured color gradient.
|
|
239
|
+
*
|
|
240
|
+
* @private
|
|
241
|
+
*/
|
|
242
|
+
private __updateBackgroundGradient() {
|
|
243
|
+
const colorGradient = this.getColorGradient();
|
|
244
|
+
console.log(colorGradient);
|
|
245
|
+
this.container.style["background"] = colorGradient;
|
|
246
|
+
console.log(this.container);
|
|
247
|
+
// document.body.style["background-color"] = colorGradient;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
private __updateColorIndicator(rangeSliderIndex: number) {
|
|
251
|
+
const colorValue = this.__getSliderColor(rangeSliderIndex, "grey");
|
|
252
|
+
const ratio = this.__getSliderPercentage(rangeSliderIndex);
|
|
253
|
+
this.colorIndicatorButton.style["left"] = `calc( ${ratio * 100}% + ${(1.0 - ratio) * this.indicatorWidth_num * 0.5}em - ${
|
|
254
|
+
ratio * this.indicatorWidth_num * 0.5
|
|
255
|
+
}em)`;
|
|
256
|
+
|
|
257
|
+
this.colorIndicatorButton.style["background-color"] = colorValue;
|
|
258
|
+
this.colorInput.value = colorValue;
|
|
259
|
+
this.colorInput.dataset["activeSliderIndex"] = `${rangeSliderIndex}`;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Get the value of the n-th rangel slider.
|
|
264
|
+
*
|
|
265
|
+
* @param {number} sliderIndex
|
|
266
|
+
* @param {number} fallback
|
|
267
|
+
* @returns
|
|
268
|
+
*/
|
|
269
|
+
private __getSliderValue(sliderIndex: number, fallback: number): number {
|
|
270
|
+
if (sliderIndex < 0 || sliderIndex >= this.sliderElements.length) {
|
|
271
|
+
return fallback;
|
|
272
|
+
}
|
|
273
|
+
return Number.parseFloat(this.sliderElements[sliderIndex].value);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Get the slider's value in a mapped range of 0.0 ... 1.0.
|
|
278
|
+
*
|
|
279
|
+
* @param sliderIndex
|
|
280
|
+
* @returns
|
|
281
|
+
*/
|
|
282
|
+
private __getSliderPercentage(sliderIndex): number {
|
|
283
|
+
const sliderValue: number = this.__getSliderValue(sliderIndex, 0.0);
|
|
284
|
+
const percentage: number = (this.sliderMin + sliderValue) / (this.sliderMax - this.sliderMin);
|
|
285
|
+
return percentage;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Get the configured color value of the n-th rangel slider.
|
|
290
|
+
*
|
|
291
|
+
* @param {number} sliderIndex
|
|
292
|
+
* @param {string} fallback
|
|
293
|
+
* @returns
|
|
294
|
+
*/
|
|
295
|
+
private __getSliderColor(sliderIndex: number, fallback: string): string {
|
|
296
|
+
if (sliderIndex < 0 || sliderIndex >= this.sliderElements.length) {
|
|
297
|
+
return fallback;
|
|
298
|
+
}
|
|
299
|
+
const colorValue = this.sliderElements[sliderIndex].dataset["colorValue"];
|
|
300
|
+
return colorValue ? colorValue : fallback;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Adds custom styles (global STYLE tag).
|
|
305
|
+
*
|
|
306
|
+
* @private
|
|
307
|
+
*/
|
|
308
|
+
private __addCustomStyles() {
|
|
309
|
+
const headElements = document.querySelector("head");
|
|
310
|
+
if (headElements) {
|
|
311
|
+
const thumbWidth = "0.5em";
|
|
312
|
+
const thumbHeight = "1.333em";
|
|
313
|
+
const styleElement = document.createElement("style");
|
|
314
|
+
// Thanks to Ana Tudor
|
|
315
|
+
// https://css-tricks.com/multi-thumb-sliders-particular-two-thumb-case/
|
|
316
|
+
styleElement.innerHTML = `
|
|
317
|
+
input[type='range'] {
|
|
318
|
+
|
|
319
|
+
-webkit-appearance: none;
|
|
320
|
+
|
|
321
|
+
grid-column: 1;
|
|
322
|
+
grid-row: 2;
|
|
323
|
+
|
|
324
|
+
/* same as before */
|
|
325
|
+
background: none; /* get rid of white Chrome background */
|
|
326
|
+
color: #000;
|
|
327
|
+
font: inherit; /* fix too small font-size in both Chrome & Firefox */
|
|
328
|
+
margin: 0;
|
|
329
|
+
pointer-events: none; /* let clicks pass through */
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
input[type='range']::-webkit-slider-runnable-track {
|
|
333
|
+
-webkit-appearance: none;
|
|
334
|
+
|
|
335
|
+
background: none; /* get rid of Firefox track background */
|
|
336
|
+
height: 100%;
|
|
337
|
+
width: 100%;
|
|
338
|
+
|
|
339
|
+
pointer-events: none;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
input[type='range']::-webkit-slider-thumb {
|
|
343
|
+
-webkit-appearance: none;
|
|
344
|
+
background: currentcolor;
|
|
345
|
+
border: none; /* get rid of Firefox thumb border */
|
|
346
|
+
border-radius: 6px; /* get rid of Firefox corner rounding */
|
|
347
|
+
pointer-events: auto; /* catch clicks */
|
|
348
|
+
width: ${thumbWidth};
|
|
349
|
+
height: ${thumbHeight};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
input[type='range']:focus::-webkit-slider-thumb {
|
|
353
|
+
border: 2px solid white;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
input[type='range']::-moz-range-track {
|
|
357
|
+
-webkit-appearance: none;
|
|
358
|
+
background: none; /* get rid of Firefox track background */
|
|
359
|
+
height: 100%;
|
|
360
|
+
width: 100%;
|
|
361
|
+
pointer-events: none;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
input[type='range']::-moz-range-thumb {
|
|
365
|
+
/* -webkit-appearance: none; */
|
|
366
|
+
background: currentcolor;
|
|
367
|
+
border: none; /* get rid of Firefox thumb border */
|
|
368
|
+
border-radius: 6px; /* get rid of Firefox corner rounding */
|
|
369
|
+
pointer-events: auto; /* catch clicks */
|
|
370
|
+
width: ${thumbWidth};
|
|
371
|
+
height: ${thumbHeight};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
input[type='range']:focus::-moz-range-thumb {
|
|
375
|
+
border: 2px solid white;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
input[type='range'] {
|
|
379
|
+
/* same as before */
|
|
380
|
+
z-index: 1;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
input[type='range']:focus {
|
|
384
|
+
z-index: 2;
|
|
385
|
+
outline: dotted 1px orange;
|
|
386
|
+
color: darkorange;
|
|
387
|
+
}
|
|
388
|
+
`;
|
|
389
|
+
headElements.appendChild(styleElement);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
@@ -29,7 +29,7 @@ const applyGuiSize = (gui: GUI, guiDoubleSize: boolean, cssProps: Record<string,
|
|
|
29
29
|
|
|
30
30
|
const transform = cssProps && cssProps.hasOwnProperty("transform") ? cssProps["transform"] + " " : "";
|
|
31
31
|
|
|
32
|
-
console.log("transform", transform);
|
|
32
|
+
// console.log("transform", transform);
|
|
33
33
|
if (guiDoubleSize) {
|
|
34
34
|
gui.domElement.style["transform"] = transform + "scale(2.0)";
|
|
35
35
|
} else {
|
|
@@ -25,7 +25,10 @@
|
|
|
25
25
|
* @modified 2025-04-14 Added the `BezierPathInteractionHelper.drawHandleLines` method.
|
|
26
26
|
* @modified 2025-04-14 Fixing correct event types for touch events in `BezierPathInteractionHelper`.
|
|
27
27
|
* @modified 2025-04-14 BezierPathInteractionHelper: Changed default value of `HelperOptions.autoAdjustPaths` from `true` to `false`.
|
|
28
|
-
* @
|
|
28
|
+
* @modified 2025-05-05 Added optional params `draw` and `fill` to BezierPathInteractionHelper.drawHandleLines` method.
|
|
29
|
+
* @modified 2025-05-05 Class `BezierPathInteractionHelper` now implementing `IShapeInteractionHelper`.
|
|
30
|
+
* @modified 2025-05-07 Tweaking performance of `BezierPathInteractionHelper`: only triggering redraw now when mouse move within given detect range.
|
|
31
|
+
* @version 1.2.1
|
|
29
32
|
*
|
|
30
33
|
* @file BezierPathInteractionHelper
|
|
31
34
|
* @public
|
|
@@ -42,7 +45,7 @@ import { PlotBoilerplate } from "../../PlotBoilerplate";
|
|
|
42
45
|
import { VertListener } from "../../VertexListeners";
|
|
43
46
|
import { Vertex } from "../../Vertex";
|
|
44
47
|
import { XMouseEvent } from "../../MouseHandler";
|
|
45
|
-
import { DrawLib, XYCoords } from "../../interfaces";
|
|
48
|
+
import { DrawLib, IShapeInteractionHelper, XYCoords } from "../../interfaces";
|
|
46
49
|
import { AFTouchEvent } from "alloyfinger-typescript/src/cjs/alloy_finger";
|
|
47
50
|
|
|
48
51
|
/**
|
|
@@ -91,7 +94,7 @@ interface HelperOptions {
|
|
|
91
94
|
*
|
|
92
95
|
* @public
|
|
93
96
|
**/
|
|
94
|
-
export class BezierPathInteractionHelper {
|
|
97
|
+
export class BezierPathInteractionHelper implements IShapeInteractionHelper {
|
|
95
98
|
/**
|
|
96
99
|
* @member {PlotBoilerplate} pb
|
|
97
100
|
* @memberof BezierPathInteractionHelper
|
|
@@ -273,8 +276,12 @@ export class BezierPathInteractionHelper {
|
|
|
273
276
|
/**
|
|
274
277
|
* Draw grey handle lines.
|
|
275
278
|
*
|
|
279
|
+
* @param {DrawLib<any>} draw - (optional) The draw library to use. If not provided then `pb.draw` will be used.
|
|
280
|
+
* @param {DrawLib<any>} fill - (optional) The fill library to use. If not provided then `pb.fill` will be used.
|
|
276
281
|
*/
|
|
277
|
-
drawHandleLines() {
|
|
282
|
+
drawHandleLines(draw?: DrawLib<any>, fill?: DrawLib<any>) {
|
|
283
|
+
draw = draw || this.pb.draw;
|
|
284
|
+
fill = fill || this.pb.fill;
|
|
278
285
|
this.paths.forEach((path: BezierPath) => {
|
|
279
286
|
path.bezierCurves.forEach((curve: CubicBezierCurve) => {
|
|
280
287
|
this.pb.draw.line(curve.startPoint, curve.startControlPoint, "rgba(64,192,128,0.333)", 1.0, {
|
|
@@ -434,6 +441,9 @@ export class BezierPathInteractionHelper {
|
|
|
434
441
|
// | Touch and mouse events should call this fuction when the pointer was moved.
|
|
435
442
|
// +-------------------------------
|
|
436
443
|
private _handleMoveEvent(posX: number, posY: number): void {
|
|
444
|
+
const oldA = this.currentA.clone();
|
|
445
|
+
const oldB = this.currentB.clone();
|
|
446
|
+
const oldDistance = this.currentDistance;
|
|
437
447
|
const point: XYCoords = this.pb.transformMousePosition(posX, posY);
|
|
438
448
|
this.currentB.set(point);
|
|
439
449
|
this._updateMinDistance();
|
|
@@ -443,8 +453,14 @@ export class BezierPathInteractionHelper {
|
|
|
443
453
|
} else {
|
|
444
454
|
this.onPointerMoved(-1, null, null, 0.0);
|
|
445
455
|
}
|
|
446
|
-
//
|
|
447
|
-
|
|
456
|
+
// Only redraw when moving inside the detection distance
|
|
457
|
+
if (
|
|
458
|
+
(this.currentDistance <= this.maxDetectDistance ||
|
|
459
|
+
(this.currentDistance > this.maxDetectDistance && oldDistance <= this.maxDetectDistance)) &&
|
|
460
|
+
(!oldA.equals(this.currentA) || !oldB.equals(this.currentB))
|
|
461
|
+
) {
|
|
462
|
+
this.pb.redraw();
|
|
463
|
+
}
|
|
448
464
|
}
|
|
449
465
|
|
|
450
466
|
// +---------------------------------------------------------------------------------
|
|
@@ -462,23 +478,15 @@ export class BezierPathInteractionHelper {
|
|
|
462
478
|
private _installTouchListener(): AlloyFinger {
|
|
463
479
|
var _self: BezierPathInteractionHelper = this;
|
|
464
480
|
const afProps = {
|
|
465
|
-
// Todo: which event types does AlloyFinger use?
|
|
466
|
-
// touchStart: function (_event: TouchEvent) {
|
|
467
|
-
// _self.mouseIsOver = true;
|
|
468
|
-
// },
|
|
469
|
-
// /* TouchMoveEvent , AFTouchEvent<"touchStart"> */
|
|
470
481
|
touchStart: function (_event: AFTouchEvent<"touchStart">) {
|
|
471
482
|
_self.mouseIsOver = true;
|
|
472
483
|
},
|
|
473
484
|
touchMove: function (event: AFTouchEvent<"touchMove">) {
|
|
474
|
-
// TouchEvent) {
|
|
475
485
|
if (_self.pb.getDraggedElementCount() == 0 && event.touches.length > 0) {
|
|
476
|
-
// console.log('touchmove');
|
|
477
486
|
_self._handleMoveEvent(event.touches[0].clientX, event.touches[0].clientY);
|
|
478
487
|
}
|
|
479
488
|
},
|
|
480
489
|
touchEnd: function (_event: AFTouchEvent<"touchEnd">) {
|
|
481
|
-
// TouchEvent) {
|
|
482
490
|
_self.mouseIsOver = false;
|
|
483
491
|
_self._clearMoveEvent();
|
|
484
492
|
}
|
|
@@ -571,7 +579,9 @@ export class BezierPathInteractionHelper {
|
|
|
571
579
|
// | Update the min distance from point `line.b` to the curve. And redraw.
|
|
572
580
|
// +-------------------------------
|
|
573
581
|
private _updateMinDistance(): void {
|
|
574
|
-
if (this.paths.length == 0)
|
|
582
|
+
if (this.paths.length == 0) {
|
|
583
|
+
return;
|
|
584
|
+
}
|
|
575
585
|
let pathIndex: number = -1;
|
|
576
586
|
let minDist: number = Number.MAX_VALUE;
|
|
577
587
|
let closestPoint: Vertex | null = null;
|
|
@@ -10,17 +10,20 @@
|
|
|
10
10
|
* @modified 2024-02-26 Removed the constructor param `pb` (unused).
|
|
11
11
|
* @modified 2024-02-25 Added `circle` and `radiusPoint` attributes.
|
|
12
12
|
* @modified 2024-03-10 Fixed some issues in the `destroy` method; listeners were not properly removed.
|
|
13
|
+
* @modified 2025-05-05 Class `BezierPathInteractionHelper` now implementing `IShapeInteractionHelper`.
|
|
13
14
|
* @version 1.2.1
|
|
14
15
|
**/
|
|
15
16
|
|
|
16
17
|
import { Circle } from "../../Circle";
|
|
17
18
|
import { VertEvent, VertListener } from "../../VertexListeners";
|
|
18
19
|
import { Vertex } from "../../Vertex";
|
|
20
|
+
import { IShapeInteractionHelper } from "../../interfaces/core";
|
|
21
|
+
import { DrawLib } from "../../interfaces/DrawLib";
|
|
19
22
|
|
|
20
23
|
/**
|
|
21
24
|
* @classdesc A helper for handling circles with an additional radius-control-point.
|
|
22
25
|
*/
|
|
23
|
-
export class CircleHelper {
|
|
26
|
+
export class CircleHelper implements IShapeInteractionHelper {
|
|
24
27
|
circle: Circle;
|
|
25
28
|
radiusPoint: Vertex;
|
|
26
29
|
|
|
@@ -40,8 +43,18 @@ export class CircleHelper {
|
|
|
40
43
|
this.circle = circle;
|
|
41
44
|
this.radiusPoint = radiusPoint;
|
|
42
45
|
|
|
43
|
-
circle.center.listeners.addDragListener(
|
|
44
|
-
radiusPoint.listeners.addDragListener(this.radiusHandler = this._handleDragRadiusPoint());
|
|
46
|
+
circle.center.listeners.addDragListener((this.centerHandler = this._handleDragCenter()));
|
|
47
|
+
radiusPoint.listeners.addDragListener((this.radiusHandler = this._handleDragRadiusPoint()));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//--- BEGIN --- Implement ISHapeInteractionHelper ---
|
|
51
|
+
/**
|
|
52
|
+
* Let this shape helper draw it's handle lines. It's up to the helper what they look like.
|
|
53
|
+
* @param {DrawLib<any>} draw - The draw library to use.
|
|
54
|
+
* @param {DrawLib<any>} fill - The fill library to use.
|
|
55
|
+
*/
|
|
56
|
+
drawHandleLines(_draw: DrawLib<any>, _fill: DrawLib<any>): void {
|
|
57
|
+
// NOOP
|
|
45
58
|
}
|
|
46
59
|
|
|
47
60
|
/**
|
|
@@ -56,6 +69,7 @@ export class CircleHelper {
|
|
|
56
69
|
this.circle.center.listeners.removeDragListener(this.centerHandler);
|
|
57
70
|
this.radiusPoint.listeners.removeDragListener(this.radiusHandler);
|
|
58
71
|
}
|
|
72
|
+
//--- END --- Implement ISHapeInteractionHelper ---
|
|
59
73
|
|
|
60
74
|
/**
|
|
61
75
|
* Creates a new drag handler for the circle's center point.
|
|
@@ -22,12 +22,12 @@ import { CircleSector } from "../../CircleSector";
|
|
|
22
22
|
import { PlotBoilerplate } from "../../PlotBoilerplate";
|
|
23
23
|
import { VertEvent, VertListener } from "../../VertexListeners";
|
|
24
24
|
import { Vertex } from "../../Vertex";
|
|
25
|
-
import { DrawLib } from "../../interfaces";
|
|
25
|
+
import { DrawLib, IShapeInteractionHelper } from "../../interfaces";
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* @classdesc A helper for handling circles with an additional radius-control-point.
|
|
29
29
|
*/
|
|
30
|
-
export class CircleSectorHelper {
|
|
30
|
+
export class CircleSectorHelper implements IShapeInteractionHelper {
|
|
31
31
|
private circleSector: CircleSector;
|
|
32
32
|
private controlPointStart: Vertex;
|
|
33
33
|
private controlPointEnd: Vertex;
|
|
@@ -109,6 +109,7 @@ export class CircleSectorHelper {
|
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
//--- BEGIN --- Implement IShapeInteractionHelper ---
|
|
112
113
|
/**
|
|
113
114
|
* Draw grey handle lines.
|
|
114
115
|
*
|
|
@@ -139,4 +140,5 @@ export class CircleSectorHelper {
|
|
|
139
140
|
this.controlPointStart.listeners.removeDragListener(this.radiusStartListener);
|
|
140
141
|
this.controlPointEnd.listeners.removeDragListener(this.radiusEndListener);
|
|
141
142
|
}
|
|
143
|
+
//--- END --- Implement IShapeInteractionHelper ---
|
|
142
144
|
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Easily handle triangles with this triangle interaction helper: always keep your
|
|
3
|
+
* triangles equilateral.
|
|
4
|
+
*
|
|
5
|
+
* @author Ikaros Kappler
|
|
6
|
+
* @date 2025-05-05
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
**/
|
|
9
|
+
|
|
10
|
+
import { VertEvent, VertListener } from "../../VertexListeners";
|
|
11
|
+
import { Vertex } from "../../Vertex";
|
|
12
|
+
import { IShapeInteractionHelper } from "../../interfaces/core";
|
|
13
|
+
import { DrawLib } from "../../interfaces/DrawLib";
|
|
14
|
+
import { Triangle } from "../../Triangle";
|
|
15
|
+
import { Vector } from "../../Vector";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @classdesc A helper for handling circles with an additional radius-control-point.
|
|
19
|
+
*/
|
|
20
|
+
export class TriangleHelper implements IShapeInteractionHelper {
|
|
21
|
+
triangle: Triangle;
|
|
22
|
+
radiusPoint: Vertex;
|
|
23
|
+
|
|
24
|
+
private handlerA: VertListener;
|
|
25
|
+
private handlerB: VertListener;
|
|
26
|
+
private handlerC: VertListener;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The constructor.
|
|
30
|
+
*
|
|
31
|
+
* @constructor
|
|
32
|
+
* @name TriangleHelper
|
|
33
|
+
* @param {Triangle} triangle - The triangle to handle.
|
|
34
|
+
* @param {Vertex} radiusPoint - A point to define the radius (distance from center).
|
|
35
|
+
* @param {PlotBoilerplate} pb - The PlotBoilerplate which contains the circle and point.
|
|
36
|
+
**/
|
|
37
|
+
constructor(triangle: Triangle, setInitiallyEquilateral?: boolean) {
|
|
38
|
+
this.triangle = triangle;
|
|
39
|
+
|
|
40
|
+
triangle.a.listeners.addDragListener(
|
|
41
|
+
(this.handlerA = this._handleTrianglePoint(this.triangle.a, this.triangle.b, this.triangle.c))
|
|
42
|
+
);
|
|
43
|
+
triangle.b.listeners.addDragListener(
|
|
44
|
+
(this.handlerB = this._handleTrianglePoint(this.triangle.b, this.triangle.c, this.triangle.a))
|
|
45
|
+
);
|
|
46
|
+
triangle.c.listeners.addDragListener(
|
|
47
|
+
(this.handlerC = this._handleTrianglePoint(this.triangle.c, this.triangle.a, this.triangle.b))
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// Trigger to set equilateral
|
|
51
|
+
if (setInitiallyEquilateral) {
|
|
52
|
+
this.handlerC(null as any as VertEvent); // We know by construction that _here_ the param is optional!
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//--- BEGIN --- Implement ISHapeInteractionHelper ---
|
|
57
|
+
/**
|
|
58
|
+
* Let this shape helper draw it's handle lines. It's up to the helper what they look like.
|
|
59
|
+
* @param {DrawLib<any>} draw - The draw library to use.
|
|
60
|
+
* @param {DrawLib<any>} fill - The fill library to use.
|
|
61
|
+
*/
|
|
62
|
+
drawHandleLines(_draw: DrawLib<any>, _fill: DrawLib<any>): void {
|
|
63
|
+
// NOOP
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Destroy this circle helper.
|
|
68
|
+
* The listeners will be removed from the circle points.
|
|
69
|
+
*
|
|
70
|
+
* @method destroy
|
|
71
|
+
* @instance
|
|
72
|
+
* @memberof TriangleHelper
|
|
73
|
+
*/
|
|
74
|
+
destroy() {
|
|
75
|
+
this.triangle.a.listeners.removeDragListener(this.handlerA);
|
|
76
|
+
this.triangle.b.listeners.removeDragListener(this.handlerB);
|
|
77
|
+
this.triangle.c.listeners.removeDragListener(this.handlerC);
|
|
78
|
+
}
|
|
79
|
+
//--- END --- Implement ISHapeInteractionHelper ---
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Creates a new drag handler for the circle's radius control point.
|
|
83
|
+
*
|
|
84
|
+
* @private
|
|
85
|
+
* @method _handleDragCenter
|
|
86
|
+
* @instance
|
|
87
|
+
* @memberof TriangleHelper
|
|
88
|
+
* @returns A new event handler.
|
|
89
|
+
*/
|
|
90
|
+
private _handleTrianglePoint(vertex1: Vertex, vertex2: Vertex, vertex3: Vertex): VertListener {
|
|
91
|
+
const _self = this;
|
|
92
|
+
return (_evt: VertEvent) => {
|
|
93
|
+
// _self.circle.radius = _self.circle.center.distance(_self.radiusPoint);
|
|
94
|
+
// Calculate new side length: set equialateral
|
|
95
|
+
const vec = new Vector(vertex1, vertex2);
|
|
96
|
+
const mid = vec.vertAt(0.5);
|
|
97
|
+
const perp = vec.perp().add(mid).sub(vec.a);
|
|
98
|
+
perp.setLength((vec.length() * Math.sqrt(3)) / 2); // The height of a equilateral triangle
|
|
99
|
+
vertex3.set(perp.b);
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|