@editframe/elements 0.20.4-beta.0 → 0.23.6-beta.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/dist/DelayedLoadingState.js +0 -27
- package/dist/EF_FRAMEGEN.d.ts +5 -3
- package/dist/EF_FRAMEGEN.js +49 -11
- package/dist/_virtual/_@oxc-project_runtime@0.94.0/helpers/decorate.js +7 -0
- package/dist/attachContextRoot.d.ts +1 -0
- package/dist/attachContextRoot.js +9 -0
- package/dist/elements/ContextProxiesController.d.ts +1 -2
- package/dist/elements/EFAudio.js +5 -9
- package/dist/elements/EFCaptions.d.ts +1 -3
- package/dist/elements/EFCaptions.js +112 -129
- package/dist/elements/EFImage.js +6 -7
- package/dist/elements/EFMedia/AssetIdMediaEngine.js +2 -5
- package/dist/elements/EFMedia/AssetMediaEngine.js +36 -33
- package/dist/elements/EFMedia/BaseMediaEngine.js +57 -73
- package/dist/elements/EFMedia/BufferedSeekingInput.d.ts +1 -1
- package/dist/elements/EFMedia/BufferedSeekingInput.js +134 -78
- package/dist/elements/EFMedia/JitMediaEngine.js +9 -19
- package/dist/elements/EFMedia/audioTasks/makeAudioBufferTask.js +7 -13
- package/dist/elements/EFMedia/audioTasks/makeAudioFrequencyAnalysisTask.js +2 -3
- package/dist/elements/EFMedia/audioTasks/makeAudioInitSegmentFetchTask.js +1 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioInputTask.js +6 -5
- package/dist/elements/EFMedia/audioTasks/makeAudioSeekTask.js +1 -3
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentFetchTask.js +1 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioSegmentIdTask.js +1 -1
- package/dist/elements/EFMedia/audioTasks/makeAudioTimeDomainAnalysisTask.js +1 -1
- package/dist/elements/EFMedia/shared/AudioSpanUtils.js +9 -25
- package/dist/elements/EFMedia/shared/BufferUtils.js +2 -17
- package/dist/elements/EFMedia/shared/GlobalInputCache.js +0 -24
- package/dist/elements/EFMedia/shared/PrecisionUtils.js +0 -21
- package/dist/elements/EFMedia/shared/ThumbnailExtractor.js +0 -17
- package/dist/elements/EFMedia/tasks/makeMediaEngineTask.js +1 -10
- package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.d.ts +29 -0
- package/dist/elements/EFMedia/videoTasks/MainVideoInputCache.js +32 -0
- package/dist/elements/EFMedia/videoTasks/ScrubInputCache.js +1 -15
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoBufferTask.js +1 -7
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoInputTask.js +8 -5
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.js +12 -13
- package/dist/elements/EFMedia/videoTasks/makeScrubVideoSegmentIdTask.js +1 -1
- package/dist/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.js +134 -70
- package/dist/elements/EFMedia/videoTasks/makeVideoBufferTask.js +11 -18
- package/dist/elements/EFMedia.d.ts +19 -0
- package/dist/elements/EFMedia.js +44 -25
- package/dist/elements/EFSourceMixin.js +5 -7
- package/dist/elements/EFSurface.js +6 -9
- package/dist/elements/EFTemporal.browsertest.d.ts +11 -0
- package/dist/elements/EFTemporal.d.ts +10 -0
- package/dist/elements/EFTemporal.js +100 -41
- package/dist/elements/EFThumbnailStrip.js +23 -73
- package/dist/elements/EFTimegroup.browsertest.d.ts +3 -3
- package/dist/elements/EFTimegroup.d.ts +35 -14
- package/dist/elements/EFTimegroup.js +138 -181
- package/dist/elements/EFVideo.d.ts +16 -2
- package/dist/elements/EFVideo.js +156 -108
- package/dist/elements/EFWaveform.js +23 -40
- package/dist/elements/SampleBuffer.js +3 -7
- package/dist/elements/TargetController.js +5 -5
- package/dist/elements/durationConverter.js +4 -4
- package/dist/elements/renderTemporalAudio.d.ts +10 -0
- package/dist/elements/renderTemporalAudio.js +35 -0
- package/dist/elements/updateAnimations.js +19 -43
- package/dist/gui/ContextMixin.d.ts +5 -5
- package/dist/gui/ContextMixin.js +167 -162
- package/dist/gui/Controllable.browsertest.d.ts +0 -0
- package/dist/gui/Controllable.d.ts +15 -0
- package/dist/gui/Controllable.js +9 -0
- package/dist/gui/EFConfiguration.js +7 -7
- package/dist/gui/EFControls.browsertest.d.ts +11 -0
- package/dist/gui/EFControls.d.ts +18 -4
- package/dist/gui/EFControls.js +70 -28
- package/dist/gui/EFDial.browsertest.d.ts +0 -0
- package/dist/gui/EFDial.d.ts +18 -0
- package/dist/gui/EFDial.js +141 -0
- package/dist/gui/EFFilmstrip.browsertest.d.ts +11 -0
- package/dist/gui/EFFilmstrip.d.ts +12 -2
- package/dist/gui/EFFilmstrip.js +214 -129
- package/dist/gui/EFFitScale.js +5 -8
- package/dist/gui/EFFocusOverlay.js +4 -4
- package/dist/gui/EFPause.browsertest.d.ts +0 -0
- package/dist/gui/EFPause.d.ts +23 -0
- package/dist/gui/EFPause.js +59 -0
- package/dist/gui/EFPlay.browsertest.d.ts +0 -0
- package/dist/gui/EFPlay.d.ts +23 -0
- package/dist/gui/EFPlay.js +59 -0
- package/dist/gui/EFPreview.d.ts +4 -0
- package/dist/gui/EFPreview.js +18 -9
- package/dist/gui/EFResizableBox.browsertest.d.ts +0 -0
- package/dist/gui/EFResizableBox.d.ts +34 -0
- package/dist/gui/EFResizableBox.js +547 -0
- package/dist/gui/EFScrubber.d.ts +9 -3
- package/dist/gui/EFScrubber.js +13 -13
- package/dist/gui/EFTimeDisplay.d.ts +7 -1
- package/dist/gui/EFTimeDisplay.js +8 -8
- package/dist/gui/EFToggleLoop.d.ts +9 -3
- package/dist/gui/EFToggleLoop.js +7 -5
- package/dist/gui/EFTogglePlay.d.ts +12 -4
- package/dist/gui/EFTogglePlay.js +26 -21
- package/dist/gui/EFWorkbench.js +5 -5
- package/dist/gui/PlaybackController.d.ts +67 -0
- package/dist/gui/PlaybackController.js +310 -0
- package/dist/gui/TWMixin.js +1 -1
- package/dist/gui/TWMixin2.js +1 -1
- package/dist/gui/TargetOrContextMixin.d.ts +10 -0
- package/dist/gui/TargetOrContextMixin.js +98 -0
- package/dist/gui/efContext.d.ts +2 -2
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -1
- package/dist/otel/BridgeSpanExporter.d.ts +13 -0
- package/dist/otel/BridgeSpanExporter.js +87 -0
- package/dist/otel/setupBrowserTracing.d.ts +12 -0
- package/dist/otel/setupBrowserTracing.js +32 -0
- package/dist/otel/tracingHelpers.d.ts +34 -0
- package/dist/otel/tracingHelpers.js +112 -0
- package/dist/style.css +1 -1
- package/dist/transcoding/cache/RequestDeduplicator.js +0 -21
- package/dist/transcoding/cache/URLTokenDeduplicator.js +1 -21
- package/dist/transcoding/utils/UrlGenerator.js +2 -19
- package/dist/utils/LRUCache.js +6 -53
- package/package.json +13 -5
- package/src/elements/ContextProxiesController.ts +10 -10
- package/src/elements/EFAudio.ts +1 -0
- package/src/elements/EFCaptions.browsertest.ts +128 -56
- package/src/elements/EFCaptions.ts +60 -34
- package/src/elements/EFImage.browsertest.ts +1 -2
- package/src/elements/EFMedia/AssetMediaEngine.ts +65 -37
- package/src/elements/EFMedia/BaseMediaEngine.ts +110 -52
- package/src/elements/EFMedia/BufferedSeekingInput.ts +218 -101
- package/src/elements/EFMedia/JitMediaEngine.browsertest.ts +3 -0
- package/src/elements/EFMedia/audioTasks/makeAudioInputTask.ts +7 -3
- package/src/elements/EFMedia/audioTasks/makeAudioSeekTask.chunkboundary.regression.browsertest.ts +1 -1
- package/src/elements/EFMedia/videoTasks/MainVideoInputCache.ts +76 -0
- package/src/elements/EFMedia/videoTasks/makeScrubVideoInputTask.ts +16 -10
- package/src/elements/EFMedia/videoTasks/makeScrubVideoSeekTask.ts +7 -1
- package/src/elements/EFMedia/videoTasks/makeUnifiedVideoSeekTask.ts +222 -116
- package/src/elements/EFMedia.browsertest.ts +8 -15
- package/src/elements/EFMedia.ts +54 -8
- package/src/elements/EFSurface.browsertest.ts +2 -6
- package/src/elements/EFSurface.ts +1 -0
- package/src/elements/EFTemporal.browsertest.ts +58 -1
- package/src/elements/EFTemporal.ts +140 -4
- package/src/elements/EFThumbnailStrip.browsertest.ts +2 -8
- package/src/elements/EFThumbnailStrip.ts +1 -0
- package/src/elements/EFTimegroup.browsertest.ts +16 -15
- package/src/elements/EFTimegroup.ts +281 -275
- package/src/elements/EFVideo.browsertest.ts +162 -74
- package/src/elements/EFVideo.ts +229 -101
- package/src/elements/FetchContext.browsertest.ts +7 -2
- package/src/elements/TargetController.browsertest.ts +1 -0
- package/src/elements/TargetController.ts +1 -0
- package/src/elements/renderTemporalAudio.ts +108 -0
- package/src/elements/updateAnimations.browsertest.ts +181 -6
- package/src/elements/updateAnimations.ts +6 -6
- package/src/gui/ContextMixin.browsertest.ts +274 -27
- package/src/gui/ContextMixin.ts +230 -175
- package/src/gui/Controllable.browsertest.ts +258 -0
- package/src/gui/Controllable.ts +41 -0
- package/src/gui/EFControls.browsertest.ts +294 -80
- package/src/gui/EFControls.ts +139 -28
- package/src/gui/EFDial.browsertest.ts +84 -0
- package/src/gui/EFDial.ts +172 -0
- package/src/gui/EFFilmstrip.browsertest.ts +712 -0
- package/src/gui/EFFilmstrip.ts +213 -23
- package/src/gui/EFPause.browsertest.ts +202 -0
- package/src/gui/EFPause.ts +73 -0
- package/src/gui/EFPlay.browsertest.ts +202 -0
- package/src/gui/EFPlay.ts +73 -0
- package/src/gui/EFPreview.ts +20 -5
- package/src/gui/EFResizableBox.browsertest.ts +79 -0
- package/src/gui/EFResizableBox.ts +898 -0
- package/src/gui/EFScrubber.ts +7 -5
- package/src/gui/EFTimeDisplay.browsertest.ts +19 -19
- package/src/gui/EFTimeDisplay.ts +3 -1
- package/src/gui/EFToggleLoop.ts +6 -5
- package/src/gui/EFTogglePlay.ts +30 -23
- package/src/gui/PlaybackController.ts +522 -0
- package/src/gui/TWMixin.css +3 -0
- package/src/gui/TargetOrContextMixin.ts +185 -0
- package/src/gui/efContext.ts +2 -2
- package/src/otel/BridgeSpanExporter.ts +150 -0
- package/src/otel/setupBrowserTracing.ts +73 -0
- package/src/otel/tracingHelpers.ts +251 -0
- package/test/cache-integration-verification.browsertest.ts +1 -1
- package/types.json +1 -1
- package/dist/elements/ContextProxiesController.js +0 -69
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { html, render } from "lit";
|
|
2
|
+
import { afterEach, describe, expect, test } from "vitest";
|
|
3
|
+
import type { EFDial } from "./EFDial";
|
|
4
|
+
import "./EFDial";
|
|
5
|
+
|
|
6
|
+
describe("EFDial", () => {
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
document.body.innerHTML = "";
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("should render with default value", async () => {
|
|
12
|
+
const container = document.createElement("div");
|
|
13
|
+
document.body.appendChild(container);
|
|
14
|
+
render(html`<ef-dial></ef-dial>`, container);
|
|
15
|
+
const el = container.querySelector<EFDial>("ef-dial")!;
|
|
16
|
+
await el.updateComplete;
|
|
17
|
+
|
|
18
|
+
const centerText = el.shadowRoot!.querySelector(
|
|
19
|
+
".center-text",
|
|
20
|
+
) as HTMLDivElement;
|
|
21
|
+
expect(centerText.textContent).to.equal("0°");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("should render with provided value", async () => {
|
|
25
|
+
const container = document.createElement("div");
|
|
26
|
+
document.body.appendChild(container);
|
|
27
|
+
render(html`<ef-dial .value=${45}></ef-dial>`, container);
|
|
28
|
+
const el = container.querySelector<EFDial>("ef-dial")!;
|
|
29
|
+
await el.updateComplete;
|
|
30
|
+
|
|
31
|
+
const centerText = el.shadowRoot!.querySelector(
|
|
32
|
+
".center-text",
|
|
33
|
+
) as HTMLDivElement;
|
|
34
|
+
expect(centerText.textContent).to.equal("45°");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("should update value on drag and emit 'change' event", async () => {
|
|
38
|
+
const container = document.createElement("div");
|
|
39
|
+
container.style.width = "200px";
|
|
40
|
+
container.style.height = "200px";
|
|
41
|
+
document.body.appendChild(container);
|
|
42
|
+
render(html`<ef-dial></ef-dial>`, container);
|
|
43
|
+
const el = container.querySelector<EFDial>("ef-dial")!;
|
|
44
|
+
await el.updateComplete;
|
|
45
|
+
|
|
46
|
+
let changedValue: number | undefined;
|
|
47
|
+
el.addEventListener("change", (e) => {
|
|
48
|
+
changedValue = (e as CustomEvent).detail.value;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const dial = el.shadowRoot!.querySelector(
|
|
52
|
+
".dial-container",
|
|
53
|
+
) as HTMLDivElement;
|
|
54
|
+
const pointerId = 1;
|
|
55
|
+
const downEvent = new PointerEvent("pointerdown", {
|
|
56
|
+
clientX: 100,
|
|
57
|
+
clientY: 20,
|
|
58
|
+
bubbles: true,
|
|
59
|
+
composed: true,
|
|
60
|
+
pointerId,
|
|
61
|
+
});
|
|
62
|
+
dial.dispatchEvent(downEvent);
|
|
63
|
+
|
|
64
|
+
const moveEvent = new PointerEvent("pointermove", {
|
|
65
|
+
clientX: 180,
|
|
66
|
+
clientY: 100,
|
|
67
|
+
bubbles: true,
|
|
68
|
+
composed: true,
|
|
69
|
+
pointerId,
|
|
70
|
+
});
|
|
71
|
+
dial.dispatchEvent(moveEvent);
|
|
72
|
+
await el.updateComplete;
|
|
73
|
+
|
|
74
|
+
expect(el.value).to.be.closeTo(90, 0.1); // Expect a value around 90 degrees
|
|
75
|
+
expect(changedValue).to.be.closeTo(el.value, 0.1);
|
|
76
|
+
|
|
77
|
+
// Test normalization to 0-360
|
|
78
|
+
el.value = -10; // Set a negative value
|
|
79
|
+
expect(el.value).to.be.closeTo(350, 0.1); // Should normalize to 350
|
|
80
|
+
|
|
81
|
+
el.value = 370; // Set a value > 360
|
|
82
|
+
expect(el.value).to.be.closeTo(10, 0.1); // Should normalize to 10
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { css, html, LitElement } from "lit";
|
|
2
|
+
import { customElement, property, state } from "lit/decorators.js";
|
|
3
|
+
import { styleMap } from "lit/directives/style-map.js";
|
|
4
|
+
|
|
5
|
+
export interface DialChangeDetail {
|
|
6
|
+
value: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@customElement("ef-dial")
|
|
10
|
+
export class EFDial extends LitElement {
|
|
11
|
+
@property({ type: Number })
|
|
12
|
+
set value(newValue: number) {
|
|
13
|
+
// Normalize to 0-360 range
|
|
14
|
+
newValue = newValue % 360;
|
|
15
|
+
if (newValue < 0) {
|
|
16
|
+
newValue += 360;
|
|
17
|
+
}
|
|
18
|
+
// Limit to 6 significant digits
|
|
19
|
+
newValue = Number.parseFloat(newValue.toPrecision(6));
|
|
20
|
+
|
|
21
|
+
const oldValue = this._value;
|
|
22
|
+
this._value = newValue;
|
|
23
|
+
this.requestUpdate("value", oldValue);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get value() {
|
|
27
|
+
return this._value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private _value = 0;
|
|
31
|
+
|
|
32
|
+
@state()
|
|
33
|
+
private isDragging = false;
|
|
34
|
+
|
|
35
|
+
private dragStartAngle = 0;
|
|
36
|
+
private dragStartValue = 0;
|
|
37
|
+
|
|
38
|
+
static styles = css`
|
|
39
|
+
:host {
|
|
40
|
+
display: inline-block;
|
|
41
|
+
width: 200px; /* Default size, can be overridden by CSS */
|
|
42
|
+
height: 200px; /* Default size, can be overridden by CSS */
|
|
43
|
+
}
|
|
44
|
+
.dial-container {
|
|
45
|
+
position: relative;
|
|
46
|
+
width: 100%;
|
|
47
|
+
height: 100%;
|
|
48
|
+
border-radius: 50%;
|
|
49
|
+
background-color: #f3f4f6;
|
|
50
|
+
border: 2px solid #d1d5db;
|
|
51
|
+
}
|
|
52
|
+
.handle {
|
|
53
|
+
position: absolute;
|
|
54
|
+
width: 16px;
|
|
55
|
+
height: 16px;
|
|
56
|
+
border-radius: 50%;
|
|
57
|
+
border: 2px solid #3b82f6;
|
|
58
|
+
background-color: white;
|
|
59
|
+
cursor: grab;
|
|
60
|
+
}
|
|
61
|
+
.handle.dragging {
|
|
62
|
+
background-color: #3b82f6;
|
|
63
|
+
cursor: grabbing;
|
|
64
|
+
}
|
|
65
|
+
.center-text {
|
|
66
|
+
position: absolute;
|
|
67
|
+
top: 50%;
|
|
68
|
+
left: 50%;
|
|
69
|
+
transform: translate(-50%, -50%);
|
|
70
|
+
background-color: white;
|
|
71
|
+
border: 1px solid #d1d5db;
|
|
72
|
+
padding: 2px 4px;
|
|
73
|
+
border-radius: 4px;
|
|
74
|
+
font-family: monospace;
|
|
75
|
+
font-size: 12px;
|
|
76
|
+
}
|
|
77
|
+
`;
|
|
78
|
+
|
|
79
|
+
private getAngleFromPoint(clientX: number, clientY: number, rect: DOMRect) {
|
|
80
|
+
const center = this.clientWidth / 2;
|
|
81
|
+
const x = clientX - rect.left - center;
|
|
82
|
+
const y = clientY - rect.top - center;
|
|
83
|
+
return Math.atan2(y, x);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private handlePointerDown(e: PointerEvent) {
|
|
87
|
+
e.preventDefault();
|
|
88
|
+
this.isDragging = true;
|
|
89
|
+
const rect = this.getBoundingClientRect();
|
|
90
|
+
this.dragStartAngle = this.getAngleFromPoint(e.clientX, e.clientY, rect);
|
|
91
|
+
this.dragStartValue = this.value;
|
|
92
|
+
this.setPointerCapture(e.pointerId);
|
|
93
|
+
this.addEventListener("pointermove", this.handlePointerMove);
|
|
94
|
+
this.addEventListener("pointerup", this.handlePointerUp);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private handlePointerMove(e: PointerEvent) {
|
|
98
|
+
if (!this.isDragging) return;
|
|
99
|
+
|
|
100
|
+
const rect = this.getBoundingClientRect();
|
|
101
|
+
const currentAngle = this.getAngleFromPoint(e.clientX, e.clientY, rect);
|
|
102
|
+
const angleDelta = currentAngle - this.dragStartAngle;
|
|
103
|
+
|
|
104
|
+
let newValue = this.dragStartValue + (angleDelta * 180) / Math.PI;
|
|
105
|
+
|
|
106
|
+
if (e.shiftKey) {
|
|
107
|
+
newValue = Math.round(newValue / 15) * 15;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Normalize to 0-360 range
|
|
111
|
+
newValue = newValue % 360;
|
|
112
|
+
if (newValue < 0) {
|
|
113
|
+
newValue += 360;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Limit to 6 significant digits
|
|
117
|
+
newValue = Number.parseFloat(newValue.toPrecision(6));
|
|
118
|
+
|
|
119
|
+
this.value = newValue;
|
|
120
|
+
this.dispatchEvent(
|
|
121
|
+
new CustomEvent<DialChangeDetail>("change", {
|
|
122
|
+
detail: { value: this.value },
|
|
123
|
+
}),
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
private handlePointerUp(e: PointerEvent) {
|
|
128
|
+
this.isDragging = false;
|
|
129
|
+
this.releasePointerCapture(e.pointerId);
|
|
130
|
+
this.removeEventListener("pointermove", this.handlePointerMove);
|
|
131
|
+
this.removeEventListener("pointerup", this.handlePointerUp);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
render() {
|
|
135
|
+
const center = this.clientWidth / 2;
|
|
136
|
+
const radius = center - 20;
|
|
137
|
+
const handleAngle = (this.value * Math.PI) / 180;
|
|
138
|
+
const handleX = center + Math.cos(handleAngle) * radius;
|
|
139
|
+
const handleY = center + Math.sin(handleAngle) * radius;
|
|
140
|
+
|
|
141
|
+
const handleStyles = {
|
|
142
|
+
left: `${handleX - 8}px`,
|
|
143
|
+
top: `${handleY - 8}px`,
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
return html`
|
|
147
|
+
<div class="dial-container" @pointerdown=${this.handlePointerDown}>
|
|
148
|
+
<svg class="absolute inset-0 w-full h-full">
|
|
149
|
+
<circle
|
|
150
|
+
cx=${center}
|
|
151
|
+
cy=${center}
|
|
152
|
+
r=${radius}
|
|
153
|
+
fill="none"
|
|
154
|
+
stroke="#94a3b8"
|
|
155
|
+
stroke-width="2"
|
|
156
|
+
stroke-dasharray="4 4"
|
|
157
|
+
/>
|
|
158
|
+
${[0, 90, 180, 270].map((deg) => {
|
|
159
|
+
const angle = (deg * Math.PI) / 180;
|
|
160
|
+
const x1 = center + Math.cos(angle) * (radius - 8);
|
|
161
|
+
const y1 = center + Math.sin(angle) * (radius - 8);
|
|
162
|
+
const x2 = center + Math.cos(angle) * (radius + 8);
|
|
163
|
+
const y2 = center + Math.sin(angle) * (radius + 8);
|
|
164
|
+
return html`<line x1=${x1} y1=${y1} x2=${x2} y2=${y2} stroke="#64748b" stroke-width="2" />`;
|
|
165
|
+
})}
|
|
166
|
+
</svg>
|
|
167
|
+
<div class="handle ${this.isDragging ? "dragging" : ""}" style=${styleMap(handleStyles)}></div>
|
|
168
|
+
<div class="center-text">${this.value.toFixed(0)}°</div>
|
|
169
|
+
</div>
|
|
170
|
+
`;
|
|
171
|
+
}
|
|
172
|
+
}
|