@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.105 → 2.0.0-next.106
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/bundle/openbridge-webcomponents.bundle.js +197 -100
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +46 -0
- package/dist/navigation-instruments/pitch-roll/pitch-roll.d.ts +26 -0
- package/dist/navigation-instruments/pitch-roll/pitch-roll.d.ts.map +1 -1
- package/dist/navigation-instruments/pitch-roll/pitch-roll.js +205 -102
- package/dist/navigation-instruments/pitch-roll/pitch-roll.js.map +1 -1
- package/package.json +1 -1
- package/src/navigation-instruments/pitch-roll/pitch-roll.stories.ts +27 -1
- package/src/navigation-instruments/pitch-roll/pitch-roll.ts +242 -122
|
@@ -30,6 +30,20 @@ export enum PitchRollPriorityElement {
|
|
|
30
30
|
roll = 'roll',
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
export enum PitchRollType {
|
|
34
|
+
/**
|
|
35
|
+
* Pitch and roll arcs on both opposing sides (default). Unlike
|
|
36
|
+
* `obc-pitch`/`obc-roll` this is the default, because it is the historical
|
|
37
|
+
* behaviour of `obc-pitch-roll`.
|
|
38
|
+
*/
|
|
39
|
+
dualScale = 'dual-scale',
|
|
40
|
+
/**
|
|
41
|
+
* One pitch arc on the right and one roll arc at the bottom, with a thin
|
|
42
|
+
* ring completing the circle and rotating indicator lines in the centre.
|
|
43
|
+
*/
|
|
44
|
+
singleScale = 'single-scale',
|
|
45
|
+
}
|
|
46
|
+
|
|
33
47
|
/** Half-side of the centre overlay viewBox in SVG units. */
|
|
34
48
|
const CENTRE_HALF = 200;
|
|
35
49
|
|
|
@@ -54,6 +68,12 @@ const MIN_ARC_HALF_DEG = 2;
|
|
|
54
68
|
*/
|
|
55
69
|
@customElement('obc-pitch-roll')
|
|
56
70
|
export class ObcPitchRoll extends LitElement {
|
|
71
|
+
/**
|
|
72
|
+
* `dual-scale` (default) shows pitch and roll arcs on both opposing sides;
|
|
73
|
+
* `single-scale` shows one pitch arc on the right and one roll arc at the
|
|
74
|
+
* bottom, completed by a thin ring.
|
|
75
|
+
*/
|
|
76
|
+
@property({type: String}) type: PitchRollType = PitchRollType.dualScale;
|
|
57
77
|
@property({type: Number}) pitch = 0;
|
|
58
78
|
@property({type: Number}) roll = 0;
|
|
59
79
|
@property({type: Number}) minAvgPitch = 0;
|
|
@@ -155,28 +175,20 @@ export class ObcPitchRoll extends LitElement {
|
|
|
155
175
|
return normalizeArcAngle(this.rollArcAngle ?? this.arcAngle, 30);
|
|
156
176
|
}
|
|
157
177
|
|
|
178
|
+
private get isSingleScale(): boolean {
|
|
179
|
+
return this.type === PitchRollType.singleScale;
|
|
180
|
+
}
|
|
181
|
+
|
|
158
182
|
override render() {
|
|
159
183
|
const pitchReq = this.requestedPitchArcAngle;
|
|
160
184
|
const rollReq = this.requestedRollArcAngle;
|
|
161
|
-
const areas = [
|
|
185
|
+
const areas: WatchArea[] = [
|
|
162
186
|
{
|
|
163
187
|
startAngle: 90 - pitchReq,
|
|
164
188
|
endAngle: 90 + pitchReq,
|
|
165
189
|
roundOutsideCut: true,
|
|
166
190
|
roundInsideCut: true,
|
|
167
191
|
},
|
|
168
|
-
{
|
|
169
|
-
startAngle: 270 - pitchReq,
|
|
170
|
-
endAngle: 270 + pitchReq,
|
|
171
|
-
roundOutsideCut: true,
|
|
172
|
-
roundInsideCut: true,
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
startAngle: 360 - rollReq,
|
|
176
|
-
endAngle: rollReq,
|
|
177
|
-
roundOutsideCut: true,
|
|
178
|
-
roundInsideCut: true,
|
|
179
|
-
},
|
|
180
192
|
{
|
|
181
193
|
startAngle: 180 - rollReq,
|
|
182
194
|
endAngle: 180 + rollReq,
|
|
@@ -184,6 +196,22 @@ export class ObcPitchRoll extends LitElement {
|
|
|
184
196
|
roundInsideCut: true,
|
|
185
197
|
},
|
|
186
198
|
];
|
|
199
|
+
if (!this.isSingleScale) {
|
|
200
|
+
areas.push(
|
|
201
|
+
{
|
|
202
|
+
startAngle: 270 - pitchReq,
|
|
203
|
+
endAngle: 270 + pitchReq,
|
|
204
|
+
roundOutsideCut: true,
|
|
205
|
+
roundInsideCut: true,
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
startAngle: 360 - rollReq,
|
|
209
|
+
endAngle: rollReq,
|
|
210
|
+
roundOutsideCut: true,
|
|
211
|
+
roundInsideCut: true,
|
|
212
|
+
}
|
|
213
|
+
);
|
|
214
|
+
}
|
|
187
215
|
|
|
188
216
|
const overlayViewBox = `-${CENTRE_HALF} -${CENTRE_HALF} ${CENTRE_HALF * 2} ${CENTRE_HALF * 2}`;
|
|
189
217
|
const vesselScale = 224 / 160;
|
|
@@ -191,16 +219,56 @@ export class ObcPitchRoll extends LitElement {
|
|
|
191
219
|
return html`
|
|
192
220
|
<div class="container">
|
|
193
221
|
<svg viewBox="${overlayViewBox}">
|
|
222
|
+
${this.isSingleScale && !this.zoomToFitArc
|
|
223
|
+
? this.renderRingComplement(pitchReq, rollReq)
|
|
224
|
+
: nothing}
|
|
194
225
|
${this.hasReadout
|
|
195
226
|
? nothing
|
|
196
227
|
: svg`
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
228
|
+
${
|
|
229
|
+
this.isSingleScale
|
|
230
|
+
? svg`
|
|
231
|
+
<line
|
|
232
|
+
x1=${-OUTER_RING_RADIUS}
|
|
233
|
+
y1="0"
|
|
234
|
+
x2=${OUTER_RING_RADIUS}
|
|
235
|
+
y2="0"
|
|
236
|
+
stroke="var(--instrument-frame-tertiary-color)"
|
|
237
|
+
/>
|
|
238
|
+
<line
|
|
239
|
+
x1="0"
|
|
240
|
+
y1=${-OUTER_RING_RADIUS}
|
|
241
|
+
x2="0"
|
|
242
|
+
y2=${OUTER_RING_RADIUS}
|
|
243
|
+
stroke="var(--instrument-frame-tertiary-color)"
|
|
244
|
+
/>
|
|
245
|
+
<line
|
|
246
|
+
x1="0"
|
|
247
|
+
y1="0"
|
|
248
|
+
x2=${OUTER_RING_RADIUS - 10}
|
|
249
|
+
y2="0"
|
|
250
|
+
stroke="${this.needleColor(PitchRollPriorityElement.pitch)}"
|
|
251
|
+
transform="rotate(${this.pitch} 0 0)"
|
|
252
|
+
/>
|
|
253
|
+
<line
|
|
254
|
+
x1="0"
|
|
255
|
+
y1="0"
|
|
256
|
+
x2="0"
|
|
257
|
+
y2=${OUTER_RING_RADIUS - 10}
|
|
258
|
+
stroke="${this.needleColor(PitchRollPriorityElement.roll)}"
|
|
259
|
+
transform="rotate(${this.roll} 0 0)"
|
|
260
|
+
/>
|
|
261
|
+
`
|
|
262
|
+
: svg`
|
|
263
|
+
<line
|
|
264
|
+
x1="-150"
|
|
265
|
+
y1="0"
|
|
266
|
+
x2="150"
|
|
267
|
+
y2="0"
|
|
268
|
+
stroke="var(--instrument-frame-tertiary-color)"
|
|
269
|
+
/>
|
|
270
|
+
`
|
|
271
|
+
}
|
|
204
272
|
<g
|
|
205
273
|
style="transform: rotate(${this.pitch}deg) scale(${vesselScale}) translate(-80px, -80px);"
|
|
206
274
|
>
|
|
@@ -242,6 +310,38 @@ export class ObcPitchRoll extends LitElement {
|
|
|
242
310
|
`;
|
|
243
311
|
}
|
|
244
312
|
|
|
313
|
+
/**
|
|
314
|
+
* Thin ring segments completing the circle between the single-scale arcs:
|
|
315
|
+
* one short segment between the pitch (right) and roll (bottom) arcs, and
|
|
316
|
+
* one long segment the other way around (left and top).
|
|
317
|
+
*/
|
|
318
|
+
private renderRingComplement(pitchArc: number, rollArc: number) {
|
|
319
|
+
const r = OUTER_RING_RADIUS;
|
|
320
|
+
const pt = (deg: number): [number, number] => {
|
|
321
|
+
const rad = ((deg - 90) * Math.PI) / 180;
|
|
322
|
+
return [r * Math.cos(rad), r * Math.sin(rad)];
|
|
323
|
+
};
|
|
324
|
+
const segment = (from: number, to: number) => {
|
|
325
|
+
if (to - from <= 0) {
|
|
326
|
+
return nothing;
|
|
327
|
+
}
|
|
328
|
+
const [x1, y1] = pt(from);
|
|
329
|
+
const [x2, y2] = pt(to);
|
|
330
|
+
const large = to - from > 180 ? 1 : 0;
|
|
331
|
+
return svg`
|
|
332
|
+
<path
|
|
333
|
+
d="M ${x1} ${y1} A ${r} ${r} 0 ${large} 1 ${x2} ${y2}"
|
|
334
|
+
fill="none"
|
|
335
|
+
stroke="var(--instrument-frame-tertiary-color)"
|
|
336
|
+
/>
|
|
337
|
+
`;
|
|
338
|
+
};
|
|
339
|
+
return svg`
|
|
340
|
+
${segment(90 + pitchArc, 180 - rollArc)}
|
|
341
|
+
${segment(180 + rollArc, 450 - pitchArc)}
|
|
342
|
+
`;
|
|
343
|
+
}
|
|
344
|
+
|
|
245
345
|
/**
|
|
246
346
|
* Zoomed-arc layer: four CSS-rotated `<obc-watch>` instances, each
|
|
247
347
|
* containing a single arc rendered at the watch's natural top
|
|
@@ -521,16 +621,18 @@ export class ObcPitchRoll extends LitElement {
|
|
|
521
621
|
`;
|
|
522
622
|
|
|
523
623
|
return html`
|
|
524
|
-
${
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
624
|
+
${this.isSingleScale
|
|
625
|
+
? nothing
|
|
626
|
+
: subWatch(
|
|
627
|
+
0,
|
|
628
|
+
rollFrame.subArcFrame,
|
|
629
|
+
rollAreas,
|
|
630
|
+
rollBars,
|
|
631
|
+
rollNeedles,
|
|
632
|
+
rollAdvices,
|
|
633
|
+
rollClip,
|
|
634
|
+
rollTickmarks
|
|
635
|
+
)}
|
|
534
636
|
${subWatch(
|
|
535
637
|
90,
|
|
536
638
|
pitchFrame.subArcFrame,
|
|
@@ -551,16 +653,18 @@ export class ObcPitchRoll extends LitElement {
|
|
|
551
653
|
rollClip,
|
|
552
654
|
rollTickmarks
|
|
553
655
|
)}
|
|
554
|
-
${
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
656
|
+
${this.isSingleScale
|
|
657
|
+
? nothing
|
|
658
|
+
: subWatch(
|
|
659
|
+
270,
|
|
660
|
+
pitchFrame.subArcFrame,
|
|
661
|
+
pitchAreas,
|
|
662
|
+
pitchBars,
|
|
663
|
+
pitchNeedles,
|
|
664
|
+
pitchAdvices,
|
|
665
|
+
pitchClip,
|
|
666
|
+
pitchTickmarks
|
|
667
|
+
)}
|
|
564
668
|
`;
|
|
565
669
|
}
|
|
566
670
|
|
|
@@ -603,55 +707,76 @@ export class ObcPitchRoll extends LitElement {
|
|
|
603
707
|
|
|
604
708
|
/** Full unzoomed watch — original single-instance render. */
|
|
605
709
|
private renderFullWatch(areas: WatchArea[]) {
|
|
710
|
+
const barAreas = [
|
|
711
|
+
{
|
|
712
|
+
startAngle: 180 + this.minAvgRoll,
|
|
713
|
+
endAngle: 180 + this.maxAvgRoll,
|
|
714
|
+
fillColor: this.barColor(PitchRollPriorityElement.roll),
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
startAngle: 90 + this.minAvgPitch,
|
|
718
|
+
endAngle: 90 + this.maxAvgPitch,
|
|
719
|
+
fillColor: this.barColor(PitchRollPriorityElement.pitch),
|
|
720
|
+
},
|
|
721
|
+
];
|
|
722
|
+
const needles = [
|
|
723
|
+
{
|
|
724
|
+
angle: 180 + this.roll,
|
|
725
|
+
fillColor: this.needleColor(PitchRollPriorityElement.roll),
|
|
726
|
+
strokeColor: 'var(--border-silhouette-color)',
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
angle: 90 + this.pitch,
|
|
730
|
+
fillColor: this.needleColor(PitchRollPriorityElement.pitch),
|
|
731
|
+
strokeColor: 'var(--border-silhouette-color)',
|
|
732
|
+
},
|
|
733
|
+
];
|
|
734
|
+
const tickmarks = [
|
|
735
|
+
{angle: 90, type: TickmarkType.main},
|
|
736
|
+
{angle: 180, type: TickmarkType.main},
|
|
737
|
+
...arcTickmarks(90, this.requestedPitchArcAngle),
|
|
738
|
+
...arcTickmarks(180, this.requestedRollArcAngle),
|
|
739
|
+
];
|
|
740
|
+
if (!this.isSingleScale) {
|
|
741
|
+
barAreas.push(
|
|
742
|
+
{
|
|
743
|
+
startAngle: this.minAvgRoll,
|
|
744
|
+
endAngle: this.maxAvgRoll,
|
|
745
|
+
fillColor: this.barColor(PitchRollPriorityElement.roll),
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
startAngle: 270 + this.minAvgPitch,
|
|
749
|
+
endAngle: 270 + this.maxAvgPitch,
|
|
750
|
+
fillColor: this.barColor(PitchRollPriorityElement.pitch),
|
|
751
|
+
}
|
|
752
|
+
);
|
|
753
|
+
needles.push(
|
|
754
|
+
{
|
|
755
|
+
angle: this.roll,
|
|
756
|
+
fillColor: this.needleColor(PitchRollPriorityElement.roll),
|
|
757
|
+
strokeColor: 'var(--border-silhouette-color)',
|
|
758
|
+
},
|
|
759
|
+
{
|
|
760
|
+
angle: 270 + this.pitch,
|
|
761
|
+
fillColor: this.needleColor(PitchRollPriorityElement.pitch),
|
|
762
|
+
strokeColor: 'var(--border-silhouette-color)',
|
|
763
|
+
}
|
|
764
|
+
);
|
|
765
|
+
tickmarks.push(
|
|
766
|
+
{angle: 0, type: TickmarkType.main},
|
|
767
|
+
{angle: 270, type: TickmarkType.main},
|
|
768
|
+
...arcTickmarks(0, this.requestedRollArcAngle),
|
|
769
|
+
...arcTickmarks(270, this.requestedPitchArcAngle)
|
|
770
|
+
);
|
|
771
|
+
}
|
|
772
|
+
|
|
606
773
|
return html`
|
|
607
774
|
<obc-watch
|
|
608
775
|
.watchCircleType=${WatchCircleType.double}
|
|
609
776
|
.zoomToFitArc=${false}
|
|
610
777
|
.areas=${areas}
|
|
611
|
-
.barAreas=${
|
|
612
|
-
|
|
613
|
-
startAngle: this.minAvgRoll,
|
|
614
|
-
endAngle: this.maxAvgRoll,
|
|
615
|
-
fillColor: this.barColor(PitchRollPriorityElement.roll),
|
|
616
|
-
},
|
|
617
|
-
{
|
|
618
|
-
startAngle: 180 + this.minAvgRoll,
|
|
619
|
-
endAngle: 180 + this.maxAvgRoll,
|
|
620
|
-
fillColor: this.barColor(PitchRollPriorityElement.roll),
|
|
621
|
-
},
|
|
622
|
-
{
|
|
623
|
-
startAngle: 90 + this.minAvgPitch,
|
|
624
|
-
endAngle: 90 + this.maxAvgPitch,
|
|
625
|
-
fillColor: this.barColor(PitchRollPriorityElement.pitch),
|
|
626
|
-
},
|
|
627
|
-
{
|
|
628
|
-
startAngle: 270 + this.minAvgPitch,
|
|
629
|
-
endAngle: 270 + this.maxAvgPitch,
|
|
630
|
-
fillColor: this.barColor(PitchRollPriorityElement.pitch),
|
|
631
|
-
},
|
|
632
|
-
]}
|
|
633
|
-
.needles=${[
|
|
634
|
-
{
|
|
635
|
-
angle: this.roll,
|
|
636
|
-
fillColor: this.needleColor(PitchRollPriorityElement.roll),
|
|
637
|
-
strokeColor: 'var(--border-silhouette-color)',
|
|
638
|
-
},
|
|
639
|
-
{
|
|
640
|
-
angle: 180 + this.roll,
|
|
641
|
-
fillColor: this.needleColor(PitchRollPriorityElement.roll),
|
|
642
|
-
strokeColor: 'var(--border-silhouette-color)',
|
|
643
|
-
},
|
|
644
|
-
{
|
|
645
|
-
angle: 90 + this.pitch,
|
|
646
|
-
fillColor: this.needleColor(PitchRollPriorityElement.pitch),
|
|
647
|
-
strokeColor: 'var(--border-silhouette-color)',
|
|
648
|
-
},
|
|
649
|
-
{
|
|
650
|
-
angle: 270 + this.pitch,
|
|
651
|
-
fillColor: this.needleColor(PitchRollPriorityElement.pitch),
|
|
652
|
-
strokeColor: 'var(--border-silhouette-color)',
|
|
653
|
-
},
|
|
654
|
-
]}
|
|
778
|
+
.barAreas=${barAreas}
|
|
779
|
+
.needles=${needles}
|
|
655
780
|
.vessels=${this.hasReadout
|
|
656
781
|
? []
|
|
657
782
|
: [
|
|
@@ -666,16 +791,7 @@ export class ObcPitchRoll extends LitElement {
|
|
|
666
791
|
transform: `rotate(${this.roll}deg) scale(${this.normalizedScaleForeImage})`,
|
|
667
792
|
},
|
|
668
793
|
]}
|
|
669
|
-
.tickmarks=${
|
|
670
|
-
{angle: 0, type: TickmarkType.main},
|
|
671
|
-
{angle: 90, type: TickmarkType.main},
|
|
672
|
-
{angle: 180, type: TickmarkType.main},
|
|
673
|
-
{angle: 270, type: TickmarkType.main},
|
|
674
|
-
...arcTickmarks(0, this.requestedRollArcAngle),
|
|
675
|
-
...arcTickmarks(180, this.requestedRollArcAngle),
|
|
676
|
-
...arcTickmarks(90, this.requestedPitchArcAngle),
|
|
677
|
-
...arcTickmarks(270, this.requestedPitchArcAngle),
|
|
678
|
-
]}
|
|
794
|
+
.tickmarks=${tickmarks}
|
|
679
795
|
.advices=${this.advices}
|
|
680
796
|
></obc-watch>
|
|
681
797
|
`;
|
|
@@ -705,20 +821,22 @@ export class ObcPitchRoll extends LitElement {
|
|
|
705
821
|
state: state,
|
|
706
822
|
hideMaxTickmark: true,
|
|
707
823
|
});
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
824
|
+
if (!this.isSingleScale) {
|
|
825
|
+
advices.push({
|
|
826
|
+
minAngle: 270 - outer,
|
|
827
|
+
maxAngle: 270 - inner,
|
|
828
|
+
type: AdviceType.caution,
|
|
829
|
+
state: state,
|
|
830
|
+
hideMinTickmark: true,
|
|
831
|
+
});
|
|
832
|
+
advices.push({
|
|
833
|
+
minAngle: 270 + inner,
|
|
834
|
+
maxAngle: 270 + outer,
|
|
835
|
+
type: AdviceType.caution,
|
|
836
|
+
state: state,
|
|
837
|
+
hideMaxTickmark: true,
|
|
838
|
+
});
|
|
839
|
+
}
|
|
722
840
|
}
|
|
723
841
|
if (this.maxRollAdvice !== undefined) {
|
|
724
842
|
const outer = Math.min(rollReq, 45);
|
|
@@ -726,20 +844,6 @@ export class ObcPitchRoll extends LitElement {
|
|
|
726
844
|
const state = this.triggerRollAdvice
|
|
727
845
|
? AdviceState.triggered
|
|
728
846
|
: AdviceState.regular;
|
|
729
|
-
advices.push({
|
|
730
|
-
minAngle: -outer,
|
|
731
|
-
maxAngle: -inner,
|
|
732
|
-
type: AdviceType.caution,
|
|
733
|
-
state: state,
|
|
734
|
-
hideMinTickmark: true,
|
|
735
|
-
});
|
|
736
|
-
advices.push({
|
|
737
|
-
minAngle: inner,
|
|
738
|
-
maxAngle: outer,
|
|
739
|
-
type: AdviceType.caution,
|
|
740
|
-
state: state,
|
|
741
|
-
hideMaxTickmark: true,
|
|
742
|
-
});
|
|
743
847
|
advices.push({
|
|
744
848
|
minAngle: 180 - outer,
|
|
745
849
|
maxAngle: 180 - inner,
|
|
@@ -754,6 +858,22 @@ export class ObcPitchRoll extends LitElement {
|
|
|
754
858
|
state: state,
|
|
755
859
|
hideMaxTickmark: true,
|
|
756
860
|
});
|
|
861
|
+
if (!this.isSingleScale) {
|
|
862
|
+
advices.push({
|
|
863
|
+
minAngle: -outer,
|
|
864
|
+
maxAngle: -inner,
|
|
865
|
+
type: AdviceType.caution,
|
|
866
|
+
state: state,
|
|
867
|
+
hideMinTickmark: true,
|
|
868
|
+
});
|
|
869
|
+
advices.push({
|
|
870
|
+
minAngle: inner,
|
|
871
|
+
maxAngle: outer,
|
|
872
|
+
type: AdviceType.caution,
|
|
873
|
+
state: state,
|
|
874
|
+
hideMaxTickmark: true,
|
|
875
|
+
});
|
|
876
|
+
}
|
|
757
877
|
}
|
|
758
878
|
return advices;
|
|
759
879
|
}
|