@oicl/openbridge-webcomponents 0.0.20260407101310 → 0.0.20260407112816
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/building-blocks/instrument-radial/instrument-radial.d.ts +3 -0
- package/dist/building-blocks/instrument-radial/instrument-radial.d.ts.map +1 -1
- package/dist/building-blocks/instrument-radial/instrument-radial.js +50 -22
- package/dist/building-blocks/instrument-radial/instrument-radial.js.map +1 -1
- package/dist/navigation-instruments/compass/arrow.d.ts +1 -1
- package/dist/navigation-instruments/compass/arrow.d.ts.map +1 -1
- package/dist/navigation-instruments/compass/arrow.js +3 -3
- package/dist/navigation-instruments/compass/arrow.js.map +1 -1
- package/dist/navigation-instruments/compass/compass.d.ts +12 -6
- package/dist/navigation-instruments/compass/compass.d.ts.map +1 -1
- package/dist/navigation-instruments/compass/compass.js +29 -24
- package/dist/navigation-instruments/compass/compass.js.map +1 -1
- package/dist/navigation-instruments/compass-flat/compass-flat.d.ts +37 -1
- package/dist/navigation-instruments/compass-flat/compass-flat.d.ts.map +1 -1
- package/dist/navigation-instruments/compass-flat/compass-flat.js +34 -3
- package/dist/navigation-instruments/compass-flat/compass-flat.js.map +1 -1
- package/dist/navigation-instruments/compass-sector/compass-sector.css.js +34 -0
- package/dist/navigation-instruments/compass-sector/compass-sector.css.js.map +1 -0
- package/dist/navigation-instruments/compass-sector/compass-sector.d.ts +101 -0
- package/dist/navigation-instruments/compass-sector/compass-sector.d.ts.map +1 -0
- package/dist/navigation-instruments/compass-sector/compass-sector.js +404 -0
- package/dist/navigation-instruments/compass-sector/compass-sector.js.map +1 -0
- package/dist/navigation-instruments/rate-of-turn/rate-of-turn.controller.d.ts +15 -2
- package/dist/navigation-instruments/rate-of-turn/rate-of-turn.controller.d.ts.map +1 -1
- package/dist/navigation-instruments/rate-of-turn/rate-of-turn.controller.js +50 -18
- package/dist/navigation-instruments/rate-of-turn/rate-of-turn.controller.js.map +1 -1
- package/dist/navigation-instruments/rate-of-turn/rate-of-turn.d.ts +40 -6
- package/dist/navigation-instruments/rate-of-turn/rate-of-turn.d.ts.map +1 -1
- package/dist/navigation-instruments/rate-of-turn/rate-of-turn.js +40 -47
- package/dist/navigation-instruments/rate-of-turn/rate-of-turn.js.map +1 -1
- package/dist/navigation-instruments/rate-of-turn/rot-renderer.d.ts +63 -0
- package/dist/navigation-instruments/rate-of-turn/rot-renderer.d.ts.map +1 -0
- package/dist/navigation-instruments/rate-of-turn/rot-renderer.js +211 -0
- package/dist/navigation-instruments/rate-of-turn/rot-renderer.js.map +1 -0
- package/dist/navigation-instruments/rot-sector/rot-sector.d.ts +10 -4
- package/dist/navigation-instruments/rot-sector/rot-sector.d.ts.map +1 -1
- package/dist/navigation-instruments/rot-sector/rot-sector.js +13 -3
- package/dist/navigation-instruments/rot-sector/rot-sector.js.map +1 -1
- package/dist/navigation-instruments/rudder/rudder.d.ts +4 -0
- package/dist/navigation-instruments/rudder/rudder.d.ts.map +1 -1
- package/dist/navigation-instruments/rudder/rudder.js +55 -19
- package/dist/navigation-instruments/rudder/rudder.js.map +1 -1
- package/dist/navigation-instruments/watch/advice.d.ts +3 -3
- package/dist/navigation-instruments/watch/advice.d.ts.map +1 -1
- package/dist/navigation-instruments/watch/advice.js +68 -16
- package/dist/navigation-instruments/watch/advice.js.map +1 -1
- package/dist/navigation-instruments/watch/tickmark.d.ts +2 -1
- package/dist/navigation-instruments/watch/tickmark.d.ts.map +1 -1
- package/dist/navigation-instruments/watch/tickmark.js +15 -13
- package/dist/navigation-instruments/watch/tickmark.js.map +1 -1
- package/dist/navigation-instruments/watch/watch.d.ts +29 -0
- package/dist/navigation-instruments/watch/watch.d.ts.map +1 -1
- package/dist/navigation-instruments/watch/watch.js +256 -44
- package/dist/navigation-instruments/watch/watch.js.map +1 -1
- package/dist/navigation-instruments/watch-flat/watch-flat.d.ts +29 -1
- package/dist/navigation-instruments/watch-flat/watch-flat.d.ts.map +1 -1
- package/dist/navigation-instruments/watch-flat/watch-flat.js +162 -17
- package/dist/navigation-instruments/watch-flat/watch-flat.js.map +1 -1
- package/dist/svghelpers/arc-frame.d.ts +42 -0
- package/dist/svghelpers/arc-frame.d.ts.map +1 -0
- package/dist/svghelpers/arc-frame.js +123 -0
- package/dist/svghelpers/arc-frame.js.map +1 -0
- package/package.json +1 -1
- package/dist/navigation-instruments/compass/rot.d.ts +0 -4
- package/dist/navigation-instruments/compass/rot.d.ts.map +0 -1
- package/dist/navigation-instruments/compass/rot.js +0 -11
- package/dist/navigation-instruments/compass/rot.js.map +0 -1
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
import { unsafeCSS, LitElement, nothing, svg, html } from "lit";
|
|
2
|
+
import { property } from "lit/decorators.js";
|
|
3
|
+
import componentStyle from "./compass-sector.css.js";
|
|
4
|
+
import { WatchCircleType, innerRingRadiusFor, OUTER_RING_RADIUS } from "../watch/watch.js";
|
|
5
|
+
import { TickmarkType, TickmarkStyle } from "../watch/tickmark.js";
|
|
6
|
+
import { arrow, ArrowStyle } from "../compass/arrow.js";
|
|
7
|
+
import { AdviceState } from "../watch/advice.js";
|
|
8
|
+
import { SetpointBundle } from "../../svghelpers/setpoint-bundle.js";
|
|
9
|
+
import { computeZoomToFitArcFrame } from "../../svghelpers/arc-frame.js";
|
|
10
|
+
import { customElement } from "../../decorator.js";
|
|
11
|
+
import { InstrumentState, Priority } from "../types.js";
|
|
12
|
+
import { RotPosition } from "../rate-of-turn/rot-renderer.js";
|
|
13
|
+
import { RotType } from "../rate-of-turn/rot-renderer.js";
|
|
14
|
+
var __defProp = Object.defineProperty;
|
|
15
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
16
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
17
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
18
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
19
|
+
if (decorator = decorators[i])
|
|
20
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
21
|
+
if (kind && result) __defProp(target, key, result);
|
|
22
|
+
return result;
|
|
23
|
+
};
|
|
24
|
+
var CompassSectorPriorityElement = /* @__PURE__ */ ((CompassSectorPriorityElement2) => {
|
|
25
|
+
CompassSectorPriorityElement2["hdg"] = "hdg";
|
|
26
|
+
CompassSectorPriorityElement2["cog"] = "cog";
|
|
27
|
+
CompassSectorPriorityElement2["rot"] = "rot";
|
|
28
|
+
return CompassSectorPriorityElement2;
|
|
29
|
+
})(CompassSectorPriorityElement || {});
|
|
30
|
+
const PADDING = 72;
|
|
31
|
+
const WATCH_TYPE = WatchCircleType.triple;
|
|
32
|
+
const INNER_RADIUS = innerRingRadiusFor(WATCH_TYPE);
|
|
33
|
+
const ARC_HALF_EXTENT = 60;
|
|
34
|
+
function tickDensityForFOV(fov) {
|
|
35
|
+
if (fov <= 30) {
|
|
36
|
+
return { mainInterval: 10, primaryInterval: 5, secondaryInterval: 1 };
|
|
37
|
+
} else if (fov <= 60) {
|
|
38
|
+
return { mainInterval: 10, primaryInterval: 5, secondaryInterval: void 0 };
|
|
39
|
+
} else if (fov <= 120) {
|
|
40
|
+
return { mainInterval: 30, primaryInterval: 10, secondaryInterval: 5 };
|
|
41
|
+
} else {
|
|
42
|
+
return { mainInterval: 90, primaryInterval: 30, secondaryInterval: 10 };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function normalizeAngle(a) {
|
|
46
|
+
return (a % 360 + 360) % 360;
|
|
47
|
+
}
|
|
48
|
+
let ObcCompassSector = class extends LitElement {
|
|
49
|
+
constructor() {
|
|
50
|
+
super(...arguments);
|
|
51
|
+
this.heading = 0;
|
|
52
|
+
this.courseOverGround = 0;
|
|
53
|
+
this.headingSetpoint = null;
|
|
54
|
+
this.atHeadingSetpoint = false;
|
|
55
|
+
this.headingSetpointAtZeroDeadband = 0.5;
|
|
56
|
+
this.headingSetpointOverride = false;
|
|
57
|
+
this.autoAtHeadingSetpoint = true;
|
|
58
|
+
this.autoAtHeadingSetpointDeadband = 2;
|
|
59
|
+
this.animateSetpoint = false;
|
|
60
|
+
this.touching = false;
|
|
61
|
+
this.headingAdvices = [];
|
|
62
|
+
this.minFOV = 30;
|
|
63
|
+
this.rotPosition = RotPosition.innerCircle;
|
|
64
|
+
this.rotationsPerMinute = 1;
|
|
65
|
+
this.rotMaxValue = 10;
|
|
66
|
+
this.state = InstrumentState.active;
|
|
67
|
+
this.priority = Priority.regular;
|
|
68
|
+
this.priorityElements = [
|
|
69
|
+
"hdg"
|
|
70
|
+
/* hdg */
|
|
71
|
+
];
|
|
72
|
+
this.tickmarksInside = false;
|
|
73
|
+
this.zoomToFitArc = false;
|
|
74
|
+
this._headingSp = new SetpointBundle({
|
|
75
|
+
angularWraparound: true,
|
|
76
|
+
onAnimationEnd: () => this.requestUpdate()
|
|
77
|
+
});
|
|
78
|
+
this._halfFOV = 30;
|
|
79
|
+
this._arcHalfExtent = ARC_HALF_EXTENT;
|
|
80
|
+
this._scale = 1;
|
|
81
|
+
this._radiusOffset = 0;
|
|
82
|
+
this._cachedViewBox = "";
|
|
83
|
+
this._cachedAreas = [];
|
|
84
|
+
this._cachedTickmarks = [];
|
|
85
|
+
this._cachedAdvices = [];
|
|
86
|
+
}
|
|
87
|
+
willUpdate(changed) {
|
|
88
|
+
super.willUpdate(changed);
|
|
89
|
+
this._headingSp.sync({
|
|
90
|
+
setpoint: this.headingSetpoint ?? void 0,
|
|
91
|
+
newSetpoint: this.newHeadingSetpoint,
|
|
92
|
+
atSetpoint: this.atHeadingSetpoint,
|
|
93
|
+
touching: this.touching,
|
|
94
|
+
autoAtSetpoint: this.autoAtHeadingSetpoint,
|
|
95
|
+
autoAtSetpointDeadband: this.autoAtHeadingSetpointDeadband,
|
|
96
|
+
setpointAtZeroDeadband: this.headingSetpointAtZeroDeadband,
|
|
97
|
+
setpointOverride: this.headingSetpointOverride,
|
|
98
|
+
animateSetpoint: this.animateSetpoint
|
|
99
|
+
});
|
|
100
|
+
const arcInputsChanged = changed.has("heading") || changed.has("courseOverGround") || changed.has("minFOV") || changed.has("zoomToFitArc");
|
|
101
|
+
if (arcInputsChanged) {
|
|
102
|
+
let diff = this.courseOverGround - this.heading;
|
|
103
|
+
if (diff > 180) diff -= 360;
|
|
104
|
+
else if (diff < -180) diff += 360;
|
|
105
|
+
const minFov = Math.max(1, this.minFOV);
|
|
106
|
+
const MARGIN = 15;
|
|
107
|
+
if (this.zoomToFitArc) {
|
|
108
|
+
const needed = Math.max(minFov, Math.abs(diff) + MARGIN);
|
|
109
|
+
if (needed <= ARC_HALF_EXTENT) {
|
|
110
|
+
this._halfFOV = needed;
|
|
111
|
+
this._arcHalfExtent = needed;
|
|
112
|
+
this._scale = 1;
|
|
113
|
+
} else {
|
|
114
|
+
this._halfFOV = needed;
|
|
115
|
+
this._arcHalfExtent = ARC_HALF_EXTENT;
|
|
116
|
+
this._scale = ARC_HALF_EXTENT / needed;
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
119
|
+
this._halfFOV = Math.max(minFov, Math.abs(diff));
|
|
120
|
+
this._arcHalfExtent = ARC_HALF_EXTENT;
|
|
121
|
+
this._scale = ARC_HALF_EXTENT / this._halfFOV;
|
|
122
|
+
}
|
|
123
|
+
this._cachedAreas = [
|
|
124
|
+
{
|
|
125
|
+
startAngle: this.heading - this._arcHalfExtent,
|
|
126
|
+
endAngle: this.heading + this._arcHalfExtent,
|
|
127
|
+
roundInsideCut: true,
|
|
128
|
+
roundOutsideCut: true
|
|
129
|
+
}
|
|
130
|
+
];
|
|
131
|
+
this._computeViewBox();
|
|
132
|
+
this._cachedTickmarks = this._buildTickmarks();
|
|
133
|
+
}
|
|
134
|
+
if (arcInputsChanged || changed.has("headingAdvices")) {
|
|
135
|
+
this._cachedAdvices = this._buildAdvices();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
disconnectedCallback() {
|
|
139
|
+
super.disconnectedCallback();
|
|
140
|
+
this._headingSp.dispose();
|
|
141
|
+
}
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Angle mapping — maps compass degrees to arc positions
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
_mapAngle(compassDeg) {
|
|
146
|
+
let diff = compassDeg - this.heading;
|
|
147
|
+
if (diff > 180) diff -= 360;
|
|
148
|
+
else if (diff < -180) diff += 360;
|
|
149
|
+
return this.heading + diff * this._scale;
|
|
150
|
+
}
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
// Areas — fixed 120° arc centered on heading (built in willUpdate)
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
// Tickmarks — compass-degree labels at mapped arc positions
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
_buildTickmarks() {
|
|
158
|
+
const fov = this._halfFOV * 2;
|
|
159
|
+
const { mainInterval, primaryInterval, secondaryInterval } = tickDensityForFOV(fov);
|
|
160
|
+
const halfFov = this._halfFOV;
|
|
161
|
+
const compassStart = this.heading - halfFov;
|
|
162
|
+
const compassEnd = this.heading + halfFov;
|
|
163
|
+
const tickmarks = [];
|
|
164
|
+
const added = /* @__PURE__ */ new Set();
|
|
165
|
+
const addTick = (arcAngle, type, text) => {
|
|
166
|
+
const key = Math.round(arcAngle * 1e3);
|
|
167
|
+
if (added.has(key)) return;
|
|
168
|
+
added.add(key);
|
|
169
|
+
tickmarks.push({ angle: arcAngle, type, text });
|
|
170
|
+
};
|
|
171
|
+
const step = secondaryInterval ?? primaryInterval;
|
|
172
|
+
const firstTick = Math.ceil(compassStart / step) * step;
|
|
173
|
+
for (let compassDeg = firstTick; compassDeg <= compassEnd; compassDeg += step) {
|
|
174
|
+
const norm = normalizeAngle(compassDeg);
|
|
175
|
+
const arcAngle = this._mapAngle(compassDeg);
|
|
176
|
+
const isMain = norm % mainInterval === 0;
|
|
177
|
+
const isPrimary = norm % primaryInterval === 0;
|
|
178
|
+
if (isMain) {
|
|
179
|
+
addTick(arcAngle, TickmarkType.main, Math.round(norm).toString());
|
|
180
|
+
} else if (isPrimary) {
|
|
181
|
+
addTick(arcAngle, TickmarkType.primary);
|
|
182
|
+
} else {
|
|
183
|
+
addTick(arcAngle, TickmarkType.secondary);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return tickmarks;
|
|
187
|
+
}
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
// ViewBox
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
_computeViewBox() {
|
|
192
|
+
if (this.zoomToFitArc) {
|
|
193
|
+
const targetSize = (176 + PADDING) * 2;
|
|
194
|
+
const frame = computeZoomToFitArcFrame({
|
|
195
|
+
areas: this._cachedAreas,
|
|
196
|
+
outerRadius: OUTER_RING_RADIUS,
|
|
197
|
+
innerRadius: INNER_RADIUS,
|
|
198
|
+
extension: PADDING,
|
|
199
|
+
targetSize
|
|
200
|
+
});
|
|
201
|
+
this._radiusOffset = frame.radiusOffset;
|
|
202
|
+
this._cachedViewBox = frame.viewBox;
|
|
203
|
+
this._cachedArcFrame = frame;
|
|
204
|
+
} else {
|
|
205
|
+
this._radiusOffset = 0;
|
|
206
|
+
const width = (176 + PADDING) * 2;
|
|
207
|
+
this._cachedViewBox = `-${width / 2} -${width / 2} ${width} ${width}`;
|
|
208
|
+
this._cachedArcFrame = void 0;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// ---------------------------------------------------------------------------
|
|
212
|
+
// North arrow — rendered in overlay at mapped 0° position
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
_renderNorthArrow(rOff) {
|
|
215
|
+
let northOffset = -this.heading;
|
|
216
|
+
if (northOffset > 180) northOffset -= 360;
|
|
217
|
+
else if (northOffset < -180) northOffset += 360;
|
|
218
|
+
if (Math.abs(northOffset) > this._halfFOV) return nothing;
|
|
219
|
+
const northArcAngle = this._mapAngle(0);
|
|
220
|
+
const radius = OUTER_RING_RADIUS + rOff;
|
|
221
|
+
return svg`
|
|
222
|
+
<g transform="rotate(${northArcAngle}) translate(0, ${-radius})">
|
|
223
|
+
<path fill-rule="evenodd" clip-rule="evenodd"
|
|
224
|
+
d="M-17.8457 24.984 0 0 17.8458 24.984C11.9868 24.3338 6.0324 24 0 24-6.0323 24-11.9867 24.3338-17.8457 24.984Z"
|
|
225
|
+
fill="var(--instrument-frame-tertiary-color)"/>
|
|
226
|
+
</g>
|
|
227
|
+
`;
|
|
228
|
+
}
|
|
229
|
+
// ---------------------------------------------------------------------------
|
|
230
|
+
// Priority & advice helpers
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
_angleInRange(value, min, max) {
|
|
233
|
+
const v = normalizeAngle(value);
|
|
234
|
+
const start = normalizeAngle(min);
|
|
235
|
+
const end = normalizeAngle(max);
|
|
236
|
+
return start <= end ? v >= start && v <= end : v >= start || v <= end;
|
|
237
|
+
}
|
|
238
|
+
_buildAdvices() {
|
|
239
|
+
return this.headingAdvices.map(({ minAngle, maxAngle, hinted, type }) => {
|
|
240
|
+
const state = this._angleInRange(this.heading, minAngle, maxAngle) ? AdviceState.triggered : hinted ? AdviceState.hinted : AdviceState.regular;
|
|
241
|
+
return {
|
|
242
|
+
minAngle: this._mapAngle(minAngle),
|
|
243
|
+
maxAngle: this._mapAngle(maxAngle),
|
|
244
|
+
type,
|
|
245
|
+
state
|
|
246
|
+
};
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
get _rotEndAngle() {
|
|
250
|
+
const maxVal = this.rotMaxValue || 1;
|
|
251
|
+
const barCompassDeg = this.rotationsPerMinute / maxVal * ARC_HALF_EXTENT;
|
|
252
|
+
return this._mapAngle(this.heading + barCompassDeg);
|
|
253
|
+
}
|
|
254
|
+
priorityFor(element) {
|
|
255
|
+
const selected = Array.isArray(this.priorityElements) ? this.priorityElements : [];
|
|
256
|
+
return selected.includes(element) ? this.priority : Priority.regular;
|
|
257
|
+
}
|
|
258
|
+
// ---------------------------------------------------------------------------
|
|
259
|
+
// Render
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
render() {
|
|
262
|
+
const rotation = -this.heading;
|
|
263
|
+
const viewBox = this._cachedViewBox;
|
|
264
|
+
const rOff = this._radiusOffset;
|
|
265
|
+
const mappedCOG = this._mapAngle(this.courseOverGround);
|
|
266
|
+
const mappedSetpoint = this.headingSetpoint != null ? this._mapAngle(this.headingSetpoint) : void 0;
|
|
267
|
+
const mappedNewSetpoint = this.newHeadingSetpoint != null ? this._mapAngle(this.newHeadingSetpoint) : void 0;
|
|
268
|
+
return html`
|
|
269
|
+
<div class="container">
|
|
270
|
+
<obc-watch
|
|
271
|
+
.touching=${this.touching}
|
|
272
|
+
.padding=${PADDING}
|
|
273
|
+
.advices=${this._cachedAdvices}
|
|
274
|
+
.tickmarks=${this._cachedTickmarks}
|
|
275
|
+
.tickmarkStyle=${TickmarkStyle.regular}
|
|
276
|
+
.tickmarksInside=${this.tickmarksInside}
|
|
277
|
+
.state=${this.state}
|
|
278
|
+
.watchCircleType=${WATCH_TYPE}
|
|
279
|
+
.northArrow=${false}
|
|
280
|
+
.areas=${this._cachedAreas}
|
|
281
|
+
.arcFrame=${this._cachedArcFrame}
|
|
282
|
+
.zoomToFitArc=${this.zoomToFitArc}
|
|
283
|
+
.tickFadeAngle=${this._arcHalfExtent * 0.2}
|
|
284
|
+
.rotation=${rotation}
|
|
285
|
+
.angleSetpoint=${mappedSetpoint}
|
|
286
|
+
.newAngleSetpoint=${mappedNewSetpoint}
|
|
287
|
+
.atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}
|
|
288
|
+
.angleSetpointAtZeroDeadband=${this.headingSetpointAtZeroDeadband}
|
|
289
|
+
.setpointOverride=${this.headingSetpointOverride}
|
|
290
|
+
.priority=${this.priority}
|
|
291
|
+
.animateSetpoint=${this.animateSetpoint}
|
|
292
|
+
.rotType=${this.rotType}
|
|
293
|
+
.rotPosition=${this.rotPosition}
|
|
294
|
+
.rotStartAngle=${this.heading}
|
|
295
|
+
.rotEndAngle=${this._rotEndAngle}
|
|
296
|
+
.rotPriority=${this.priorityFor(
|
|
297
|
+
"rot"
|
|
298
|
+
/* rot */
|
|
299
|
+
)}
|
|
300
|
+
.rotationsPerMinute=${this.rotationsPerMinute}
|
|
301
|
+
>
|
|
302
|
+
</obc-watch>
|
|
303
|
+
<svg viewBox="${viewBox}" transform="rotate(${rotation})">
|
|
304
|
+
${this._renderNorthArrow(rOff)}
|
|
305
|
+
${arrow(
|
|
306
|
+
ArrowStyle.HDG,
|
|
307
|
+
this.heading,
|
|
308
|
+
this.priorityFor(
|
|
309
|
+
"hdg"
|
|
310
|
+
/* hdg */
|
|
311
|
+
),
|
|
312
|
+
rOff
|
|
313
|
+
)}
|
|
314
|
+
${arrow(
|
|
315
|
+
ArrowStyle.COG,
|
|
316
|
+
mappedCOG,
|
|
317
|
+
this.priorityFor(
|
|
318
|
+
"cog"
|
|
319
|
+
/* cog */
|
|
320
|
+
),
|
|
321
|
+
rOff
|
|
322
|
+
)}
|
|
323
|
+
</svg>
|
|
324
|
+
</div>
|
|
325
|
+
`;
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
ObcCompassSector.styles = unsafeCSS(componentStyle);
|
|
329
|
+
__decorateClass([
|
|
330
|
+
property({ type: Number })
|
|
331
|
+
], ObcCompassSector.prototype, "heading", 2);
|
|
332
|
+
__decorateClass([
|
|
333
|
+
property({ type: Number })
|
|
334
|
+
], ObcCompassSector.prototype, "courseOverGround", 2);
|
|
335
|
+
__decorateClass([
|
|
336
|
+
property({ type: Number })
|
|
337
|
+
], ObcCompassSector.prototype, "headingSetpoint", 2);
|
|
338
|
+
__decorateClass([
|
|
339
|
+
property({ type: Number })
|
|
340
|
+
], ObcCompassSector.prototype, "newHeadingSetpoint", 2);
|
|
341
|
+
__decorateClass([
|
|
342
|
+
property({ type: Boolean })
|
|
343
|
+
], ObcCompassSector.prototype, "atHeadingSetpoint", 2);
|
|
344
|
+
__decorateClass([
|
|
345
|
+
property({ type: Number })
|
|
346
|
+
], ObcCompassSector.prototype, "headingSetpointAtZeroDeadband", 2);
|
|
347
|
+
__decorateClass([
|
|
348
|
+
property({ type: Boolean })
|
|
349
|
+
], ObcCompassSector.prototype, "headingSetpointOverride", 2);
|
|
350
|
+
__decorateClass([
|
|
351
|
+
property({ type: Boolean, attribute: false })
|
|
352
|
+
], ObcCompassSector.prototype, "autoAtHeadingSetpoint", 2);
|
|
353
|
+
__decorateClass([
|
|
354
|
+
property({ type: Number })
|
|
355
|
+
], ObcCompassSector.prototype, "autoAtHeadingSetpointDeadband", 2);
|
|
356
|
+
__decorateClass([
|
|
357
|
+
property({ type: Boolean })
|
|
358
|
+
], ObcCompassSector.prototype, "animateSetpoint", 2);
|
|
359
|
+
__decorateClass([
|
|
360
|
+
property({ type: Boolean })
|
|
361
|
+
], ObcCompassSector.prototype, "touching", 2);
|
|
362
|
+
__decorateClass([
|
|
363
|
+
property({ type: Array, attribute: false })
|
|
364
|
+
], ObcCompassSector.prototype, "headingAdvices", 2);
|
|
365
|
+
__decorateClass([
|
|
366
|
+
property({ type: Number })
|
|
367
|
+
], ObcCompassSector.prototype, "minFOV", 2);
|
|
368
|
+
__decorateClass([
|
|
369
|
+
property({ type: String })
|
|
370
|
+
], ObcCompassSector.prototype, "rotType", 2);
|
|
371
|
+
__decorateClass([
|
|
372
|
+
property({ type: String })
|
|
373
|
+
], ObcCompassSector.prototype, "rotPosition", 2);
|
|
374
|
+
__decorateClass([
|
|
375
|
+
property({ type: Number })
|
|
376
|
+
], ObcCompassSector.prototype, "rotationsPerMinute", 2);
|
|
377
|
+
__decorateClass([
|
|
378
|
+
property({ type: Number })
|
|
379
|
+
], ObcCompassSector.prototype, "rotMaxValue", 2);
|
|
380
|
+
__decorateClass([
|
|
381
|
+
property({ type: String })
|
|
382
|
+
], ObcCompassSector.prototype, "state", 2);
|
|
383
|
+
__decorateClass([
|
|
384
|
+
property({ type: String })
|
|
385
|
+
], ObcCompassSector.prototype, "priority", 2);
|
|
386
|
+
__decorateClass([
|
|
387
|
+
property({ type: Array, attribute: false })
|
|
388
|
+
], ObcCompassSector.prototype, "priorityElements", 2);
|
|
389
|
+
__decorateClass([
|
|
390
|
+
property({ type: Boolean })
|
|
391
|
+
], ObcCompassSector.prototype, "tickmarksInside", 2);
|
|
392
|
+
__decorateClass([
|
|
393
|
+
property({ type: Boolean })
|
|
394
|
+
], ObcCompassSector.prototype, "zoomToFitArc", 2);
|
|
395
|
+
ObcCompassSector = __decorateClass([
|
|
396
|
+
customElement("obc-compass-sector")
|
|
397
|
+
], ObcCompassSector);
|
|
398
|
+
export {
|
|
399
|
+
CompassSectorPriorityElement,
|
|
400
|
+
ObcCompassSector,
|
|
401
|
+
RotPosition,
|
|
402
|
+
RotType
|
|
403
|
+
};
|
|
404
|
+
//# sourceMappingURL=compass-sector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compass-sector.js","sources":["../../../src/navigation-instruments/compass-sector/compass-sector.ts"],"sourcesContent":["import {LitElement, PropertyValues, html, svg, unsafeCSS, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport componentStyle from './compass-sector.css?inline';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType, TickmarkStyle} from '../watch/tickmark.js';\nimport {arrow, ArrowStyle} from '../compass/arrow.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {\n WatchCircleType,\n WatchArea,\n OUTER_RING_RADIUS,\n innerRingRadiusFor,\n RotType,\n RotPosition,\n} from '../watch/watch.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {\n computeZoomToFitArcFrame,\n type ZoomToFitArcFrame,\n} from '../../svghelpers/arc-frame.js';\nimport {customElement} from '../../decorator.js';\nimport {InstrumentState, Priority} from '../types.js';\nexport {RotType, RotPosition};\n\nexport enum CompassSectorPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n rot = 'rot',\n}\n\nconst PADDING = 72;\nconst WATCH_TYPE = WatchCircleType.triple;\nconst INNER_RADIUS = innerRingRadiusFor(WATCH_TYPE);\n/** Half of the fixed 120° arc on the watch face. */\nconst ARC_HALF_EXTENT = 60;\n\ninterface TickDensity {\n mainInterval: number;\n primaryInterval: number;\n secondaryInterval: number | undefined;\n}\n\nfunction tickDensityForFOV(fov: number): TickDensity {\n if (fov <= 30) {\n return {mainInterval: 10, primaryInterval: 5, secondaryInterval: 1};\n } else if (fov <= 60) {\n return {mainInterval: 10, primaryInterval: 5, secondaryInterval: undefined};\n } else if (fov <= 120) {\n return {mainInterval: 30, primaryInterval: 10, secondaryInterval: 5};\n } else {\n return {mainInterval: 90, primaryInterval: 30, secondaryInterval: 10};\n }\n}\n\nfunction normalizeAngle(a: number): number {\n return ((a % 360) + 360) % 360;\n}\n\n/**\n * `<obc-compass-sector>` — Curved compass strip that auto‑scales to keep HDG and COG visible.\n *\n * Renders a fixed 120° arc of a triple‑ring compass face. The visible\n * compass range (field of view) adjusts automatically so that both the\n * heading (HDG) and course‑over‑ground (COG) arrows are always in view.\n * This is the radial equivalent of `<obc-compass-flat>`: the arc shape\n * never changes — only the scale (compass‑degrees per arc‑degree) changes.\n *\n * ## Features\n *\n * - **Fixed 120° arc**: The watch face is always a 120° sector (±60° from\n * center), identical in shape to `<obc-rot-sector>`.\n * - **FOV auto‑scaling**: The field of view widens when the HDG–COG\n * angular difference grows, compressing more compass degrees into the\n * fixed arc. Tickmark density adjusts automatically.\n * - **HDG / COG arrows**: Solid (HDG) arrow is always at the arc center.\n * Hollow (COG) arrow is positioned proportionally within the arc.\n * - **North arrow**: A gray triangle in the outer scale band indicates\n * north when it falls within the visible FOV.\n * - **Heading setpoint**: Optional setpoint marker with auto at‑setpoint\n * detection and confirm animation, positioned at the mapped arc angle.\n * - **Advice zones**: Pass `headingAdvices` to render caution/alert arcs,\n * mapped into the scaled arc.\n * - **Rate of turn**: Animated ROT indicator (dots or bar) spanning from\n * HDG to the mapped COG position, clipped to the arc.\n * - **Zoom to fit**: When `zoomToFitArc` is `true`, the fixed 120° arc is\n * enlarged to fill the available space.\n *\n * ## Usage Guidelines\n *\n * - Set `heading` and `courseOverGround` to sensor values in degrees.\n * - Adjust `minFOV` to control the minimum zoom level (default 30°).\n * - Enable `zoomToFitArc` to enlarge the arc to fill the viewport.\n * - For a full‑circle compass, use `<obc-compass>` instead.\n *\n * @fires None\n */\n@customElement('obc-compass-sector')\nexport class ObcCompassSector extends LitElement {\n @property({type: Number}) heading = 0;\n @property({type: Number}) courseOverGround = 0;\n\n @property({type: Number}) headingSetpoint: number | null = null;\n @property({type: Number}) newHeadingSetpoint: number | undefined;\n @property({type: Boolean}) atHeadingSetpoint: boolean = false;\n @property({type: Number}) headingSetpointAtZeroDeadband: number = 0.5;\n @property({type: Boolean}) headingSetpointOverride: boolean = false;\n @property({type: Boolean, attribute: false}) autoAtHeadingSetpoint = true;\n @property({type: Number}) autoAtHeadingSetpointDeadband: number = 2;\n @property({type: Boolean}) animateSetpoint: boolean = false;\n @property({type: Boolean}) touching: boolean = false;\n @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];\n\n @property({type: Number}) minFOV: number = 30;\n\n @property({type: String}) rotType: RotType | undefined;\n @property({type: String}) rotPosition: RotPosition = RotPosition.innerCircle;\n @property({type: Number}) rotationsPerMinute: number = 1;\n @property({type: Number}) rotMaxValue: number = 10;\n\n @property({type: String}) state: InstrumentState = InstrumentState.active;\n @property({type: String}) priority: Priority = Priority.regular;\n @property({type: Array, attribute: false})\n priorityElements: CompassSectorPriorityElement[] = [\n CompassSectorPriorityElement.hdg,\n ];\n @property({type: Boolean}) tickmarksInside: boolean = false;\n @property({type: Boolean}) zoomToFitArc: boolean = false;\n\n private _headingSp = new SetpointBundle({\n angularWraparound: true,\n onAnimationEnd: () => this.requestUpdate(),\n });\n\n // Cached computed values — updated in willUpdate()\n private _halfFOV = 30;\n private _arcHalfExtent = ARC_HALF_EXTENT;\n private _scale = 1;\n private _radiusOffset = 0;\n private _cachedViewBox = '';\n private _cachedArcFrame: ZoomToFitArcFrame | undefined;\n private _cachedAreas: WatchArea[] = [];\n private _cachedTickmarks: Tickmark[] = [];\n private _cachedAdvices: AngleAdviceRaw[] = [];\n\n override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n this._headingSp.sync({\n setpoint: this.headingSetpoint ?? undefined,\n newSetpoint: this.newHeadingSetpoint,\n atSetpoint: this.atHeadingSetpoint,\n touching: this.touching,\n autoAtSetpoint: this.autoAtHeadingSetpoint,\n autoAtSetpointDeadband: this.autoAtHeadingSetpointDeadband,\n setpointAtZeroDeadband: this.headingSetpointAtZeroDeadband,\n setpointOverride: this.headingSetpointOverride,\n animateSetpoint: this.animateSetpoint,\n });\n\n const arcInputsChanged =\n changed.has('heading') ||\n changed.has('courseOverGround') ||\n changed.has('minFOV') ||\n changed.has('zoomToFitArc');\n\n if (arcInputsChanged) {\n let diff = this.courseOverGround - this.heading;\n if (diff > 180) diff -= 360;\n else if (diff < -180) diff += 360;\n const minFov = Math.max(1, this.minFOV);\n const MARGIN = 15;\n\n if (this.zoomToFitArc) {\n const needed = Math.max(minFov, Math.abs(diff) + MARGIN);\n if (needed <= ARC_HALF_EXTENT) {\n this._halfFOV = needed;\n this._arcHalfExtent = needed;\n this._scale = 1;\n } else {\n this._halfFOV = needed;\n this._arcHalfExtent = ARC_HALF_EXTENT;\n this._scale = ARC_HALF_EXTENT / needed;\n }\n } else {\n this._halfFOV = Math.max(minFov, Math.abs(diff));\n this._arcHalfExtent = ARC_HALF_EXTENT;\n this._scale = ARC_HALF_EXTENT / this._halfFOV;\n }\n\n this._cachedAreas = [\n {\n startAngle: this.heading - this._arcHalfExtent,\n endAngle: this.heading + this._arcHalfExtent,\n roundInsideCut: true,\n roundOutsideCut: true,\n },\n ];\n\n this._computeViewBox();\n this._cachedTickmarks = this._buildTickmarks();\n }\n\n if (arcInputsChanged || changed.has('headingAdvices')) {\n this._cachedAdvices = this._buildAdvices();\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._headingSp.dispose();\n }\n\n // ---------------------------------------------------------------------------\n // Angle mapping — maps compass degrees to arc positions\n // ---------------------------------------------------------------------------\n\n private _mapAngle(compassDeg: number): number {\n let diff = compassDeg - this.heading;\n if (diff > 180) diff -= 360;\n else if (diff < -180) diff += 360;\n return this.heading + diff * this._scale;\n }\n\n // ---------------------------------------------------------------------------\n // Areas — fixed 120° arc centered on heading (built in willUpdate)\n // ---------------------------------------------------------------------------\n\n // ---------------------------------------------------------------------------\n // Tickmarks — compass-degree labels at mapped arc positions\n // ---------------------------------------------------------------------------\n\n private _buildTickmarks(): Tickmark[] {\n const fov = this._halfFOV * 2;\n const {mainInterval, primaryInterval, secondaryInterval} =\n tickDensityForFOV(fov);\n const halfFov = this._halfFOV;\n const compassStart = this.heading - halfFov;\n const compassEnd = this.heading + halfFov;\n\n const tickmarks: Tickmark[] = [];\n const added = new Set<number>();\n\n const addTick = (\n arcAngle: number,\n type: TickmarkType,\n text?: string\n ): void => {\n const key = Math.round(arcAngle * 1000);\n if (added.has(key)) return;\n added.add(key);\n tickmarks.push({angle: arcAngle, type, text});\n };\n\n const step = secondaryInterval ?? primaryInterval;\n const firstTick = Math.ceil(compassStart / step) * step;\n\n for (\n let compassDeg = firstTick;\n compassDeg <= compassEnd;\n compassDeg += step\n ) {\n const norm = normalizeAngle(compassDeg);\n const arcAngle = this._mapAngle(compassDeg);\n const isMain = norm % mainInterval === 0;\n const isPrimary = norm % primaryInterval === 0;\n\n if (isMain) {\n addTick(arcAngle, TickmarkType.main, Math.round(norm).toString());\n } else if (isPrimary) {\n addTick(arcAngle, TickmarkType.primary);\n } else {\n addTick(arcAngle, TickmarkType.secondary);\n }\n }\n\n return tickmarks;\n }\n\n // ---------------------------------------------------------------------------\n // ViewBox\n // ---------------------------------------------------------------------------\n\n private _computeViewBox(): void {\n if (this.zoomToFitArc) {\n const targetSize = (176 + PADDING) * 2;\n const frame = computeZoomToFitArcFrame({\n areas: this._cachedAreas,\n outerRadius: OUTER_RING_RADIUS,\n innerRadius: INNER_RADIUS,\n extension: PADDING,\n targetSize,\n });\n this._radiusOffset = frame.radiusOffset;\n this._cachedViewBox = frame.viewBox;\n this._cachedArcFrame = frame;\n } else {\n this._radiusOffset = 0;\n const width = (176 + PADDING) * 2;\n this._cachedViewBox = `-${width / 2} -${width / 2} ${width} ${width}`;\n this._cachedArcFrame = undefined;\n }\n }\n\n // ---------------------------------------------------------------------------\n // North arrow — rendered in overlay at mapped 0° position\n // ---------------------------------------------------------------------------\n\n private _renderNorthArrow(rOff: number) {\n let northOffset = -this.heading;\n if (northOffset > 180) northOffset -= 360;\n else if (northOffset < -180) northOffset += 360;\n if (Math.abs(northOffset) > this._halfFOV) return nothing;\n\n const northArcAngle = this._mapAngle(0);\n const radius = OUTER_RING_RADIUS + rOff;\n return svg`\n <g transform=\"rotate(${northArcAngle}) translate(0, ${-radius})\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\"\n d=\"M-17.8457 24.984 0 0 17.8458 24.984C11.9868 24.3338 6.0324 24 0 24-6.0323 24-11.9867 24.3338-17.8457 24.984Z\"\n fill=\"var(--instrument-frame-tertiary-color)\"/>\n </g>\n `;\n }\n\n // ---------------------------------------------------------------------------\n // Priority & advice helpers\n // ---------------------------------------------------------------------------\n\n private _angleInRange(value: number, min: number, max: number): boolean {\n const v = normalizeAngle(value);\n const start = normalizeAngle(min);\n const end = normalizeAngle(max);\n return start <= end ? v >= start && v <= end : v >= start || v <= end;\n }\n\n private _buildAdvices(): AngleAdviceRaw[] {\n return this.headingAdvices.map(({minAngle, maxAngle, hinted, type}) => {\n const state = this._angleInRange(this.heading, minAngle, maxAngle)\n ? AdviceState.triggered\n : hinted\n ? AdviceState.hinted\n : AdviceState.regular;\n return {\n minAngle: this._mapAngle(minAngle),\n maxAngle: this._mapAngle(maxAngle),\n type,\n state,\n };\n });\n }\n\n private get _rotEndAngle(): number {\n const maxVal = this.rotMaxValue || 1;\n const barCompassDeg = (this.rotationsPerMinute / maxVal) * ARC_HALF_EXTENT;\n return this._mapAngle(this.heading + barCompassDeg);\n }\n\n private priorityFor(element: CompassSectorPriorityElement): Priority {\n const selected = Array.isArray(this.priorityElements)\n ? this.priorityElements\n : [];\n return selected.includes(element) ? this.priority : Priority.regular;\n }\n\n // ---------------------------------------------------------------------------\n // Render\n // ---------------------------------------------------------------------------\n\n override render() {\n const rotation = -this.heading;\n const viewBox = this._cachedViewBox;\n const rOff = this._radiusOffset;\n\n const mappedCOG = this._mapAngle(this.courseOverGround);\n const mappedSetpoint =\n this.headingSetpoint != null\n ? this._mapAngle(this.headingSetpoint)\n : undefined;\n const mappedNewSetpoint =\n this.newHeadingSetpoint != null\n ? this._mapAngle(this.newHeadingSetpoint)\n : undefined;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .padding=${PADDING}\n .advices=${this._cachedAdvices}\n .tickmarks=${this._cachedTickmarks}\n .tickmarkStyle=${TickmarkStyle.regular}\n .tickmarksInside=${this.tickmarksInside}\n .state=${this.state}\n .watchCircleType=${WATCH_TYPE}\n .northArrow=${false}\n .areas=${this._cachedAreas}\n .arcFrame=${this._cachedArcFrame}\n .zoomToFitArc=${this.zoomToFitArc}\n .tickFadeAngle=${this._arcHalfExtent * 0.2}\n .rotation=${rotation}\n .angleSetpoint=${mappedSetpoint}\n .newAngleSetpoint=${mappedNewSetpoint}\n .atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}\n .angleSetpointAtZeroDeadband=${this.headingSetpointAtZeroDeadband}\n .setpointOverride=${this.headingSetpointOverride}\n .priority=${this.priority}\n .animateSetpoint=${this.animateSetpoint}\n .rotType=${this.rotType}\n .rotPosition=${this.rotPosition}\n .rotStartAngle=${this.heading}\n .rotEndAngle=${this._rotEndAngle}\n .rotPriority=${this.priorityFor(CompassSectorPriorityElement.rot)}\n .rotationsPerMinute=${this.rotationsPerMinute}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\" transform=\"rotate(${rotation})\">\n ${this._renderNorthArrow(rOff)}\n ${arrow(\n ArrowStyle.HDG,\n this.heading,\n this.priorityFor(CompassSectorPriorityElement.hdg),\n rOff\n )}\n ${arrow(\n ArrowStyle.COG,\n mappedCOG,\n this.priorityFor(CompassSectorPriorityElement.cog),\n rOff\n )}\n </svg>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-compass-sector': ObcCompassSector;\n }\n}\n"],"names":["CompassSectorPriorityElement"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAwBO,IAAK,iDAAAA,kCAAL;AACLA,gCAAA,KAAA,IAAM;AACNA,gCAAA,KAAA,IAAM;AACNA,gCAAA,KAAA,IAAM;AAHI,SAAAA;AAAA,GAAA,gCAAA,CAAA,CAAA;AAMZ,MAAM,UAAU;AAChB,MAAM,aAAa,gBAAgB;AACnC,MAAM,eAAe,mBAAmB,UAAU;AAElD,MAAM,kBAAkB;AAQxB,SAAS,kBAAkB,KAA0B;AACnD,MAAI,OAAO,IAAI;AACb,WAAO,EAAC,cAAc,IAAI,iBAAiB,GAAG,mBAAmB,EAAA;AAAA,EACnE,WAAW,OAAO,IAAI;AACpB,WAAO,EAAC,cAAc,IAAI,iBAAiB,GAAG,mBAAmB,OAAA;AAAA,EACnE,WAAW,OAAO,KAAK;AACrB,WAAO,EAAC,cAAc,IAAI,iBAAiB,IAAI,mBAAmB,EAAA;AAAA,EACpE,OAAO;AACL,WAAO,EAAC,cAAc,IAAI,iBAAiB,IAAI,mBAAmB,GAAA;AAAA,EACpE;AACF;AAEA,SAAS,eAAe,GAAmB;AACzC,UAAS,IAAI,MAAO,OAAO;AAC7B;AAyCO,IAAM,mBAAN,cAA+B,WAAW;AAAA,EAA1C,cAAA;AAAA,UAAA,GAAA,SAAA;AACqB,SAAA,UAAU;AACV,SAAA,mBAAmB;AAEnB,SAAA,kBAAiC;AAEhC,SAAA,oBAA6B;AAC9B,SAAA,gCAAwC;AACvC,SAAA,0BAAmC;AACjB,SAAA,wBAAwB;AAC3C,SAAA,gCAAwC;AACvC,SAAA,kBAA2B;AAC3B,SAAA,WAAoB;AACJ,SAAA,iBAAgC,CAAA;AAEjD,SAAA,SAAiB;AAGjB,SAAA,cAA2B,YAAY;AACvC,SAAA,qBAA6B;AAC7B,SAAA,cAAsB;AAEtB,SAAA,QAAyB,gBAAgB;AACzC,SAAA,WAAqB,SAAS;AAExD,SAAA,mBAAmD;AAAA,MACjD;AAAA;AAAA,IAAA;AAEyB,SAAA,kBAA2B;AAC3B,SAAA,eAAwB;AAEnD,SAAQ,aAAa,IAAI,eAAe;AAAA,MACtC,mBAAmB;AAAA,MACnB,gBAAgB,MAAM,KAAK,cAAA;AAAA,IAAc,CAC1C;AAGD,SAAQ,WAAW;AACnB,SAAQ,iBAAiB;AACzB,SAAQ,SAAS;AACjB,SAAQ,gBAAgB;AACxB,SAAQ,iBAAiB;AAEzB,SAAQ,eAA4B,CAAA;AACpC,SAAQ,mBAA+B,CAAA;AACvC,SAAQ,iBAAmC,CAAA;AAAA,EAAC;AAAA,EAEnC,WAAW,SAA+B;AACjD,UAAM,WAAW,OAAO;AACxB,SAAK,WAAW,KAAK;AAAA,MACnB,UAAU,KAAK,mBAAmB;AAAA,MAClC,aAAa,KAAK;AAAA,MAClB,YAAY,KAAK;AAAA,MACjB,UAAU,KAAK;AAAA,MACf,gBAAgB,KAAK;AAAA,MACrB,wBAAwB,KAAK;AAAA,MAC7B,wBAAwB,KAAK;AAAA,MAC7B,kBAAkB,KAAK;AAAA,MACvB,iBAAiB,KAAK;AAAA,IAAA,CACvB;AAED,UAAM,mBACJ,QAAQ,IAAI,SAAS,KACrB,QAAQ,IAAI,kBAAkB,KAC9B,QAAQ,IAAI,QAAQ,KACpB,QAAQ,IAAI,cAAc;AAE5B,QAAI,kBAAkB;AACpB,UAAI,OAAO,KAAK,mBAAmB,KAAK;AACxC,UAAI,OAAO,IAAK,SAAQ;AAAA,eACf,OAAO,KAAM,SAAQ;AAC9B,YAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM;AACtC,YAAM,SAAS;AAEf,UAAI,KAAK,cAAc;AACrB,cAAM,SAAS,KAAK,IAAI,QAAQ,KAAK,IAAI,IAAI,IAAI,MAAM;AACvD,YAAI,UAAU,iBAAiB;AAC7B,eAAK,WAAW;AAChB,eAAK,iBAAiB;AACtB,eAAK,SAAS;AAAA,QAChB,OAAO;AACL,eAAK,WAAW;AAChB,eAAK,iBAAiB;AACtB,eAAK,SAAS,kBAAkB;AAAA,QAClC;AAAA,MACF,OAAO;AACL,aAAK,WAAW,KAAK,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC;AAC/C,aAAK,iBAAiB;AACtB,aAAK,SAAS,kBAAkB,KAAK;AAAA,MACvC;AAEA,WAAK,eAAe;AAAA,QAClB;AAAA,UACE,YAAY,KAAK,UAAU,KAAK;AAAA,UAChC,UAAU,KAAK,UAAU,KAAK;AAAA,UAC9B,gBAAgB;AAAA,UAChB,iBAAiB;AAAA,QAAA;AAAA,MACnB;AAGF,WAAK,gBAAA;AACL,WAAK,mBAAmB,KAAK,gBAAA;AAAA,IAC/B;AAEA,QAAI,oBAAoB,QAAQ,IAAI,gBAAgB,GAAG;AACrD,WAAK,iBAAiB,KAAK,cAAA;AAAA,IAC7B;AAAA,EACF;AAAA,EAES,uBAA6B;AACpC,UAAM,qBAAA;AACN,SAAK,WAAW,QAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAMQ,UAAU,YAA4B;AAC5C,QAAI,OAAO,aAAa,KAAK;AAC7B,QAAI,OAAO,IAAK,SAAQ;AAAA,aACf,OAAO,KAAM,SAAQ;AAC9B,WAAO,KAAK,UAAU,OAAO,KAAK;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUQ,kBAA8B;AACpC,UAAM,MAAM,KAAK,WAAW;AAC5B,UAAM,EAAC,cAAc,iBAAiB,kBAAA,IACpC,kBAAkB,GAAG;AACvB,UAAM,UAAU,KAAK;AACrB,UAAM,eAAe,KAAK,UAAU;AACpC,UAAM,aAAa,KAAK,UAAU;AAElC,UAAM,YAAwB,CAAA;AAC9B,UAAM,4BAAY,IAAA;AAElB,UAAM,UAAU,CACd,UACA,MACA,SACS;AACT,YAAM,MAAM,KAAK,MAAM,WAAW,GAAI;AACtC,UAAI,MAAM,IAAI,GAAG,EAAG;AACpB,YAAM,IAAI,GAAG;AACb,gBAAU,KAAK,EAAC,OAAO,UAAU,MAAM,MAAK;AAAA,IAC9C;AAEA,UAAM,OAAO,qBAAqB;AAClC,UAAM,YAAY,KAAK,KAAK,eAAe,IAAI,IAAI;AAEnD,aACM,aAAa,WACjB,cAAc,YACd,cAAc,MACd;AACA,YAAM,OAAO,eAAe,UAAU;AACtC,YAAM,WAAW,KAAK,UAAU,UAAU;AAC1C,YAAM,SAAS,OAAO,iBAAiB;AACvC,YAAM,YAAY,OAAO,oBAAoB;AAE7C,UAAI,QAAQ;AACV,gBAAQ,UAAU,aAAa,MAAM,KAAK,MAAM,IAAI,EAAE,UAAU;AAAA,MAClE,WAAW,WAAW;AACpB,gBAAQ,UAAU,aAAa,OAAO;AAAA,MACxC,OAAO;AACL,gBAAQ,UAAU,aAAa,SAAS;AAAA,MAC1C;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAwB;AAC9B,QAAI,KAAK,cAAc;AACrB,YAAM,cAAc,MAAM,WAAW;AACrC,YAAM,QAAQ,yBAAyB;AAAA,QACrC,OAAO,KAAK;AAAA,QACZ,aAAa;AAAA,QACb,aAAa;AAAA,QACb,WAAW;AAAA,QACX;AAAA,MAAA,CACD;AACD,WAAK,gBAAgB,MAAM;AAC3B,WAAK,iBAAiB,MAAM;AAC5B,WAAK,kBAAkB;AAAA,IACzB,OAAO;AACL,WAAK,gBAAgB;AACrB,YAAM,SAAS,MAAM,WAAW;AAChC,WAAK,iBAAiB,IAAI,QAAQ,CAAC,KAAK,QAAQ,CAAC,IAAI,KAAK,IAAI,KAAK;AACnE,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAkB,MAAc;AACtC,QAAI,cAAc,CAAC,KAAK;AACxB,QAAI,cAAc,IAAK,gBAAe;AAAA,aAC7B,cAAc,KAAM,gBAAe;AAC5C,QAAI,KAAK,IAAI,WAAW,IAAI,KAAK,SAAU,QAAO;AAElD,UAAM,gBAAgB,KAAK,UAAU,CAAC;AACtC,UAAM,SAAS,oBAAoB;AACnC,WAAO;AAAA,6BACkB,aAAa,kBAAkB,CAAC,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMjE;AAAA;AAAA;AAAA;AAAA,EAMQ,cAAc,OAAe,KAAa,KAAsB;AACtE,UAAM,IAAI,eAAe,KAAK;AAC9B,UAAM,QAAQ,eAAe,GAAG;AAChC,UAAM,MAAM,eAAe,GAAG;AAC9B,WAAO,SAAS,MAAM,KAAK,SAAS,KAAK,MAAM,KAAK,SAAS,KAAK;AAAA,EACpE;AAAA,EAEQ,gBAAkC;AACxC,WAAO,KAAK,eAAe,IAAI,CAAC,EAAC,UAAU,UAAU,QAAQ,WAAU;AACrE,YAAM,QAAQ,KAAK,cAAc,KAAK,SAAS,UAAU,QAAQ,IAC7D,YAAY,YACZ,SACE,YAAY,SACZ,YAAY;AAClB,aAAO;AAAA,QACL,UAAU,KAAK,UAAU,QAAQ;AAAA,QACjC,UAAU,KAAK,UAAU,QAAQ;AAAA,QACjC;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,CAAC;AAAA,EACH;AAAA,EAEA,IAAY,eAAuB;AACjC,UAAM,SAAS,KAAK,eAAe;AACnC,UAAM,gBAAiB,KAAK,qBAAqB,SAAU;AAC3D,WAAO,KAAK,UAAU,KAAK,UAAU,aAAa;AAAA,EACpD;AAAA,EAEQ,YAAY,SAAiD;AACnE,UAAM,WAAW,MAAM,QAAQ,KAAK,gBAAgB,IAChD,KAAK,mBACL,CAAA;AACJ,WAAO,SAAS,SAAS,OAAO,IAAI,KAAK,WAAW,SAAS;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAMS,SAAS;AAChB,UAAM,WAAW,CAAC,KAAK;AACvB,UAAM,UAAU,KAAK;AACrB,UAAM,OAAO,KAAK;AAElB,UAAM,YAAY,KAAK,UAAU,KAAK,gBAAgB;AACtD,UAAM,iBACJ,KAAK,mBAAmB,OACpB,KAAK,UAAU,KAAK,eAAe,IACnC;AACN,UAAM,oBACJ,KAAK,sBAAsB,OACvB,KAAK,UAAU,KAAK,kBAAkB,IACtC;AAEN,WAAO;AAAA;AAAA;AAAA,sBAGW,KAAK,QAAQ;AAAA,qBACd,OAAO;AAAA,qBACP,KAAK,cAAc;AAAA,uBACjB,KAAK,gBAAgB;AAAA,2BACjB,cAAc,OAAO;AAAA,6BACnB,KAAK,eAAe;AAAA,mBAC9B,KAAK,KAAK;AAAA,6BACA,UAAU;AAAA,wBACf,KAAK;AAAA,mBACV,KAAK,YAAY;AAAA,sBACd,KAAK,eAAe;AAAA,0BAChB,KAAK,YAAY;AAAA,2BAChB,KAAK,iBAAiB,GAAG;AAAA,sBAC9B,QAAQ;AAAA,2BACH,cAAc;AAAA,8BACX,iBAAiB;AAAA,6BAClB,KAAK,WAAW,kBAAkB,KAAK,OAAO,CAAC;AAAA,yCACnC,KAAK,6BAA6B;AAAA,8BAC7C,KAAK,uBAAuB;AAAA,sBACpC,KAAK,QAAQ;AAAA,6BACN,KAAK,eAAe;AAAA,qBAC5B,KAAK,OAAO;AAAA,yBACR,KAAK,WAAW;AAAA,2BACd,KAAK,OAAO;AAAA,yBACd,KAAK,YAAY;AAAA,yBACjB,KAAK;AAAA,MAAY;AAAA;AAAA,IAAA,CAAiC;AAAA,gCAC3C,KAAK,kBAAkB;AAAA;AAAA;AAAA,wBAG/B,OAAO,uBAAuB,QAAQ;AAAA,YAClD,KAAK,kBAAkB,IAAI,CAAC;AAAA,YAC5B;AAAA,MACA,WAAW;AAAA,MACX,KAAK;AAAA,MACL,KAAK;AAAA,QAAY;AAAA;AAAA,MAAA;AAAA,MACjB;AAAA,IAAA,CACD;AAAA,YACC;AAAA,MACA,WAAW;AAAA,MACX;AAAA,MACA,KAAK;AAAA,QAAY;AAAA;AAAA,MAAA;AAAA,MACjB;AAAA,IAAA,CACD;AAAA;AAAA;AAAA;AAAA,EAIT;AAGF;AAjVa,iBAgVK,SAAS,UAAU,cAAc;AA/UvB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GADb,iBACe,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAFb,iBAEe,WAAA,oBAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAJb,iBAIe,WAAA,mBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GALb,iBAKe,WAAA,sBAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GANd,iBAMgB,WAAA,qBAAA,CAAA;AACD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAPb,iBAOe,WAAA,iCAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GARd,iBAQgB,WAAA,2BAAA,CAAA;AACkB,gBAAA;AAAA,EAA5C,SAAS,EAAC,MAAM,SAAS,WAAW,OAAM;AAAA,GAThC,iBASkC,WAAA,yBAAA,CAAA;AACnB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAVb,iBAUe,WAAA,iCAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAXd,iBAWgB,WAAA,mBAAA,CAAA;AACA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAZd,iBAYgB,WAAA,YAAA,CAAA;AACgB,gBAAA;AAAA,EAA1C,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAb9B,iBAagC,WAAA,kBAAA,CAAA;AAEjB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAfb,iBAee,WAAA,UAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAjBb,iBAiBe,WAAA,WAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAlBb,iBAkBe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAnBb,iBAmBe,WAAA,sBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GApBb,iBAoBe,WAAA,eAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAtBb,iBAsBe,WAAA,SAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAvBb,iBAuBe,WAAA,YAAA,CAAA;AAE1B,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,OAAO,WAAW,OAAM;AAAA,GAxB9B,iBAyBX,WAAA,oBAAA,CAAA;AAG2B,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA5Bd,iBA4BgB,WAAA,mBAAA,CAAA;AACA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GA7Bd,iBA6BgB,WAAA,gBAAA,CAAA;AA7BhB,mBAAN,gBAAA;AAAA,EADN,cAAc,oBAAoB;AAAA,GACtB,gBAAA;"}
|
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import { ReactiveController, ReactiveControllerHost } from 'lit';
|
|
2
2
|
export declare class RateOfTurnController implements ReactiveController {
|
|
3
3
|
private host;
|
|
4
|
-
|
|
4
|
+
readonly el: Element;
|
|
5
5
|
private animation?;
|
|
6
6
|
private _rotationsPerMinute;
|
|
7
|
-
|
|
7
|
+
private _cyclePx;
|
|
8
|
+
constructor(host: ReactiveControllerHost, el: Element, initialRotationsPerMinute?: number, cyclePx?: number);
|
|
8
9
|
set rotationsPerMinute(value: number);
|
|
9
10
|
get rotationsPerMinute(): number;
|
|
11
|
+
set cyclePx(value: number);
|
|
12
|
+
get cyclePx(): number;
|
|
13
|
+
private get isTranslateMode();
|
|
14
|
+
private getKeyframes;
|
|
10
15
|
hostConnected(): void;
|
|
11
16
|
private startAnimation;
|
|
12
17
|
private updateAnimation;
|
|
18
|
+
destroy(): void;
|
|
19
|
+
hostDisconnected(): void;
|
|
13
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Dispose a `RateOfTurnController` reference: destroy the animation,
|
|
23
|
+
* remove the controller from its host, and return `undefined` to clear
|
|
24
|
+
* the caller's field.
|
|
25
|
+
*/
|
|
26
|
+
export declare function disposeRotController(host: ReactiveControllerHost, controller: RateOfTurnController | undefined): undefined;
|
|
14
27
|
//# sourceMappingURL=rate-of-turn.controller.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-of-turn.controller.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/rate-of-turn/rate-of-turn.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,kBAAkB,EAAE,sBAAsB,EAAC,MAAM,KAAK,CAAC;AAE/D,qBAAa,oBAAqB,YAAW,kBAAkB;IAC7D,OAAO,CAAC,IAAI,CAAyB;IACrC,
|
|
1
|
+
{"version":3,"file":"rate-of-turn.controller.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/rate-of-turn/rate-of-turn.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,kBAAkB,EAAE,sBAAsB,EAAC,MAAM,KAAK,CAAC;AAE/D,qBAAa,oBAAqB,YAAW,kBAAkB;IAC7D,OAAO,CAAC,IAAI,CAAyB;IACrC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,QAAQ,CAAK;gBAGnB,IAAI,EAAE,sBAAsB,EAC5B,EAAE,EAAE,OAAO,EACX,yBAAyB,SAAI,EAC7B,OAAO,SAAI;IASb,IAAI,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAKnC;IAED,IAAI,kBAAkB,IAPQ,MAAM,CASnC;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,EAKxB;IAED,IAAI,OAAO,IAPQ,MAAM,CASxB;IAED,OAAO,KAAK,eAAe,GAE1B;IAED,OAAO,CAAC,YAAY;IAUpB,aAAa;IAIb,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,eAAe;IA+BvB,OAAO;IAKP,gBAAgB;CAGjB;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,sBAAsB,EAC5B,UAAU,EAAE,oBAAoB,GAAG,SAAS,GAC3C,SAAS,CAMX"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
class RateOfTurnController {
|
|
2
|
-
constructor(host, el, initialRotationsPerMinute = 1) {
|
|
2
|
+
constructor(host, el, initialRotationsPerMinute = 1, cyclePx = 0) {
|
|
3
3
|
this._rotationsPerMinute = 1;
|
|
4
|
+
this._cyclePx = 0;
|
|
4
5
|
this.host = host;
|
|
5
6
|
this.el = el;
|
|
6
7
|
this._rotationsPerMinute = initialRotationsPerMinute;
|
|
8
|
+
this._cyclePx = cyclePx;
|
|
7
9
|
this.host.addController(this);
|
|
8
10
|
}
|
|
9
11
|
set rotationsPerMinute(value) {
|
|
@@ -15,20 +17,38 @@ class RateOfTurnController {
|
|
|
15
17
|
get rotationsPerMinute() {
|
|
16
18
|
return this._rotationsPerMinute;
|
|
17
19
|
}
|
|
20
|
+
set cyclePx(value) {
|
|
21
|
+
if (this._cyclePx !== value) {
|
|
22
|
+
this._cyclePx = value;
|
|
23
|
+
this.updateAnimation();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
get cyclePx() {
|
|
27
|
+
return this._cyclePx;
|
|
28
|
+
}
|
|
29
|
+
get isTranslateMode() {
|
|
30
|
+
return this._cyclePx > 0;
|
|
31
|
+
}
|
|
32
|
+
getKeyframes() {
|
|
33
|
+
if (this.isTranslateMode) {
|
|
34
|
+
return [
|
|
35
|
+
{ transform: "translateX(0px)" },
|
|
36
|
+
{ transform: `translateX(${this._cyclePx}px)` }
|
|
37
|
+
];
|
|
38
|
+
}
|
|
39
|
+
return [{ transform: "rotate(0deg)" }, { transform: "rotate(360deg)" }];
|
|
40
|
+
}
|
|
18
41
|
hostConnected() {
|
|
19
42
|
this.startAnimation();
|
|
20
43
|
}
|
|
21
44
|
startAnimation() {
|
|
22
45
|
const absSpeed = Math.abs(this._rotationsPerMinute);
|
|
23
46
|
const duration = absSpeed === 0 ? 1 : 1e3 * 60 / absSpeed;
|
|
24
|
-
this.animation = this.el.animate(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
direction: this._rotationsPerMinute >= 0 ? "normal" : "reverse"
|
|
30
|
-
}
|
|
31
|
-
);
|
|
47
|
+
this.animation = this.el.animate(this.getKeyframes(), {
|
|
48
|
+
duration,
|
|
49
|
+
iterations: Infinity,
|
|
50
|
+
direction: this._rotationsPerMinute >= 0 ? "normal" : "reverse"
|
|
51
|
+
});
|
|
32
52
|
if (this._rotationsPerMinute === 0) {
|
|
33
53
|
this.animation.pause();
|
|
34
54
|
}
|
|
@@ -45,21 +65,33 @@ class RateOfTurnController {
|
|
|
45
65
|
const newDuration = absSpeed === 0 ? 1 : 1e3 * 60 / absSpeed;
|
|
46
66
|
const newDirection = this._rotationsPerMinute >= 0 ? "normal" : "reverse";
|
|
47
67
|
const correctedProgress = oldDirection !== newDirection ? 1 - progress : progress;
|
|
48
|
-
this.animation = this.el.animate(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
direction: newDirection
|
|
54
|
-
}
|
|
55
|
-
);
|
|
68
|
+
this.animation = this.el.animate(this.getKeyframes(), {
|
|
69
|
+
duration: newDuration,
|
|
70
|
+
iterations: Infinity,
|
|
71
|
+
direction: newDirection
|
|
72
|
+
});
|
|
56
73
|
this.animation.currentTime = correctedProgress * newDuration;
|
|
57
74
|
if (this._rotationsPerMinute === 0) {
|
|
58
75
|
this.animation.pause();
|
|
59
76
|
}
|
|
60
77
|
}
|
|
78
|
+
destroy() {
|
|
79
|
+
this.animation?.cancel();
|
|
80
|
+
this.animation = void 0;
|
|
81
|
+
}
|
|
82
|
+
hostDisconnected() {
|
|
83
|
+
this.destroy();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function disposeRotController(host, controller) {
|
|
87
|
+
if (controller) {
|
|
88
|
+
controller.destroy();
|
|
89
|
+
host.removeController(controller);
|
|
90
|
+
}
|
|
91
|
+
return void 0;
|
|
61
92
|
}
|
|
62
93
|
export {
|
|
63
|
-
RateOfTurnController
|
|
94
|
+
RateOfTurnController,
|
|
95
|
+
disposeRotController
|
|
64
96
|
};
|
|
65
97
|
//# sourceMappingURL=rate-of-turn.controller.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate-of-turn.controller.js","sources":["../../../src/navigation-instruments/rate-of-turn/rate-of-turn.controller.ts"],"sourcesContent":["// spinner-controller.ts\nimport {ReactiveController, ReactiveControllerHost} from 'lit';\n\nexport class RateOfTurnController implements ReactiveController {\n private host: ReactiveControllerHost;\n
|
|
1
|
+
{"version":3,"file":"rate-of-turn.controller.js","sources":["../../../src/navigation-instruments/rate-of-turn/rate-of-turn.controller.ts"],"sourcesContent":["// spinner-controller.ts\nimport {ReactiveController, ReactiveControllerHost} from 'lit';\n\nexport class RateOfTurnController implements ReactiveController {\n private host: ReactiveControllerHost;\n readonly el: Element;\n private animation?: Animation;\n private _rotationsPerMinute = 1;\n private _cyclePx = 0;\n\n constructor(\n host: ReactiveControllerHost,\n el: Element,\n initialRotationsPerMinute = 1,\n cyclePx = 0\n ) {\n this.host = host;\n this.el = el;\n this._rotationsPerMinute = initialRotationsPerMinute;\n this._cyclePx = cyclePx;\n this.host.addController(this);\n }\n\n set rotationsPerMinute(value: number) {\n if (this._rotationsPerMinute !== value) {\n this._rotationsPerMinute = value;\n this.updateAnimation();\n }\n }\n\n get rotationsPerMinute() {\n return this._rotationsPerMinute;\n }\n\n set cyclePx(value: number) {\n if (this._cyclePx !== value) {\n this._cyclePx = value;\n this.updateAnimation();\n }\n }\n\n get cyclePx() {\n return this._cyclePx;\n }\n\n private get isTranslateMode() {\n return this._cyclePx > 0;\n }\n\n private getKeyframes(): Keyframe[] {\n if (this.isTranslateMode) {\n return [\n {transform: 'translateX(0px)'},\n {transform: `translateX(${this._cyclePx}px)`},\n ];\n }\n return [{transform: 'rotate(0deg)'}, {transform: 'rotate(360deg)'}];\n }\n\n hostConnected() {\n this.startAnimation();\n }\n\n private startAnimation() {\n const absSpeed = Math.abs(this._rotationsPerMinute);\n const duration = absSpeed === 0 ? 1 : (1000 * 60) / absSpeed;\n\n this.animation = this.el.animate(this.getKeyframes(), {\n duration,\n iterations: Infinity,\n direction: this._rotationsPerMinute >= 0 ? 'normal' : 'reverse',\n });\n\n if (this._rotationsPerMinute === 0) {\n this.animation.pause();\n }\n }\n\n private updateAnimation() {\n if (!this.animation) return;\n\n const currentTiming = this.animation.effect!.getComputedTiming();\n const oldDuration = currentTiming.duration as number;\n const currentTime = (this.animation.currentTime as number) ?? 0;\n const oldDirection = currentTiming.direction;\n const progress = (currentTime % oldDuration) / oldDuration;\n\n this.animation.cancel();\n\n const absSpeed = Math.abs(this._rotationsPerMinute);\n const newDuration = absSpeed === 0 ? 1 : (1000 * 60) / absSpeed;\n const newDirection = this._rotationsPerMinute >= 0 ? 'normal' : 'reverse';\n\n const correctedProgress =\n oldDirection !== newDirection ? 1 - progress : progress;\n\n this.animation = this.el.animate(this.getKeyframes(), {\n duration: newDuration,\n iterations: Infinity,\n direction: newDirection,\n });\n\n this.animation.currentTime = correctedProgress * newDuration;\n\n if (this._rotationsPerMinute === 0) {\n this.animation.pause();\n }\n }\n\n destroy() {\n this.animation?.cancel();\n this.animation = undefined;\n }\n\n hostDisconnected() {\n this.destroy();\n }\n}\n\n/**\n * Dispose a `RateOfTurnController` reference: destroy the animation,\n * remove the controller from its host, and return `undefined` to clear\n * the caller's field.\n */\nexport function disposeRotController(\n host: ReactiveControllerHost,\n controller: RateOfTurnController | undefined\n): undefined {\n if (controller) {\n controller.destroy();\n host.removeController(controller);\n }\n return undefined;\n}\n"],"names":[],"mappings":"AAGO,MAAM,qBAAmD;AAAA,EAO9D,YACE,MACA,IACA,4BAA4B,GAC5B,UAAU,GACV;AARF,SAAQ,sBAAsB;AAC9B,SAAQ,WAAW;AAQjB,SAAK,OAAO;AACZ,SAAK,KAAK;AACV,SAAK,sBAAsB;AAC3B,SAAK,WAAW;AAChB,SAAK,KAAK,cAAc,IAAI;AAAA,EAC9B;AAAA,EAEA,IAAI,mBAAmB,OAAe;AACpC,QAAI,KAAK,wBAAwB,OAAO;AACtC,WAAK,sBAAsB;AAC3B,WAAK,gBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEA,IAAI,qBAAqB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,QAAQ,OAAe;AACzB,QAAI,KAAK,aAAa,OAAO;AAC3B,WAAK,WAAW;AAChB,WAAK,gBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEA,IAAI,UAAU;AACZ,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAY,kBAAkB;AAC5B,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEQ,eAA2B;AACjC,QAAI,KAAK,iBAAiB;AACxB,aAAO;AAAA,QACL,EAAC,WAAW,kBAAA;AAAA,QACZ,EAAC,WAAW,cAAc,KAAK,QAAQ,MAAA;AAAA,MAAK;AAAA,IAEhD;AACA,WAAO,CAAC,EAAC,WAAW,eAAA,GAAiB,EAAC,WAAW,kBAAiB;AAAA,EACpE;AAAA,EAEA,gBAAgB;AACd,SAAK,eAAA;AAAA,EACP;AAAA,EAEQ,iBAAiB;AACvB,UAAM,WAAW,KAAK,IAAI,KAAK,mBAAmB;AAClD,UAAM,WAAW,aAAa,IAAI,IAAK,MAAO,KAAM;AAEpD,SAAK,YAAY,KAAK,GAAG,QAAQ,KAAK,gBAAgB;AAAA,MACpD;AAAA,MACA,YAAY;AAAA,MACZ,WAAW,KAAK,uBAAuB,IAAI,WAAW;AAAA,IAAA,CACvD;AAED,QAAI,KAAK,wBAAwB,GAAG;AAClC,WAAK,UAAU,MAAA;AAAA,IACjB;AAAA,EACF;AAAA,EAEQ,kBAAkB;AACxB,QAAI,CAAC,KAAK,UAAW;AAErB,UAAM,gBAAgB,KAAK,UAAU,OAAQ,kBAAA;AAC7C,UAAM,cAAc,cAAc;AAClC,UAAM,cAAe,KAAK,UAAU,eAA0B;AAC9D,UAAM,eAAe,cAAc;AACnC,UAAM,WAAY,cAAc,cAAe;AAE/C,SAAK,UAAU,OAAA;AAEf,UAAM,WAAW,KAAK,IAAI,KAAK,mBAAmB;AAClD,UAAM,cAAc,aAAa,IAAI,IAAK,MAAO,KAAM;AACvD,UAAM,eAAe,KAAK,uBAAuB,IAAI,WAAW;AAEhE,UAAM,oBACJ,iBAAiB,eAAe,IAAI,WAAW;AAEjD,SAAK,YAAY,KAAK,GAAG,QAAQ,KAAK,gBAAgB;AAAA,MACpD,UAAU;AAAA,MACV,YAAY;AAAA,MACZ,WAAW;AAAA,IAAA,CACZ;AAED,SAAK,UAAU,cAAc,oBAAoB;AAEjD,QAAI,KAAK,wBAAwB,GAAG;AAClC,WAAK,UAAU,MAAA;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,UAAU;AACR,SAAK,WAAW,OAAA;AAChB,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,mBAAmB;AACjB,SAAK,QAAA;AAAA,EACP;AACF;AAOO,SAAS,qBACd,MACA,YACW;AACX,MAAI,YAAY;AACd,eAAW,QAAA;AACX,SAAK,iBAAiB,UAAU;AAAA,EAClC;AACA,SAAO;AACT;"}
|