@oicl/openbridge-webcomponents 2.0.0-next.55 → 2.0.0-next.57
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 +395 -123
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +326 -2
- package/dist/automation/automation-tank/automation-tank.d.ts +11 -0
- package/dist/automation/automation-tank/automation-tank.d.ts.map +1 -1
- package/dist/automation/automation-tank/automation-tank.js.map +1 -1
- package/dist/navigation-instruments/compass-sector/compass-sector.css.js +12 -0
- package/dist/navigation-instruments/compass-sector/compass-sector.css.js.map +1 -1
- package/dist/navigation-instruments/compass-sector/compass-sector.d.ts +23 -0
- package/dist/navigation-instruments/compass-sector/compass-sector.d.ts.map +1 -1
- package/dist/navigation-instruments/compass-sector/compass-sector.js +47 -0
- package/dist/navigation-instruments/compass-sector/compass-sector.js.map +1 -1
- package/dist/navigation-instruments/pitch/pitch.d.ts +37 -0
- package/dist/navigation-instruments/pitch/pitch.d.ts.map +1 -1
- package/dist/navigation-instruments/pitch/pitch.js +130 -62
- package/dist/navigation-instruments/pitch/pitch.js.map +1 -1
- package/dist/navigation-instruments/pitch-roll/pitch-roll.d.ts +7 -0
- package/dist/navigation-instruments/pitch-roll/pitch-roll.d.ts.map +1 -1
- package/dist/navigation-instruments/pitch-roll/pitch-roll.js +58 -2
- package/dist/navigation-instruments/pitch-roll/pitch-roll.js.map +1 -1
- package/dist/navigation-instruments/roll/roll.d.ts +37 -0
- package/dist/navigation-instruments/roll/roll.d.ts.map +1 -1
- package/dist/navigation-instruments/roll/roll.js +119 -63
- package/dist/navigation-instruments/roll/roll.js.map +1 -1
- package/dist/navigation-instruments/rot-sector/rot-sector.d.ts +15 -0
- package/dist/navigation-instruments/rot-sector/rot-sector.d.ts.map +1 -1
- package/dist/navigation-instruments/rot-sector/rot-sector.js +53 -1
- package/dist/navigation-instruments/rot-sector/rot-sector.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
import { VesselImage } from '../watch/watch.js';
|
|
3
|
+
import { Priority } from '../types.js';
|
|
3
4
|
import '../watch/watch.js';
|
|
5
|
+
import '../readout/readout.js';
|
|
6
|
+
export declare enum ObcPitchType {
|
|
7
|
+
/** Single arc scale on the right (default). */
|
|
8
|
+
singleScale = "single-scale",
|
|
9
|
+
/** Right scale duplicated to the opposite (left) arc as well. */
|
|
10
|
+
dualScale = "dual-scale"
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* `<obc-pitch>` — Pitch (trim) indicator with a side arc scale.
|
|
14
|
+
*
|
|
15
|
+
* Shows `pitch` against a watch arc centred on the right, with an average-pitch
|
|
16
|
+
* band and a rotating indicator. Supports an optional opposite-side scale
|
|
17
|
+
* (`dual-scale`), a centre readout (`hasReadout`), and a `regular`/`enhanced`
|
|
18
|
+
* palette.
|
|
19
|
+
*
|
|
20
|
+
* @element obc-pitch
|
|
21
|
+
*/
|
|
4
22
|
export declare class ObcPitch extends LitElement {
|
|
5
23
|
pitch: number;
|
|
6
24
|
minAvgPitch: number;
|
|
@@ -9,6 +27,22 @@ export declare class ObcPitch extends LitElement {
|
|
|
9
27
|
maxPitchAdvice: number | undefined;
|
|
10
28
|
triggerPitchAdvice: boolean;
|
|
11
29
|
zoomToFitArc: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* When `true`, the centre shows an `<obc-readout>` with the pitch value
|
|
32
|
+
* (label `Pitch`, unit `DEG`) instead of the horizon line, rotating indicator
|
|
33
|
+
* and vessel. Default `false`.
|
|
34
|
+
*/
|
|
35
|
+
hasReadout: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* `single-scale` shows one arc on the right (default); `dual-scale` also
|
|
38
|
+
* shows the scale on the opposite (left) arc (the indicator's opposite end).
|
|
39
|
+
*/
|
|
40
|
+
type: ObcPitchType;
|
|
41
|
+
/**
|
|
42
|
+
* Colour palette for the scale fill / indicator and the readout value:
|
|
43
|
+
* `regular` (default) or `enhanced`.
|
|
44
|
+
*/
|
|
45
|
+
priority: Priority;
|
|
12
46
|
/**
|
|
13
47
|
* Half-extent of the watch arc in degrees. The arc spans `90° ± arcAngle`
|
|
14
48
|
* and pitch values are placed at their true position within it. Default
|
|
@@ -22,7 +56,10 @@ export declare class ObcPitch extends LitElement {
|
|
|
22
56
|
*/
|
|
23
57
|
arcAngle: number;
|
|
24
58
|
private _arcFrame;
|
|
59
|
+
private get scaleFillColor();
|
|
60
|
+
private get indicatorColor();
|
|
25
61
|
render(): import('lit-html').TemplateResult<1>;
|
|
62
|
+
private renderScale;
|
|
26
63
|
private get advices();
|
|
27
64
|
static styles: import('lit').CSSResult;
|
|
28
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pitch.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/pitch/pitch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA0B,MAAM,KAAK,CAAC;AAExD,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,
|
|
1
|
+
{"version":3,"file":"pitch.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/pitch/pitch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA0B,MAAM,KAAK,CAAC;AAExD,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EAOZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,uBAAuB,CAAC;AAE/B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAerC,oBAAY,YAAY;IACtB,+CAA+C;IAC/C,WAAW,iBAAiB;IAC5B,iEAAiE;IACjE,SAAS,eAAe;CACzB;AAED;;;;;;;;;GASG;AACH,qBACa,QAAS,SAAQ,UAAU;IACZ,KAAK,SAAK;IACV,WAAW,SAAK;IAChB,WAAW,SAAK;IAChB,eAAe,EAAE,WAAW,CAAuB;IACnD,cAAc,EAAE,MAAM,GAAG,SAAS,CAAa;IAC9C,kBAAkB,UAAS;IAC3B,YAAY,EAAE,OAAO,CAAS;IACzD;;;;OAIG;IACwB,UAAU,EAAE,OAAO,CAAS;IACvD;;;OAGG;IACuB,IAAI,EAAE,YAAY,CAA4B;IACxE;;;OAGG;IACuB,QAAQ,EAAE,QAAQ,CAAoB;IAChE;;;;;;;;;;OAUG;IACuB,QAAQ,EAAE,MAAM,CAAM;IAEhD,OAAO,CAAC,SAAS,CAAgC;IAEjD,OAAO,KAAK,cAAc,GAIzB;IAED,OAAO,KAAK,cAAc,GAIzB;IAEQ,MAAM;IA4Hf,OAAO,CAAC,WAAW;IAuCnB,OAAO,KAAK,OAAO,GA4BlB;IAED,OAAgB,MAAM,0BA4BpB;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,WAAW,EAAE,QAAQ,CAAC;KACvB;CACF"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { css, LitElement, nothing, svg, html } from "lit";
|
|
2
2
|
import { property } from "lit/decorators.js";
|
|
3
3
|
import { innerRingRadiusFor, WatchCircleType, OUTER_RING_RADIUS } from "../watch/watch.js";
|
|
4
|
+
import { ReadoutVariant, ReadoutDirection } from "../readout/readout.js";
|
|
5
|
+
import { Priority } from "../types.js";
|
|
4
6
|
import { TickmarkType } from "../watch/tickmark.js";
|
|
5
7
|
import { AdviceState, AdviceType } from "../watch/advice.js";
|
|
6
8
|
import { customElement } from "../../decorator.js";
|
|
7
9
|
import { normalizeArcAngle, computeZoomToFitArcFrame, shiftArcFrameToOuterEdge } from "../../svghelpers/arc-frame.js";
|
|
8
|
-
import { VesselImage,
|
|
10
|
+
import { VesselImage, vesselImages, VesselImageSize } from "../watch/vessel.js";
|
|
9
11
|
var __defProp = Object.defineProperty;
|
|
10
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
11
13
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -18,6 +20,11 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
18
20
|
};
|
|
19
21
|
const watchRadius = OUTER_RING_RADIUS;
|
|
20
22
|
const CENTRE_HALF = 200;
|
|
23
|
+
var ObcPitchType = /* @__PURE__ */ ((ObcPitchType2) => {
|
|
24
|
+
ObcPitchType2["singleScale"] = "single-scale";
|
|
25
|
+
ObcPitchType2["dualScale"] = "dual-scale";
|
|
26
|
+
return ObcPitchType2;
|
|
27
|
+
})(ObcPitchType || {});
|
|
21
28
|
let ObcPitch = class extends LitElement {
|
|
22
29
|
constructor() {
|
|
23
30
|
super(...arguments);
|
|
@@ -28,8 +35,17 @@ let ObcPitch = class extends LitElement {
|
|
|
28
35
|
this.maxPitchAdvice = void 0;
|
|
29
36
|
this.triggerPitchAdvice = false;
|
|
30
37
|
this.zoomToFitArc = false;
|
|
38
|
+
this.hasReadout = false;
|
|
39
|
+
this.type = "single-scale";
|
|
40
|
+
this.priority = Priority.regular;
|
|
31
41
|
this.arcAngle = 45;
|
|
32
42
|
}
|
|
43
|
+
get scaleFillColor() {
|
|
44
|
+
return this.priority === Priority.enhanced ? "var(--instrument-enhanced-tertiary-color)" : "var(--instrument-regular-tertiary-color)";
|
|
45
|
+
}
|
|
46
|
+
get indicatorColor() {
|
|
47
|
+
return this.priority === Priority.enhanced ? "var(--instrument-enhanced-secondary-color)" : "var(--instrument-regular-secondary-color)";
|
|
48
|
+
}
|
|
33
49
|
render() {
|
|
34
50
|
const arcAngle = normalizeArcAngle(this.arcAngle, 45);
|
|
35
51
|
const x = watchRadius * Math.cos(arcAngle * Math.PI / 180);
|
|
@@ -67,96 +83,128 @@ let ObcPitch = class extends LitElement {
|
|
|
67
83
|
return html`
|
|
68
84
|
<div class="container">
|
|
69
85
|
<svg viewBox="${centreViewBox}">
|
|
70
|
-
${svg`
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
86
|
+
${this.hasReadout ? nothing : svg`
|
|
87
|
+
<line
|
|
88
|
+
x1="-${watchRadius}"
|
|
89
|
+
y1="0"
|
|
90
|
+
x2="${watchRadius}"
|
|
91
|
+
y2="0"
|
|
92
|
+
stroke="var(--instrument-frame-tertiary-color)"
|
|
93
|
+
/>
|
|
94
|
+
<line
|
|
95
|
+
x1="0"
|
|
96
|
+
y1="0"
|
|
97
|
+
x2="${watchRadius - 10}"
|
|
98
|
+
y2="0"
|
|
99
|
+
stroke="${this.indicatorColor}"
|
|
100
|
+
transform="${needleTransform}"
|
|
101
|
+
/>
|
|
102
|
+
<g
|
|
103
|
+
style="transform: rotate(${this.pitch}deg) scale(${vesselScale}) translate(-80px, -80px);"
|
|
104
|
+
>
|
|
105
|
+
${this.zoomToFitArc ? vesselImages[this.vesselImageSide] : nothing}
|
|
106
|
+
</g>
|
|
107
|
+
`}
|
|
108
|
+
${this.zoomToFitArc ? nothing : this.type === "dual-scale" ? svg`
|
|
109
|
+
<path
|
|
110
|
+
d="M ${x} ${-y} A ${watchRadius} ${watchRadius} 0 0 0 ${-x} ${-y}"
|
|
111
|
+
fill="none"
|
|
112
|
+
stroke="var(--instrument-frame-tertiary-color)"
|
|
113
|
+
/>
|
|
114
|
+
<path
|
|
115
|
+
d="M ${x} ${y} A ${watchRadius} ${watchRadius} 0 0 1 ${-x} ${y}"
|
|
116
|
+
fill="none"
|
|
117
|
+
stroke="var(--instrument-frame-tertiary-color)"
|
|
118
|
+
/>
|
|
119
|
+
` : svg`
|
|
120
|
+
<path
|
|
121
|
+
d="M ${x} ${y} A ${watchRadius} ${watchRadius} 0 1 1 ${x} ${-y}"
|
|
122
|
+
fill="none"
|
|
123
|
+
stroke="var(--instrument-frame-tertiary-color)"
|
|
124
|
+
/>
|
|
125
|
+
`}
|
|
99
126
|
</svg>
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
127
|
+
${this.renderScale(areas, false)}
|
|
128
|
+
${this.type === "dual-scale" ? this.renderScale(areas, true) : nothing}
|
|
129
|
+
${this.hasReadout ? html`<div class="readout">
|
|
130
|
+
<obc-readout
|
|
131
|
+
.variant=${ReadoutVariant.enhanced}
|
|
132
|
+
.direction=${ReadoutDirection.vertical}
|
|
133
|
+
.hasSetpoint=${false}
|
|
134
|
+
.hasAdvice=${false}
|
|
135
|
+
.value=${this.pitch}
|
|
136
|
+
.fractionDigits=${0}
|
|
137
|
+
.valuePriority=${this.priority}
|
|
138
|
+
label="Pitch"
|
|
139
|
+
unit="DEG"
|
|
140
|
+
></obc-readout>
|
|
141
|
+
</div>` : nothing}
|
|
142
|
+
</div>
|
|
143
|
+
`;
|
|
144
|
+
}
|
|
145
|
+
// `opposite` rotates a second watch 180° onto the opposite (left) arc for
|
|
146
|
+
// dual-scale — a rotation (opposite end of the indicator), not a mirror. A
|
|
147
|
+
// separate watch keeps the zoomed `arcFrame` correct.
|
|
148
|
+
renderScale(areas, opposite) {
|
|
149
|
+
return html`
|
|
150
|
+
<obc-watch
|
|
151
|
+
class=${opposite ? "scale-opposite" : nothing}
|
|
152
|
+
.priority=${this.priority}
|
|
153
|
+
.watchCircleType=${WatchCircleType.double}
|
|
154
|
+
.zoomToFitArc=${this.zoomToFitArc}
|
|
155
|
+
.arcFrame=${this._arcFrame}
|
|
156
|
+
tickmarksInside
|
|
157
|
+
.areas=${areas}
|
|
158
|
+
.barAreas=${[
|
|
106
159
|
{
|
|
107
160
|
startAngle: 90 + this.minAvgPitch,
|
|
108
161
|
endAngle: 90 + this.maxAvgPitch,
|
|
109
|
-
fillColor:
|
|
162
|
+
fillColor: this.scaleFillColor
|
|
110
163
|
}
|
|
111
164
|
]}
|
|
112
|
-
|
|
165
|
+
.needles=${[
|
|
113
166
|
{
|
|
114
167
|
angle: 90 + this.pitch,
|
|
115
|
-
fillColor:
|
|
168
|
+
fillColor: this.indicatorColor,
|
|
116
169
|
strokeColor: "var(--border-silhouette-color)"
|
|
117
170
|
}
|
|
118
171
|
]}
|
|
119
|
-
|
|
172
|
+
.vessels=${opposite || this.zoomToFitArc || this.hasReadout ? [] : [
|
|
120
173
|
{
|
|
121
174
|
size: VesselImageSize.large,
|
|
122
175
|
vesselImage: this.vesselImageSide,
|
|
123
176
|
transform: `rotate(${this.pitch}deg)`
|
|
124
177
|
}
|
|
125
178
|
]}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
type: TickmarkType.main
|
|
130
|
-
}
|
|
131
|
-
]}
|
|
132
|
-
.advices=${this.advices}
|
|
133
|
-
></obc-watch>
|
|
134
|
-
</div>
|
|
179
|
+
.tickmarks=${[{ angle: 90, type: TickmarkType.main }]}
|
|
180
|
+
.advices=${this.advices}
|
|
181
|
+
></obc-watch>
|
|
135
182
|
`;
|
|
136
183
|
}
|
|
137
184
|
get advices() {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
185
|
+
if (this.maxPitchAdvice === void 0) {
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
const arcAngle = normalizeArcAngle(this.arcAngle, 45);
|
|
189
|
+
const outer = Math.min(arcAngle, 30);
|
|
190
|
+
const inner = Math.min(this.maxPitchAdvice, outer);
|
|
191
|
+
const state = this.triggerPitchAdvice ? AdviceState.triggered : AdviceState.regular;
|
|
192
|
+
return [
|
|
193
|
+
{
|
|
145
194
|
minAngle: 90 - outer,
|
|
146
195
|
maxAngle: 90 - inner,
|
|
147
196
|
type: AdviceType.caution,
|
|
148
197
|
state,
|
|
149
198
|
hideMinTickmark: true
|
|
150
|
-
}
|
|
151
|
-
|
|
199
|
+
},
|
|
200
|
+
{
|
|
152
201
|
minAngle: 90 + inner,
|
|
153
202
|
maxAngle: 90 + outer,
|
|
154
203
|
type: AdviceType.caution,
|
|
155
204
|
state,
|
|
156
205
|
hideMaxTickmark: true
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return advices;
|
|
206
|
+
}
|
|
207
|
+
];
|
|
160
208
|
}
|
|
161
209
|
};
|
|
162
210
|
ObcPitch.styles = css`
|
|
@@ -177,6 +225,16 @@ ObcPitch.styles = css`
|
|
|
177
225
|
width: 100%;
|
|
178
226
|
height: 100%;
|
|
179
227
|
}
|
|
228
|
+
|
|
229
|
+
.readout {
|
|
230
|
+
display: flex;
|
|
231
|
+
align-items: center;
|
|
232
|
+
justify-content: center;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.scale-opposite {
|
|
236
|
+
transform: rotate(180deg);
|
|
237
|
+
}
|
|
180
238
|
`;
|
|
181
239
|
__decorateClass([
|
|
182
240
|
property({ type: Number })
|
|
@@ -199,6 +257,15 @@ __decorateClass([
|
|
|
199
257
|
__decorateClass([
|
|
200
258
|
property({ type: Boolean })
|
|
201
259
|
], ObcPitch.prototype, "zoomToFitArc", 2);
|
|
260
|
+
__decorateClass([
|
|
261
|
+
property({ type: Boolean })
|
|
262
|
+
], ObcPitch.prototype, "hasReadout", 2);
|
|
263
|
+
__decorateClass([
|
|
264
|
+
property({ type: String })
|
|
265
|
+
], ObcPitch.prototype, "type", 2);
|
|
266
|
+
__decorateClass([
|
|
267
|
+
property({ type: String })
|
|
268
|
+
], ObcPitch.prototype, "priority", 2);
|
|
202
269
|
__decorateClass([
|
|
203
270
|
property({ type: Number })
|
|
204
271
|
], ObcPitch.prototype, "arcAngle", 2);
|
|
@@ -206,6 +273,7 @@ ObcPitch = __decorateClass([
|
|
|
206
273
|
customElement("obc-pitch")
|
|
207
274
|
], ObcPitch);
|
|
208
275
|
export {
|
|
209
|
-
ObcPitch
|
|
276
|
+
ObcPitch,
|
|
277
|
+
ObcPitchType
|
|
210
278
|
};
|
|
211
279
|
//# sourceMappingURL=pitch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pitch.js","sources":["../../../src/navigation-instruments/pitch/pitch.ts"],"sourcesContent":["import {LitElement, css, html, nothing, svg} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {\n VesselImage,\n VesselImageSize,\n WatchCircleType,\n OUTER_RING_RADIUS,\n innerRingRadiusFor,\n vesselImages,\n} from '../watch/watch.js';\nimport {TickmarkType} from '../watch/tickmark.js';\nimport {AdviceState, AdviceType, AngleAdviceRaw} from '../watch/advice.js';\nimport {customElement} from '../../decorator.js';\nimport {\n computeZoomToFitArcFrame,\n normalizeArcAngle,\n shiftArcFrameToOuterEdge,\n type ZoomToFitArcFrame,\n} from '../../svghelpers/arc-frame.js';\n\nconst watchRadius = OUTER_RING_RADIUS;\n/** Half-side of the centre overlay viewBox in SVG units. */\nconst CENTRE_HALF = 200;\n\n@customElement('obc-pitch')\nexport class ObcPitch extends LitElement {\n @property({type: Number}) pitch = 0;\n @property({type: Number}) minAvgPitch = 0;\n @property({type: Number}) maxAvgPitch = 0;\n @property({type: String}) vesselImageSide: VesselImage = VesselImage.psvSide;\n @property({type: Number}) maxPitchAdvice: number | undefined = undefined;\n @property({type: Boolean}) triggerPitchAdvice = false;\n @property({type: Boolean}) zoomToFitArc: boolean = false;\n /**\n * Half-extent of the watch arc in degrees. The arc spans `90° ± arcAngle`\n * and pitch values are placed at their true position within it. Default\n * `45` reproduces the historical 90°-wide arc.\n *\n * Smaller values render a narrower arc. Combined with `zoomToFitArc`, the\n * narrower arc is enlarged (its radius grows) on its own layer, while the\n * vessel image and the rotating indicator line stay at their natural size\n * and position on a separate central layer. The two layers are\n * intentionally visually disconnected.\n */\n @property({type: Number}) arcAngle: number = 45;\n\n private _arcFrame: ZoomToFitArcFrame | undefined;\n\n override render() {\n const arcAngle = normalizeArcAngle(this.arcAngle, 45);\n // Outer thin-ring complement endpoints. The arc band is centred at\n // watch angle 90° (right side) and spans 90° ± arcAngle, so its edges\n // sit at SVG coords (R·cos(arcAngle), ±R·sin(arcAngle)).\n const x = watchRadius * Math.cos((arcAngle * Math.PI) / 180);\n const y = watchRadius * Math.sin((arcAngle * Math.PI) / 180);\n\n const areas = [\n {\n startAngle: 90 - arcAngle,\n endAngle: 90 + arcAngle,\n roundOutsideCut: true,\n roundInsideCut: true,\n },\n ];\n\n if (this.zoomToFitArc) {\n const ext = 48;\n const targetSize = (176 + ext) * 2;\n // Pure arc-only fit (compass-sector style). The viewBox is centred on\n // the enlarged arc bbox, so the origin (centre of the instrument) is\n // typically OUTSIDE this viewBox. The vessel and central elements\n // therefore need their own normal-scale layer.\n const baseFrame = computeZoomToFitArcFrame({\n areas,\n outerRadius: OUTER_RING_RADIUS,\n innerRadius: innerRingRadiusFor(WatchCircleType.double),\n extension: ext,\n targetSize,\n });\n // Push the enlarged arc to the side so its outer edge aligns with the\n // central layer's outer ring. Direction is derived from the arc bbox\n // centre so left/right/top/bottom is handled automatically.\n this._arcFrame = shiftArcFrameToOuterEdge(\n baseFrame,\n OUTER_RING_RADIUS + baseFrame.radiusOffset,\n OUTER_RING_RADIUS,\n CENTRE_HALF\n );\n } else {\n this._arcFrame = undefined;\n }\n\n const needleTransform = `rotate(${this.pitch} 0 0)`;\n const centreViewBox = `-${CENTRE_HALF} -${CENTRE_HALF} ${CENTRE_HALF * 2} ${CENTRE_HALF * 2}`;\n const vesselScale = 224 / 160;\n\n return html`\n <div class=\"container\">\n <svg viewBox=\"${centreViewBox}\">\n ${svg`\n <line\n x1=\"-${watchRadius}\"\n y1=\"0\"\n x2=\"${watchRadius}\"\n y2=\"0\"\n stroke=\"var(--instrument-frame-tertiary-color)\"\n />\n <line\n x1=\"0\"\n y1=\"0\"\n x2=\"${watchRadius - 10}\"\n y2=\"0\"\n stroke=\"var(--instrument-enhanced-secondary-color)\"\n transform=\"${needleTransform}\"\n />\n <g\n style=\"transform: rotate(${this.pitch}deg) scale(${vesselScale}) translate(-80px, -80px);\"\n >\n ${vesselImages[this.vesselImageSide]}\n </g>\n ${\n this.zoomToFitArc\n ? nothing\n : svg`\n <path\n d=\"M ${x} ${y} A ${watchRadius} ${watchRadius} 0 1 1 ${x} ${-y}\"\n fill=\"none\"\n stroke=\"var(--instrument-frame-tertiary-color)\"\n />\n `\n }\n `}\n </svg>\n <obc-watch\n .watchCircleType=${WatchCircleType.double}\n .zoomToFitArc=${this.zoomToFitArc}\n .arcFrame=${this._arcFrame}\n .areas=${areas}\n .barAreas=${[\n {\n startAngle: 90 + this.minAvgPitch,\n endAngle: 90 + this.maxAvgPitch,\n fillColor: 'var(--instrument-enhanced-tertiary-color)',\n },\n ]}\n .needles=${[\n {\n angle: 90 + this.pitch,\n fillColor: 'var(--instrument-enhanced-secondary-color)',\n strokeColor: 'var(--border-silhouette-color)',\n },\n ]}\n .vessels=${this.zoomToFitArc\n ? []\n : [\n {\n size: VesselImageSize.large,\n vesselImage: this.vesselImageSide,\n transform: `rotate(${this.pitch}deg)`,\n },\n ]}\n .tickmarks=${[\n {\n angle: 90,\n type: TickmarkType.main,\n },\n ]}\n .advices=${this.advices}\n ></obc-watch>\n </div>\n `;\n }\n\n private get advices(): AngleAdviceRaw[] {\n const advices = [];\n if (this.maxPitchAdvice !== undefined) {\n const arcAngle = normalizeArcAngle(this.arcAngle, 45);\n // Caution band fills the remainder of the arc out to a default 30°\n // caution range (clamped to the arc edge).\n const outer = Math.min(arcAngle, 30);\n const inner = Math.min(this.maxPitchAdvice, outer);\n const state = this.triggerPitchAdvice\n ? AdviceState.triggered\n : AdviceState.regular;\n advices.push({\n minAngle: 90 - outer,\n maxAngle: 90 - inner,\n type: AdviceType.caution,\n state: state,\n hideMinTickmark: true,\n });\n advices.push({\n minAngle: 90 + inner,\n maxAngle: 90 + outer,\n type: AdviceType.caution,\n state: state,\n hideMaxTickmark: true,\n });\n }\n return advices;\n }\n\n static override styles = css`\n * {\n box-sizing: border-box;\n }\n\n .container {\n position: relative;\n width: 100%;\n height: 100%;\n }\n\n .container > * {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-pitch': ObcPitch;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,MAAM,cAAc;AAEpB,MAAM,cAAc;AAGb,IAAM,WAAN,cAAuB,WAAW;AAAA,EAAlC,cAAA;AAAA,UAAA,GAAA,SAAA;AACqB,SAAA,QAAQ;AACR,SAAA,cAAc;AACd,SAAA,cAAc;AACd,SAAA,kBAA+B,YAAY;AAC3C,SAAA,iBAAqC;AACpC,SAAA,qBAAqB;AACrB,SAAA,eAAwB;AAYzB,SAAA,WAAmB;AAAA,EAAA;AAAA,EAIpC,SAAS;AAChB,UAAM,WAAW,kBAAkB,KAAK,UAAU,EAAE;AAIpD,UAAM,IAAI,cAAc,KAAK,IAAK,WAAW,KAAK,KAAM,GAAG;AAC3D,UAAM,IAAI,cAAc,KAAK,IAAK,WAAW,KAAK,KAAM,GAAG;AAE3D,UAAM,QAAQ;AAAA,MACZ;AAAA,QACE,YAAY,KAAK;AAAA,QACjB,UAAU,KAAK;AAAA,QACf,iBAAiB;AAAA,QACjB,gBAAgB;AAAA,MAAA;AAAA,IAClB;AAGF,QAAI,KAAK,cAAc;AACrB,YAAM,MAAM;AACZ,YAAM,cAAc,MAAM,OAAO;AAKjC,YAAM,YAAY,yBAAyB;AAAA,QACzC;AAAA,QACA,aAAa;AAAA,QACb,aAAa,mBAAmB,gBAAgB,MAAM;AAAA,QACtD,WAAW;AAAA,QACX;AAAA,MAAA,CACD;AAID,WAAK,YAAY;AAAA,QACf;AAAA,QACA,oBAAoB,UAAU;AAAA,QAC9B;AAAA,QACA;AAAA,MAAA;AAAA,IAEJ,OAAO;AACL,WAAK,YAAY;AAAA,IACnB;AAEA,UAAM,kBAAkB,UAAU,KAAK,KAAK;AAC5C,UAAM,gBAAgB,IAAI,WAAW,KAAK,WAAW,IAAI,cAAc,CAAC,IAAI,cAAc,CAAC;AAC3F,UAAM,cAAc,MAAM;AAE1B,WAAO;AAAA;AAAA,wBAEa,aAAa;AAAA,YACzB;AAAA;AAAA,qBAES,WAAW;AAAA;AAAA,oBAEZ,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAOX,cAAc,EAAE;AAAA;AAAA;AAAA,2BAGT,eAAe;AAAA;AAAA;AAAA,yCAGD,KAAK,KAAK,cAAc,WAAW;AAAA;AAAA,gBAE5D,aAAa,KAAK,eAAe,CAAC;AAAA;AAAA,cAGpC,KAAK,eACD,UACA;AAAA;AAAA,6BAEW,CAAC,IAAI,CAAC,MAAM,WAAW,IAAI,WAAW,UAAU,CAAC,IAAI,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA,mBAKxE;AAAA,WACD;AAAA;AAAA;AAAA,6BAGkB,gBAAgB,MAAM;AAAA,0BACzB,KAAK,YAAY;AAAA,sBACrB,KAAK,SAAS;AAAA,mBACjB,KAAK;AAAA,sBACF;AAAA,MACV;AAAA,QACE,YAAY,KAAK,KAAK;AAAA,QACtB,UAAU,KAAK,KAAK;AAAA,QACpB,WAAW;AAAA,MAAA;AAAA,IACb,CACD;AAAA,qBACU;AAAA,MACT;AAAA,QACE,OAAO,KAAK,KAAK;AAAA,QACjB,WAAW;AAAA,QACX,aAAa;AAAA,MAAA;AAAA,IACf,CACD;AAAA,qBACU,KAAK,eACZ,KACA;AAAA,MACE;AAAA,QACE,MAAM,gBAAgB;AAAA,QACtB,aAAa,KAAK;AAAA,QAClB,WAAW,UAAU,KAAK,KAAK;AAAA,MAAA;AAAA,IACjC,CACD;AAAA,uBACQ;AAAA,MACX;AAAA,QACE,OAAO;AAAA,QACP,MAAM,aAAa;AAAA,MAAA;AAAA,IACrB,CACD;AAAA,qBACU,KAAK,OAAO;AAAA;AAAA;AAAA;AAAA,EAI/B;AAAA,EAEA,IAAY,UAA4B;AACtC,UAAM,UAAU,CAAA;AAChB,QAAI,KAAK,mBAAmB,QAAW;AACrC,YAAM,WAAW,kBAAkB,KAAK,UAAU,EAAE;AAGpD,YAAM,QAAQ,KAAK,IAAI,UAAU,EAAE;AACnC,YAAM,QAAQ,KAAK,IAAI,KAAK,gBAAgB,KAAK;AACjD,YAAM,QAAQ,KAAK,qBACf,YAAY,YACZ,YAAY;AAChB,cAAQ,KAAK;AAAA,QACX,UAAU,KAAK;AAAA,QACf,UAAU,KAAK;AAAA,QACf,MAAM,WAAW;AAAA,QACjB;AAAA,QACA,iBAAiB;AAAA,MAAA,CAClB;AACD,cAAQ,KAAK;AAAA,QACX,UAAU,KAAK;AAAA,QACf,UAAU,KAAK;AAAA,QACf,MAAM,WAAW;AAAA,QACjB;AAAA,QACA,iBAAiB;AAAA,MAAA,CAClB;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAqBF;AApMa,SAiLK,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAhLC,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GADb,SACe,WAAA,SAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAFb,SAEe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAHb,SAGe,WAAA,eAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAJb,SAIe,WAAA,mBAAA,CAAA;AACA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GALb,SAKe,WAAA,kBAAA,CAAA;AACC,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GANd,SAMgB,WAAA,sBAAA,CAAA;AACA,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAPd,SAOgB,WAAA,gBAAA,CAAA;AAYD,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAnBb,SAmBe,WAAA,YAAA,CAAA;AAnBf,WAAN,gBAAA;AAAA,EADN,cAAc,WAAW;AAAA,GACb,QAAA;"}
|
|
1
|
+
{"version":3,"file":"pitch.js","sources":["../../../src/navigation-instruments/pitch/pitch.ts"],"sourcesContent":["import {LitElement, css, html, nothing, svg} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {\n VesselImage,\n VesselImageSize,\n WatchCircleType,\n OUTER_RING_RADIUS,\n innerRingRadiusFor,\n vesselImages,\n type WatchArea,\n} from '../watch/watch.js';\nimport '../readout/readout.js';\nimport {ReadoutDirection, ReadoutVariant} from '../readout/readout.js';\nimport {Priority} from '../types.js';\nimport {TickmarkType} from '../watch/tickmark.js';\nimport {AdviceState, AdviceType, AngleAdviceRaw} from '../watch/advice.js';\nimport {customElement} from '../../decorator.js';\nimport {\n computeZoomToFitArcFrame,\n normalizeArcAngle,\n shiftArcFrameToOuterEdge,\n type ZoomToFitArcFrame,\n} from '../../svghelpers/arc-frame.js';\n\nconst watchRadius = OUTER_RING_RADIUS;\n/** Half-side of the centre overlay viewBox in SVG units. */\nconst CENTRE_HALF = 200;\n\nexport enum ObcPitchType {\n /** Single arc scale on the right (default). */\n singleScale = 'single-scale',\n /** Right scale duplicated to the opposite (left) arc as well. */\n dualScale = 'dual-scale',\n}\n\n/**\n * `<obc-pitch>` — Pitch (trim) indicator with a side arc scale.\n *\n * Shows `pitch` against a watch arc centred on the right, with an average-pitch\n * band and a rotating indicator. Supports an optional opposite-side scale\n * (`dual-scale`), a centre readout (`hasReadout`), and a `regular`/`enhanced`\n * palette.\n *\n * @element obc-pitch\n */\n@customElement('obc-pitch')\nexport class ObcPitch extends LitElement {\n @property({type: Number}) pitch = 0;\n @property({type: Number}) minAvgPitch = 0;\n @property({type: Number}) maxAvgPitch = 0;\n @property({type: String}) vesselImageSide: VesselImage = VesselImage.psvSide;\n @property({type: Number}) maxPitchAdvice: number | undefined = undefined;\n @property({type: Boolean}) triggerPitchAdvice = false;\n @property({type: Boolean}) zoomToFitArc: boolean = false;\n /**\n * When `true`, the centre shows an `<obc-readout>` with the pitch value\n * (label `Pitch`, unit `DEG`) instead of the horizon line, rotating indicator\n * and vessel. Default `false`.\n */\n @property({type: Boolean}) hasReadout: boolean = false;\n /**\n * `single-scale` shows one arc on the right (default); `dual-scale` also\n * shows the scale on the opposite (left) arc (the indicator's opposite end).\n */\n @property({type: String}) type: ObcPitchType = ObcPitchType.singleScale;\n /**\n * Colour palette for the scale fill / indicator and the readout value:\n * `regular` (default) or `enhanced`.\n */\n @property({type: String}) priority: Priority = Priority.regular;\n /**\n * Half-extent of the watch arc in degrees. The arc spans `90° ± arcAngle`\n * and pitch values are placed at their true position within it. Default\n * `45` reproduces the historical 90°-wide arc.\n *\n * Smaller values render a narrower arc. Combined with `zoomToFitArc`, the\n * narrower arc is enlarged (its radius grows) on its own layer, while the\n * vessel image and the rotating indicator line stay at their natural size\n * and position on a separate central layer. The two layers are\n * intentionally visually disconnected.\n */\n @property({type: Number}) arcAngle: number = 45;\n\n private _arcFrame: ZoomToFitArcFrame | undefined;\n\n private get scaleFillColor(): string {\n return this.priority === Priority.enhanced\n ? 'var(--instrument-enhanced-tertiary-color)'\n : 'var(--instrument-regular-tertiary-color)';\n }\n\n private get indicatorColor(): string {\n return this.priority === Priority.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : 'var(--instrument-regular-secondary-color)';\n }\n\n override render() {\n const arcAngle = normalizeArcAngle(this.arcAngle, 45);\n // Outer thin-ring complement endpoints. The arc band is centred at\n // watch angle 90° (right side) and spans 90° ± arcAngle, so its edges\n // sit at SVG coords (R·cos(arcAngle), ±R·sin(arcAngle)).\n const x = watchRadius * Math.cos((arcAngle * Math.PI) / 180);\n const y = watchRadius * Math.sin((arcAngle * Math.PI) / 180);\n\n const areas: WatchArea[] = [\n {\n startAngle: 90 - arcAngle,\n endAngle: 90 + arcAngle,\n roundOutsideCut: true,\n roundInsideCut: true,\n },\n ];\n\n if (this.zoomToFitArc) {\n const ext = 48;\n const targetSize = (176 + ext) * 2;\n // Pure arc-only fit (compass-sector style). The viewBox is centred on\n // the enlarged arc bbox, so the origin (centre of the instrument) is\n // typically OUTSIDE this viewBox. The vessel and central elements\n // therefore need their own normal-scale layer.\n const baseFrame = computeZoomToFitArcFrame({\n areas,\n outerRadius: OUTER_RING_RADIUS,\n innerRadius: innerRingRadiusFor(WatchCircleType.double),\n extension: ext,\n targetSize,\n });\n // Push the enlarged arc to the side so its outer edge aligns with the\n // central layer's outer ring. Direction is derived from the arc bbox\n // centre so left/right/top/bottom is handled automatically.\n this._arcFrame = shiftArcFrameToOuterEdge(\n baseFrame,\n OUTER_RING_RADIUS + baseFrame.radiusOffset,\n OUTER_RING_RADIUS,\n CENTRE_HALF\n );\n } else {\n this._arcFrame = undefined;\n }\n\n const needleTransform = `rotate(${this.pitch} 0 0)`;\n const centreViewBox = `-${CENTRE_HALF} -${CENTRE_HALF} ${CENTRE_HALF * 2} ${CENTRE_HALF * 2}`;\n const vesselScale = 224 / 160;\n\n return html`\n <div class=\"container\">\n <svg viewBox=\"${centreViewBox}\">\n ${this.hasReadout\n ? nothing\n : svg`\n <line\n x1=\"-${watchRadius}\"\n y1=\"0\"\n x2=\"${watchRadius}\"\n y2=\"0\"\n stroke=\"var(--instrument-frame-tertiary-color)\"\n />\n <line\n x1=\"0\"\n y1=\"0\"\n x2=\"${watchRadius - 10}\"\n y2=\"0\"\n stroke=\"${this.indicatorColor}\"\n transform=\"${needleTransform}\"\n />\n <g\n style=\"transform: rotate(${this.pitch}deg) scale(${vesselScale}) translate(-80px, -80px);\"\n >\n ${this.zoomToFitArc ? vesselImages[this.vesselImageSide] : nothing}\n </g>\n `}\n ${this.zoomToFitArc\n ? nothing\n : this.type === ObcPitchType.dualScale\n ? svg`\n <path\n d=\"M ${x} ${-y} A ${watchRadius} ${watchRadius} 0 0 0 ${-x} ${-y}\"\n fill=\"none\"\n stroke=\"var(--instrument-frame-tertiary-color)\"\n />\n <path\n d=\"M ${x} ${y} A ${watchRadius} ${watchRadius} 0 0 1 ${-x} ${y}\"\n fill=\"none\"\n stroke=\"var(--instrument-frame-tertiary-color)\"\n />\n `\n : svg`\n <path\n d=\"M ${x} ${y} A ${watchRadius} ${watchRadius} 0 1 1 ${x} ${-y}\"\n fill=\"none\"\n stroke=\"var(--instrument-frame-tertiary-color)\"\n />\n `}\n </svg>\n ${this.renderScale(areas, false)}\n ${this.type === ObcPitchType.dualScale\n ? this.renderScale(areas, true)\n : nothing}\n ${this.hasReadout\n ? html`<div class=\"readout\">\n <obc-readout\n .variant=${ReadoutVariant.enhanced}\n .direction=${ReadoutDirection.vertical}\n .hasSetpoint=${false}\n .hasAdvice=${false}\n .value=${this.pitch}\n .fractionDigits=${0}\n .valuePriority=${this.priority}\n label=\"Pitch\"\n unit=\"DEG\"\n ></obc-readout>\n </div>`\n : nothing}\n </div>\n `;\n }\n\n // `opposite` rotates a second watch 180° onto the opposite (left) arc for\n // dual-scale — a rotation (opposite end of the indicator), not a mirror. A\n // separate watch keeps the zoomed `arcFrame` correct.\n private renderScale(areas: WatchArea[], opposite: boolean) {\n return html`\n <obc-watch\n class=${opposite ? 'scale-opposite' : nothing}\n .priority=${this.priority}\n .watchCircleType=${WatchCircleType.double}\n .zoomToFitArc=${this.zoomToFitArc}\n .arcFrame=${this._arcFrame}\n tickmarksInside\n .areas=${areas}\n .barAreas=${[\n {\n startAngle: 90 + this.minAvgPitch,\n endAngle: 90 + this.maxAvgPitch,\n fillColor: this.scaleFillColor,\n },\n ]}\n .needles=${[\n {\n angle: 90 + this.pitch,\n fillColor: this.indicatorColor,\n strokeColor: 'var(--border-silhouette-color)',\n },\n ]}\n .vessels=${opposite || this.zoomToFitArc || this.hasReadout\n ? []\n : [\n {\n size: VesselImageSize.large,\n vesselImage: this.vesselImageSide,\n transform: `rotate(${this.pitch}deg)`,\n },\n ]}\n .tickmarks=${[{angle: 90, type: TickmarkType.main}]}\n .advices=${this.advices}\n ></obc-watch>\n `;\n }\n\n private get advices(): AngleAdviceRaw[] {\n if (this.maxPitchAdvice === undefined) {\n return [];\n }\n const arcAngle = normalizeArcAngle(this.arcAngle, 45);\n // Caution band fills the remainder of the arc out to a default 30° caution\n // range (clamped to the arc edge).\n const outer = Math.min(arcAngle, 30);\n const inner = Math.min(this.maxPitchAdvice, outer);\n const state = this.triggerPitchAdvice\n ? AdviceState.triggered\n : AdviceState.regular;\n return [\n {\n minAngle: 90 - outer,\n maxAngle: 90 - inner,\n type: AdviceType.caution,\n state: state,\n hideMinTickmark: true,\n },\n {\n minAngle: 90 + inner,\n maxAngle: 90 + outer,\n type: AdviceType.caution,\n state: state,\n hideMaxTickmark: true,\n },\n ];\n }\n\n static override styles = css`\n * {\n box-sizing: border-box;\n }\n\n .container {\n position: relative;\n width: 100%;\n height: 100%;\n }\n\n .container > * {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n }\n\n .readout {\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .scale-opposite {\n transform: rotate(180deg);\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-pitch': ObcPitch;\n }\n}\n"],"names":["ObcPitchType"],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@ import { LitElement } from 'lit';
|
|
|
2
2
|
import { VesselImage } from '../watch/watch.js';
|
|
3
3
|
import { Priority } from '../types.js';
|
|
4
4
|
import '../watch/watch.js';
|
|
5
|
+
import '../readout/readout.js';
|
|
5
6
|
export declare enum PitchRollPriorityElement {
|
|
6
7
|
pitch = "pitch",
|
|
7
8
|
roll = "roll"
|
|
@@ -22,6 +23,11 @@ export declare class ObcPitchRoll extends LitElement {
|
|
|
22
23
|
triggerRollAdvice: boolean;
|
|
23
24
|
priority: Priority;
|
|
24
25
|
priorityElements: PitchRollPriorityElement[];
|
|
26
|
+
/**
|
|
27
|
+
* When `true`, the centre shows two stacked `<obc-readout>`s (pitch above
|
|
28
|
+
* roll) instead of the vessel images. Default `false`.
|
|
29
|
+
*/
|
|
30
|
+
hasReadout: boolean;
|
|
25
31
|
zoomToFitArc: boolean;
|
|
26
32
|
/**
|
|
27
33
|
* Half-extent of each of the four watch arcs in degrees, measured from the
|
|
@@ -50,6 +56,7 @@ export declare class ObcPitchRoll extends LitElement {
|
|
|
50
56
|
private get requestedPitchArcAngle();
|
|
51
57
|
private get requestedRollArcAngle();
|
|
52
58
|
render(): import('lit-html').TemplateResult<1>;
|
|
59
|
+
private renderReadout;
|
|
53
60
|
/**
|
|
54
61
|
* Zoomed-arc layer: four CSS-rotated `<obc-watch>` instances, each
|
|
55
62
|
* containing a single arc rendered at the watch's natural top
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pitch-roll.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/pitch-roll/pitch-roll.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA0B,MAAM,KAAK,CAAC;AAExD,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EAOZ,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"pitch-roll.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/pitch-roll/pitch-roll.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA0B,MAAM,KAAK,CAAC;AAExD,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EAOZ,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AACrC,OAAO,uBAAuB,CAAC;AAQ/B,oBAAY,wBAAwB;IAClC,KAAK,UAAU;IACf,IAAI,SAAS;CACd;AAqBD,qBACa,YAAa,SAAQ,UAAU;IAChB,KAAK,SAAK;IACV,IAAI,SAAK;IACT,WAAW,SAAK;IAChB,WAAW,SAAK;IAChB,UAAU,SAAK;IACf,UAAU,SAAK;IACf,eAAe,EAAE,WAAW,CAAuB;IACnD,eAAe,EAAE,WAAW,CAAuB;IACnD,cAAc,SAAK;IACnB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAa;IAC/C,aAAa,EAAE,MAAM,GAAG,SAAS,CAAa;IAC7C,kBAAkB,UAAS;IAC3B,iBAAiB,UAAS;IAC3B,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,gBAAgB,EAAE,wBAAwB,EAAE,CAG1C;IACF;;;OAGG;IACwB,UAAU,EAAE,OAAO,CAAS;IAC5B,YAAY,EAAE,OAAO,CAAS;IACzD;;;;;;OAMG;IACuB,QAAQ,EAAE,MAAM,CAAM;IAChD;;;;OAIG;IACuB,aAAa,CAAC,EAAE,MAAM,CAAC;IACjD;;;OAGG;IACuB,YAAY,CAAC,EAAE,MAAM,CAAC;IAEhD,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,QAAQ;IAMhB,OAAO,KAAK,wBAAwB,GAKnC;IAED,kEAAkE;IAClE,OAAO,KAAK,sBAAsB,GAEjC;IACD,OAAO,KAAK,qBAAqB,GAEhC;IAEQ,MAAM;IAkFf,OAAO,CAAC,aAAa;IAoBrB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,OAAO,CAAC,gBAAgB;IA6RxB;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IA8BlB,6DAA6D;IAC7D,OAAO,CAAC,eAAe;IA2EvB,OAAO,KAAK,OAAO,GA2ElB;IAED,OAAgB,MAAM,0BAqCpB;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,gBAAgB,EAAE,YAAY,CAAC;KAChC;CACF"}
|
|
@@ -5,6 +5,7 @@ import { TickmarkType } from "../watch/tickmark.js";
|
|
|
5
5
|
import { AdviceState, AdviceType } from "../watch/advice.js";
|
|
6
6
|
import { customElement } from "../../decorator.js";
|
|
7
7
|
import { Priority } from "../types.js";
|
|
8
|
+
import { ReadoutVariant, ReadoutDirection } from "../readout/readout.js";
|
|
8
9
|
import { normalizeArcAngle, computeZoomToFitArcFrame, shiftArcFrameToOuterEdge } from "../../svghelpers/arc-frame.js";
|
|
9
10
|
import { VesselImage, vesselImages, VesselImageSize } from "../watch/vessel.js";
|
|
10
11
|
var __defProp = Object.defineProperty;
|
|
@@ -47,6 +48,7 @@ let ObcPitchRoll = class extends LitElement {
|
|
|
47
48
|
"roll"
|
|
48
49
|
/* roll */
|
|
49
50
|
];
|
|
51
|
+
this.hasReadout = false;
|
|
50
52
|
this.zoomToFitArc = false;
|
|
51
53
|
this.arcAngle = 30;
|
|
52
54
|
}
|
|
@@ -107,7 +109,7 @@ let ObcPitchRoll = class extends LitElement {
|
|
|
107
109
|
return html`
|
|
108
110
|
<div class="container">
|
|
109
111
|
<svg viewBox="${overlayViewBox}">
|
|
110
|
-
${svg`
|
|
112
|
+
${this.hasReadout ? nothing : svg`
|
|
111
113
|
<line
|
|
112
114
|
x1="-150"
|
|
113
115
|
y1="0"
|
|
@@ -128,9 +130,41 @@ let ObcPitchRoll = class extends LitElement {
|
|
|
128
130
|
`}
|
|
129
131
|
</svg>
|
|
130
132
|
${this.zoomToFitArc ? this.renderZoomedArcs(pitchReq, rollReq) : this.renderFullWatch(areas)}
|
|
133
|
+
${this.hasReadout ? html`<div class="readout">
|
|
134
|
+
<div class="readout-group">
|
|
135
|
+
${this.renderReadout(
|
|
136
|
+
this.pitch,
|
|
137
|
+
"Pitch",
|
|
138
|
+
"pitch"
|
|
139
|
+
/* pitch */
|
|
140
|
+
)}
|
|
141
|
+
<div class="readout-divider"></div>
|
|
142
|
+
${this.renderReadout(
|
|
143
|
+
this.roll,
|
|
144
|
+
"Roll",
|
|
145
|
+
"roll"
|
|
146
|
+
/* roll */
|
|
147
|
+
)}
|
|
148
|
+
</div>
|
|
149
|
+
</div>` : nothing}
|
|
131
150
|
</div>
|
|
132
151
|
`;
|
|
133
152
|
}
|
|
153
|
+
renderReadout(value, label, element) {
|
|
154
|
+
return html`
|
|
155
|
+
<obc-readout
|
|
156
|
+
.variant=${ReadoutVariant.enhanced}
|
|
157
|
+
.direction=${ReadoutDirection.vertical}
|
|
158
|
+
.hasSetpoint=${false}
|
|
159
|
+
.hasAdvice=${false}
|
|
160
|
+
.value=${value}
|
|
161
|
+
.fractionDigits=${0}
|
|
162
|
+
.valuePriority=${this.priorityFor(element)}
|
|
163
|
+
label=${label}
|
|
164
|
+
unit="DEG"
|
|
165
|
+
></obc-readout>
|
|
166
|
+
`;
|
|
167
|
+
}
|
|
134
168
|
/**
|
|
135
169
|
* Zoomed-arc layer: four CSS-rotated `<obc-watch>` instances, each
|
|
136
170
|
* containing a single arc rendered at the watch's natural top
|
|
@@ -460,7 +494,7 @@ let ObcPitchRoll = class extends LitElement {
|
|
|
460
494
|
strokeColor: "var(--border-silhouette-color)"
|
|
461
495
|
}
|
|
462
496
|
]}
|
|
463
|
-
.vessels=${[
|
|
497
|
+
.vessels=${this.hasReadout ? [] : [
|
|
464
498
|
{
|
|
465
499
|
size: VesselImageSize.large,
|
|
466
500
|
vesselImage: this.vesselImageSide,
|
|
@@ -573,6 +607,25 @@ ObcPitchRoll.styles = css`
|
|
|
573
607
|
width: 100%;
|
|
574
608
|
height: 100%;
|
|
575
609
|
}
|
|
610
|
+
|
|
611
|
+
.readout {
|
|
612
|
+
display: flex;
|
|
613
|
+
align-items: center;
|
|
614
|
+
justify-content: center;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
.readout-group {
|
|
618
|
+
display: flex;
|
|
619
|
+
flex-direction: column;
|
|
620
|
+
align-items: center;
|
|
621
|
+
width: fit-content;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
.readout-divider {
|
|
625
|
+
align-self: stretch;
|
|
626
|
+
height: 1px;
|
|
627
|
+
background: var(--border-divider-color);
|
|
628
|
+
}
|
|
576
629
|
`;
|
|
577
630
|
__decorateClass([
|
|
578
631
|
property({ type: Number })
|
|
@@ -619,6 +672,9 @@ __decorateClass([
|
|
|
619
672
|
__decorateClass([
|
|
620
673
|
property({ type: Array, attribute: false })
|
|
621
674
|
], ObcPitchRoll.prototype, "priorityElements", 2);
|
|
675
|
+
__decorateClass([
|
|
676
|
+
property({ type: Boolean })
|
|
677
|
+
], ObcPitchRoll.prototype, "hasReadout", 2);
|
|
622
678
|
__decorateClass([
|
|
623
679
|
property({ type: Boolean })
|
|
624
680
|
], ObcPitchRoll.prototype, "zoomToFitArc", 2);
|