@oicl/openbridge-webcomponents 2.0.0-next.110 → 2.0.0-next.112
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 +2370 -1522
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +641 -7
- package/dist/automation/indicator-battery/indicator-battery.css.js +52 -0
- package/dist/automation/indicator-battery/indicator-battery.css.js.map +1 -0
- package/dist/automation/indicator-battery/indicator-battery.d.ts +65 -0
- package/dist/automation/indicator-battery/indicator-battery.d.ts.map +1 -0
- package/dist/automation/indicator-battery/indicator-battery.js +119 -0
- package/dist/automation/indicator-battery/indicator-battery.js.map +1 -0
- package/dist/automation/indicator-engine/indicator-engine.css.js +45 -0
- package/dist/automation/indicator-engine/indicator-engine.css.js.map +1 -0
- package/dist/automation/indicator-engine/indicator-engine.d.ts +34 -0
- package/dist/automation/indicator-engine/indicator-engine.d.ts.map +1 -0
- package/dist/automation/indicator-engine/indicator-engine.js +73 -0
- package/dist/automation/indicator-engine/indicator-engine.js.map +1 -0
- package/dist/automation/indicator-generator/indicator-generator-geometry.d.ts +30 -0
- package/dist/automation/indicator-generator/indicator-generator-geometry.d.ts.map +1 -0
- package/dist/automation/indicator-generator/indicator-generator-geometry.js +61 -0
- package/dist/automation/indicator-generator/indicator-generator-geometry.js.map +1 -0
- package/dist/automation/indicator-generator/indicator-generator.css.js +121 -0
- package/dist/automation/indicator-generator/indicator-generator.css.js.map +1 -0
- package/dist/automation/indicator-generator/indicator-generator.d.ts +57 -0
- package/dist/automation/indicator-generator/indicator-generator.d.ts.map +1 -0
- package/dist/automation/indicator-generator/indicator-generator.js +136 -0
- package/dist/automation/indicator-generator/indicator-generator.js.map +1 -0
- package/dist/automation/indicator-shared/linear-indicator.d.ts +46 -0
- package/dist/automation/indicator-shared/linear-indicator.d.ts.map +1 -0
- package/dist/automation/indicator-shared/linear-indicator.js +175 -0
- package/dist/automation/indicator-shared/linear-indicator.js.map +1 -0
- package/dist/automation/indicator-tank-atmospheric/indicator-tank-atmospheric.css.js +48 -0
- package/dist/automation/indicator-tank-atmospheric/indicator-tank-atmospheric.css.js.map +1 -0
- package/dist/automation/indicator-tank-atmospheric/indicator-tank-atmospheric.d.ts +65 -0
- package/dist/automation/indicator-tank-atmospheric/indicator-tank-atmospheric.d.ts.map +1 -0
- package/dist/automation/indicator-tank-atmospheric/indicator-tank-atmospheric.js +105 -0
- package/dist/automation/indicator-tank-atmospheric/indicator-tank-atmospheric.js.map +1 -0
- package/dist/navigation-instruments/compass/compass.d.ts +1 -1
- package/dist/navigation-instruments/compass/compass.d.ts.map +1 -1
- package/dist/navigation-instruments/compass/compass.js +1 -1
- package/dist/navigation-instruments/compass/compass.js.map +1 -1
- package/dist/navigation-instruments/current/current.d.ts +25 -0
- package/dist/navigation-instruments/current/current.d.ts.map +1 -1
- package/dist/navigation-instruments/current/current.js +25 -4
- package/dist/navigation-instruments/current/current.js.map +1 -1
- package/dist/navigation-instruments/heading/heading.js +1 -1
- package/dist/navigation-instruments/heading/heading.js.map +1 -1
- package/dist/navigation-instruments/pitch-roll-heave/pitch-roll-heave.d.ts +6 -0
- package/dist/navigation-instruments/pitch-roll-heave/pitch-roll-heave.d.ts.map +1 -1
- package/dist/navigation-instruments/pitch-roll-heave/pitch-roll-heave.js +8 -1
- package/dist/navigation-instruments/pitch-roll-heave/pitch-roll-heave.js.map +1 -1
- package/dist/navigation-instruments/rate-of-turn/rate-of-turn.d.ts +5 -2
- 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.map +1 -1
- package/dist/navigation-instruments/top-view-propulsion/top-view-propulsion.d.ts +6 -0
- package/dist/navigation-instruments/top-view-propulsion/top-view-propulsion.d.ts.map +1 -1
- package/dist/navigation-instruments/top-view-propulsion/top-view-propulsion.js +19 -4
- package/dist/navigation-instruments/top-view-propulsion/top-view-propulsion.js.map +1 -1
- package/dist/navigation-instruments/watch/environment.d.ts +8 -0
- package/dist/navigation-instruments/watch/environment.d.ts.map +1 -1
- package/dist/navigation-instruments/watch/environment.js +3 -0
- package/dist/navigation-instruments/watch/environment.js.map +1 -1
- package/dist/navigation-instruments/watch/force-pattern.d.ts +20 -2
- package/dist/navigation-instruments/watch/force-pattern.d.ts.map +1 -1
- package/dist/navigation-instruments/watch/force-pattern.js +12 -5
- package/dist/navigation-instruments/watch/force-pattern.js.map +1 -1
- package/dist/navigation-instruments/watch/watch.d.ts.map +1 -1
- package/dist/navigation-instruments/watch/watch.js +6 -4
- package/dist/navigation-instruments/watch/watch.js.map +1 -1
- package/dist/navigation-instruments/wind/wind.d.ts +5 -2
- package/dist/navigation-instruments/wind/wind.d.ts.map +1 -1
- package/dist/navigation-instruments/wind/wind.js +5 -1
- package/dist/navigation-instruments/wind/wind.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { unsafeCSS, LitElement, nothing, html } from "lit";
|
|
2
|
+
import { property } from "lit/decorators.js";
|
|
3
|
+
import componentStyle from "./indicator-tank-atmospheric.css.js";
|
|
4
|
+
import { customElement } from "../../decorator.js";
|
|
5
|
+
import "../../icons/icon-tank.js";
|
|
6
|
+
import { IndicatorDirection, LinearIndicatorScheme, renderTrendGraph, renderLinearBar } from "../indicator-shared/linear-indicator.js";
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
10
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
11
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
12
|
+
if (decorator = decorators[i])
|
|
13
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
14
|
+
if (kind && result) __defProp(target, key, result);
|
|
15
|
+
return result;
|
|
16
|
+
};
|
|
17
|
+
var IndicatorTankAtmosphericVariant = /* @__PURE__ */ ((IndicatorTankAtmosphericVariant2) => {
|
|
18
|
+
IndicatorTankAtmosphericVariant2["bar"] = "bar";
|
|
19
|
+
IndicatorTankAtmosphericVariant2["trend"] = "trend";
|
|
20
|
+
return IndicatorTankAtmosphericVariant2;
|
|
21
|
+
})(IndicatorTankAtmosphericVariant || {});
|
|
22
|
+
var IndicatorTankAtmosphericValue = /* @__PURE__ */ ((IndicatorTankAtmosphericValue2) => {
|
|
23
|
+
IndicatorTankAtmosphericValue2["regular"] = "regular";
|
|
24
|
+
IndicatorTankAtmosphericValue2["enhanced"] = "enhanced";
|
|
25
|
+
IndicatorTankAtmosphericValue2["medium"] = "medium";
|
|
26
|
+
return IndicatorTankAtmosphericValue2;
|
|
27
|
+
})(IndicatorTankAtmosphericValue || {});
|
|
28
|
+
const HORIZONTAL_BAR = { x: 8, y: 11, width: 32, height: 26 };
|
|
29
|
+
const VERTICAL_BAR = { x: 11, y: 8, width: 26, height: 32 };
|
|
30
|
+
const HORIZONTAL_TREND = { x: 8, y: 10, width: 32, height: 28 };
|
|
31
|
+
const VERTICAL_TREND = { x: 10, y: 8, width: 28, height: 32 };
|
|
32
|
+
const FRAME_PATH = "M20.5 32.5L4.21259 32.5C3.70663 32.5 3.45364 32.5 3.09178 32.3531C2.84817 32.2542 2.44102 31.9492 2.27758 31.7433C2.0348 31.4373 1.98325 31.2615 1.88017 30.9098C1.29286 28.906 0.5 24.6852 0.5 16.5C0.5 8.31487 1.29286 4.09402 1.88016 2.09025C1.98325 1.73854 2.0348 1.56268 2.27758 1.25676C2.44102 1.0508 2.84817 0.745859 3.09178 0.646944C3.45364 0.500011 3.70662 0.500011 4.21259 0.500011L20.5 0.50001L36.7874 0.500011C37.2934 0.500011 37.5464 0.500011 37.9082 0.646943C38.1518 0.745859 38.559 1.0508 38.7224 1.25675C38.9652 1.56268 39.0167 1.73854 39.1198 2.09025C39.7071 4.09402 40.5 8.31487 40.5 16.5C40.5 24.6851 39.7071 28.906 39.1198 30.9098C39.0167 31.2615 38.9652 31.4373 38.7224 31.7433C38.559 31.9492 38.1518 32.2542 37.9082 32.3531C37.5464 32.5 37.2934 32.5 36.7874 32.5H20.5Z";
|
|
33
|
+
let ObcIndicatorTankAtmospheric = class extends LitElement {
|
|
34
|
+
constructor() {
|
|
35
|
+
super(...arguments);
|
|
36
|
+
this.direction = IndicatorDirection.vertical;
|
|
37
|
+
this.variant = "bar";
|
|
38
|
+
this.value = "regular";
|
|
39
|
+
this.level = 0;
|
|
40
|
+
this.data = [];
|
|
41
|
+
this.hasIcon = false;
|
|
42
|
+
}
|
|
43
|
+
get scheme() {
|
|
44
|
+
switch (this.value) {
|
|
45
|
+
case "enhanced":
|
|
46
|
+
return LinearIndicatorScheme.enhanced;
|
|
47
|
+
case "medium":
|
|
48
|
+
return LinearIndicatorScheme.categorical;
|
|
49
|
+
default:
|
|
50
|
+
return LinearIndicatorScheme.regular;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
render() {
|
|
54
|
+
const horizontal = this.direction === IndicatorDirection.horizontal;
|
|
55
|
+
const trend = this.variant === "trend";
|
|
56
|
+
const barRect = horizontal ? trend ? HORIZONTAL_TREND : HORIZONTAL_BAR : trend ? VERTICAL_TREND : VERTICAL_BAR;
|
|
57
|
+
const frameTransform = horizontal ? "translate(3.5 7.5)" : "rotate(90 24 24) translate(3.5 7.5)";
|
|
58
|
+
const showIcon = this.hasIcon && this.variant === "bar";
|
|
59
|
+
return html`
|
|
60
|
+
<svg viewBox="0 0 48 48" aria-hidden="true">
|
|
61
|
+
<g transform=${frameTransform}>
|
|
62
|
+
<path class="frame" d=${FRAME_PATH} />
|
|
63
|
+
</g>
|
|
64
|
+
${this.variant === "trend" ? renderTrendGraph(
|
|
65
|
+
barRect,
|
|
66
|
+
this.data,
|
|
67
|
+
this.level,
|
|
68
|
+
this.scheme,
|
|
69
|
+
"tank"
|
|
70
|
+
) : renderLinearBar(barRect, this.level, this.scheme, "tank")}
|
|
71
|
+
</svg>
|
|
72
|
+
${showIcon ? html`<div class="icon-wrapper">
|
|
73
|
+
<slot name="icon"><obi-tank usecsscolor></obi-tank></slot>
|
|
74
|
+
</div>` : nothing}
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
ObcIndicatorTankAtmospheric.styles = unsafeCSS(componentStyle);
|
|
79
|
+
__decorateClass([
|
|
80
|
+
property({ type: String, reflect: true })
|
|
81
|
+
], ObcIndicatorTankAtmospheric.prototype, "direction", 2);
|
|
82
|
+
__decorateClass([
|
|
83
|
+
property({ type: String, reflect: true })
|
|
84
|
+
], ObcIndicatorTankAtmospheric.prototype, "variant", 2);
|
|
85
|
+
__decorateClass([
|
|
86
|
+
property({ type: String, reflect: true })
|
|
87
|
+
], ObcIndicatorTankAtmospheric.prototype, "value", 2);
|
|
88
|
+
__decorateClass([
|
|
89
|
+
property({ type: Number })
|
|
90
|
+
], ObcIndicatorTankAtmospheric.prototype, "level", 2);
|
|
91
|
+
__decorateClass([
|
|
92
|
+
property({ type: Array })
|
|
93
|
+
], ObcIndicatorTankAtmospheric.prototype, "data", 2);
|
|
94
|
+
__decorateClass([
|
|
95
|
+
property({ type: Boolean })
|
|
96
|
+
], ObcIndicatorTankAtmospheric.prototype, "hasIcon", 2);
|
|
97
|
+
ObcIndicatorTankAtmospheric = __decorateClass([
|
|
98
|
+
customElement("obc-indicator-tank-atmospheric")
|
|
99
|
+
], ObcIndicatorTankAtmospheric);
|
|
100
|
+
export {
|
|
101
|
+
IndicatorTankAtmosphericValue,
|
|
102
|
+
IndicatorTankAtmosphericVariant,
|
|
103
|
+
ObcIndicatorTankAtmospheric
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=indicator-tank-atmospheric.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indicator-tank-atmospheric.js","sources":["../../../src/automation/indicator-tank-atmospheric/indicator-tank-atmospheric.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport componentStyle from './indicator-tank-atmospheric.css?inline';\nimport {customElement} from '../../decorator.js';\nimport '../../icons/icon-tank.js';\nimport {\n IndicatorDirection,\n LinearIndicatorScheme,\n Rect,\n renderLinearBar,\n renderTrendGraph,\n} from '../indicator-shared/linear-indicator.js';\n\nexport enum IndicatorTankAtmosphericVariant {\n bar = 'bar',\n trend = 'trend',\n}\n\nexport enum IndicatorTankAtmosphericValue {\n regular = 'regular',\n enhanced = 'enhanced',\n medium = 'medium',\n}\n\nconst HORIZONTAL_BAR: Rect = {x: 8, y: 11, width: 32, height: 26};\nconst VERTICAL_BAR: Rect = {x: 11, y: 8, width: 26, height: 32};\nconst HORIZONTAL_TREND: Rect = {x: 8, y: 10, width: 32, height: 28};\nconst VERTICAL_TREND: Rect = {x: 10, y: 8, width: 28, height: 32};\n\nconst FRAME_PATH =\n 'M20.5 32.5L4.21259 32.5C3.70663 32.5 3.45364 32.5 3.09178 32.3531C2.84817 32.2542 2.44102 31.9492 2.27758 31.7433C2.0348 31.4373 1.98325 31.2615 1.88017 30.9098C1.29286 28.906 0.5 24.6852 0.5 16.5C0.5 8.31487 1.29286 4.09402 1.88016 2.09025C1.98325 1.73854 2.0348 1.56268 2.27758 1.25676C2.44102 1.0508 2.84817 0.745859 3.09178 0.646944C3.45364 0.500011 3.70662 0.500011 4.21259 0.500011L20.5 0.50001L36.7874 0.500011C37.2934 0.500011 37.5464 0.500011 37.9082 0.646943C38.1518 0.745859 38.559 1.0508 38.7224 1.25675C38.9652 1.56268 39.0167 1.73854 39.1198 2.09025C39.7071 4.09402 40.5 8.31487 40.5 16.5C40.5 24.6851 39.7071 28.906 39.1198 30.9098C39.0167 31.2615 38.9652 31.4373 38.7224 31.7433C38.559 31.9492 38.1518 32.2542 37.9082 32.3531C37.5464 32.5 37.2934 32.5 36.7874 32.5H20.5Z';\n\n/**\n * Compact 48×48 atmospheric tank level indicator.\n *\n * ## Features / Variants\n * - `variant`: `bar` (bottom-up percentage fill) or `trend` (history graph\n * with a current-value micro-bar)\n * - `direction`: `vertical` or `horizontal` tank outline\n * - `value`: color scheme — `regular`, `enhanced` or `medium`\n * - `level`: current tank level 0–100 (%), drives the fill and micro-bar\n * - `data`: history samples 0–100 (%) drawn as the trend graph\n * - `hasIcon`: centered icon overlay (bar variant only)\n *\n * ## Usage Guidelines\n * Use as an at-a-glance level indicator in dashboards and lists. For a\n * full-featured tank cell with readouts, badges and setpoints, use\n * `obc-automation-tank` instead.\n *\n * ## Best Practices / Constraints\n * - `level` and `data` values are clamped to 0–100; values outside that\n * range are pinned to the nearest bound.\n * - The `trend` variant needs at least two `data` samples to draw a line;\n * with fewer it shows only the current-value micro-bar.\n * - The `icon` slot renders only in the `bar` variant; it is ignored in\n * `trend`.\n * - Display-only: the root SVG is `aria-hidden`; convey tank level to\n * assistive tech through adjacent text if it is not otherwise available.\n *\n * ## Slots\n * | Slot | Condition | Purpose |\n * | ------ | ----------------------------- | ------------------------------ |\n * | `icon` | `hasIcon` and `variant='bar'` | Icon overlay (`obi-*` element) |\n *\n * @slot icon - Centered icon overlay, defaults to `obi-tank`\n */\n@customElement('obc-indicator-tank-atmospheric')\nexport class ObcIndicatorTankAtmospheric extends LitElement {\n @property({type: String, reflect: true}) direction: IndicatorDirection =\n IndicatorDirection.vertical;\n @property({type: String, reflect: true})\n variant: IndicatorTankAtmosphericVariant =\n IndicatorTankAtmosphericVariant.bar;\n @property({type: String, reflect: true})\n value: IndicatorTankAtmosphericValue = IndicatorTankAtmosphericValue.regular;\n /** Current level, 0-100 (%) */\n @property({type: Number}) level = 0;\n /** History samples, 0-100 (%) each, oldest first */\n @property({type: Array}) data: number[] = [];\n @property({type: Boolean}) hasIcon = false;\n\n private get scheme(): LinearIndicatorScheme {\n switch (this.value) {\n case IndicatorTankAtmosphericValue.enhanced:\n return LinearIndicatorScheme.enhanced;\n case IndicatorTankAtmosphericValue.medium:\n return LinearIndicatorScheme.categorical;\n default:\n return LinearIndicatorScheme.regular;\n }\n }\n\n override render() {\n const horizontal = this.direction === IndicatorDirection.horizontal;\n const trend = this.variant === IndicatorTankAtmosphericVariant.trend;\n const barRect = horizontal\n ? trend\n ? HORIZONTAL_TREND\n : HORIZONTAL_BAR\n : trend\n ? VERTICAL_TREND\n : VERTICAL_BAR;\n const frameTransform = horizontal\n ? 'translate(3.5 7.5)'\n : 'rotate(90 24 24) translate(3.5 7.5)';\n const showIcon =\n this.hasIcon && this.variant === IndicatorTankAtmosphericVariant.bar;\n return html`\n <svg viewBox=\"0 0 48 48\" aria-hidden=\"true\">\n <g transform=${frameTransform}>\n <path class=\"frame\" d=${FRAME_PATH} />\n </g>\n ${this.variant === IndicatorTankAtmosphericVariant.trend\n ? renderTrendGraph(\n barRect,\n this.data,\n this.level,\n this.scheme,\n 'tank'\n )\n : renderLinearBar(barRect, this.level, this.scheme, 'tank')}\n </svg>\n ${showIcon\n ? html`<div class=\"icon-wrapper\">\n <slot name=\"icon\"><obi-tank usecsscolor></obi-tank></slot>\n </div>`\n : nothing}\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-indicator-tank-atmospheric': ObcIndicatorTankAtmospheric;\n }\n}\n"],"names":["IndicatorTankAtmosphericVariant","IndicatorTankAtmosphericValue"],"mappings":";;;;;;;;;;;;;;;;AAaO,IAAK,oDAAAA,qCAAL;AACLA,mCAAA,KAAA,IAAM;AACNA,mCAAA,OAAA,IAAQ;AAFE,SAAAA;AAAA,GAAA,mCAAA,CAAA,CAAA;AAKL,IAAK,kDAAAC,mCAAL;AACLA,iCAAA,SAAA,IAAU;AACVA,iCAAA,UAAA,IAAW;AACXA,iCAAA,QAAA,IAAS;AAHC,SAAAA;AAAA,GAAA,iCAAA,CAAA,CAAA;AAMZ,MAAM,iBAAuB,EAAC,GAAG,GAAG,GAAG,IAAI,OAAO,IAAI,QAAQ,GAAA;AAC9D,MAAM,eAAqB,EAAC,GAAG,IAAI,GAAG,GAAG,OAAO,IAAI,QAAQ,GAAA;AAC5D,MAAM,mBAAyB,EAAC,GAAG,GAAG,GAAG,IAAI,OAAO,IAAI,QAAQ,GAAA;AAChE,MAAM,iBAAuB,EAAC,GAAG,IAAI,GAAG,GAAG,OAAO,IAAI,QAAQ,GAAA;AAE9D,MAAM,aACJ;AAqCK,IAAM,8BAAN,cAA0C,WAAW;AAAA,EAArD,cAAA;AAAA,UAAA,GAAA,SAAA;AACoC,SAAA,YACvC,mBAAmB;AAErB,SAAA,UACE;AAEF,SAAA,QAAuC;AAEb,SAAA,QAAQ;AAET,SAAA,OAAiB,CAAA;AACf,SAAA,UAAU;AAAA,EAAA;AAAA,EAErC,IAAY,SAAgC;AAC1C,YAAQ,KAAK,OAAA;AAAA,MACX,KAAK;AACH,eAAO,sBAAsB;AAAA,MAC/B,KAAK;AACH,eAAO,sBAAsB;AAAA,MAC/B;AACE,eAAO,sBAAsB;AAAA,IAAA;AAAA,EAEnC;AAAA,EAES,SAAS;AAChB,UAAM,aAAa,KAAK,cAAc,mBAAmB;AACzD,UAAM,QAAQ,KAAK,YAAY;AAC/B,UAAM,UAAU,aACZ,QACE,mBACA,iBACF,QACE,iBACA;AACN,UAAM,iBAAiB,aACnB,uBACA;AACJ,UAAM,WACJ,KAAK,WAAW,KAAK,YAAY;AACnC,WAAO;AAAA;AAAA,uBAEY,cAAc;AAAA,kCACH,UAAU;AAAA;AAAA,UAElC,KAAK,YAAY,UACf;AAAA,MACE;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AAAA,IAAA,IAEF,gBAAgB,SAAS,KAAK,OAAO,KAAK,QAAQ,MAAM,CAAC;AAAA;AAAA,QAE7D,WACE;AAAA;AAAA,oBAGA,OAAO;AAAA;AAAA,EAEf;AAGF;AAhEa,4BA+DK,SAAS,UAAU,cAAc;AA9DR,gBAAA;AAAA,EAAxC,SAAS,EAAC,MAAM,QAAQ,SAAS,MAAK;AAAA,GAD5B,4BAC8B,WAAA,aAAA,CAAA;AAGzC,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,QAAQ,SAAS,MAAK;AAAA,GAH5B,4BAIX,WAAA,WAAA,CAAA;AAGA,gBAAA;AAAA,EADC,SAAS,EAAC,MAAM,QAAQ,SAAS,MAAK;AAAA,GAN5B,4BAOX,WAAA,SAAA,CAAA;AAE0B,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GATb,4BASe,WAAA,SAAA,CAAA;AAED,gBAAA;AAAA,EAAxB,SAAS,EAAC,MAAM,MAAA,CAAM;AAAA,GAXZ,4BAWc,WAAA,QAAA,CAAA;AACE,gBAAA;AAAA,EAA1B,SAAS,EAAC,MAAM,QAAA,CAAQ;AAAA,GAZd,4BAYgB,WAAA,WAAA,CAAA;AAZhB,8BAAN,gBAAA;AAAA,EADN,cAAc,gCAAgC;AAAA,GAClC,2BAAA;"}
|
|
@@ -220,7 +220,7 @@ export declare class ObcCompass extends LitElement {
|
|
|
220
220
|
priority: Priority;
|
|
221
221
|
/** @availableWhen priority==enhanced */
|
|
222
222
|
priorityElements: CompassPriorityElement[];
|
|
223
|
-
/** Show compass NSEW labels
|
|
223
|
+
/** Show compass NSEW labels. The north arrow is always shown, independent of this flag. */
|
|
224
224
|
showLabels: boolean;
|
|
225
225
|
/** When true, labels and north arrow are placed inside the outer ring. */
|
|
226
226
|
tickmarksInside: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compass.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass/compass.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAqB,MAAM,KAAK,CAAC;AAEnE,OAAO,mBAAmB,CAAC;AAE3B,OAAO,EACL,aAAa,EACb,aAAa,EAGd,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EAIrB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAc,WAAW,EAAiB,MAAM,oBAAoB,CAAC;AAU5E,OAAO,EACL,WAAW,EAGX,OAAO,EACP,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAC;AACtD,OAAO,EAAC,OAAO,EAAC,CAAC;AACjB,OAAO,EAAC,aAAa,EAAE,aAAa,EAAC,CAAC;AACtC,OAAO,EAAC,oBAAoB,EAAC,CAAC;AAC9B,YAAY,EAAC,oBAAoB,EAAC,CAAC;AAEnC,oBAAY,gBAAgB;IAC1B,OAAO,YAAY;IACnB,SAAS,cAAc;IACvB,QAAQ,aAAa;CACtB;AAED,oBAAY,sBAAsB;IAChC,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,GAAG,QAAQ;IACX,IAAI,SAAS;IACb,OAAO,YAAY;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyEG;AACH,qBACa,UAAW,SAAQ,UAAU;IACxC,oDAAoD;IAC1B,OAAO,SAAK;IACtC,iDAAiD;IACvB,gBAAgB,SAAK;IAE/C,gDAAgD;IACtB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAQ;IAChE,2CAA2C;IACjB,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACjE;;;OAGG;IACwB,iBAAiB,EAAE,OAAO,CAAS;IAC9D,2CAA2C;IACjB,6BAA6B,EAAE,MAAM,CAAO;IACtE,2CAA2C;IAChB,uBAAuB,EAAE,OAAO,CAAS;IACpE;;;OAGG;IAC0C,qBAAqB,EAAE,OAAO,CACpE;IACP;;;OAGG;IACuB,6BAA6B,EAAE,MAAM,CAAK;IACpE,2CAA2C;IAChB,eAAe,EAAE,OAAO,CAAS;IAC5D;;;OAGG;IACwB,QAAQ,EAAE,OAAO,CAAS;IACrD,iDAAiD;IACN,cAAc,EAAE,WAAW,EAAE,CAAM;IAC9E;;;OAGG;IACuB,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACtE;;;OAGG;IACuB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClE;;;OAGG;IACuB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC7D;;;OAGG;IACuB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACrE;;;OAGG;IACuB,WAAW,EAAE,WAAW,CAA0B;IAC5E;;;;;;;OAOG;IAEH,cAAc,EAAE,oBAAoB,EAAE,CAAM;IAC5C,iFAAiF;IACvD,aAAa,EAAE,aAAa,CAC5B;IAC1B,uFAAuF;IAC7D,aAAa,EAAE,aAAa,CAC5B;IAC1B;;;;;OAKG;IACuB,0BAA0B,EAAE,MAAM,GAAG,SAAS,CAAC;IACzE;;;;;OAKG;IACuB,qBAAqB,EAAE,MAAM,CAAM;IAC7D;;;;;;;;OAQG;IACuB,kBAAkB,EAAE,MAAM,CAAK;IACzD,wKAAwK;IAC9I,OAAO,EAAE,OAAO,CAAgB;IAC1D,sFAAsF;IAC5D,WAAW,EAAE,WAAW,CAA2B;IAC7E;;;;;;;;;OASG;IACuB,WAAW,EAAE,MAAM,CAAM;IACnD,kCAAkC;IACR,YAAY,EAAE,MAAM,CAAM;IACzB,gBAAgB,EAAE,OAAO,CAAS;IAC7D,kCAAkC;IACR,iBAAiB,EAAE,MAAM,CAAyB;IAClD,SAAS,EAAE,gBAAgB,CAC1B;IACD,KAAK,EAAE,eAAe,CAA0B;IAC1E,wIAAwI;IAC9G,QAAQ,EAAE,QAAQ,CAAoB;IAChE,wCAAwC;IAExC,gBAAgB,EAAE,sBAAsB,EAAE,CAAgC;IAC1E,
|
|
1
|
+
{"version":3,"file":"compass.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass/compass.ts"],"names":[],"mappings":"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"}
|
|
@@ -204,7 +204,7 @@ let ObcCompass = class extends LitElement {
|
|
|
204
204
|
.tickmarksInside=${this.tickmarksInside}
|
|
205
205
|
.crosshairEnabled=${true}
|
|
206
206
|
.crosshairCenterCutout=${this.hasCenterReadouts}
|
|
207
|
-
.northArrow=${
|
|
207
|
+
.northArrow=${true}
|
|
208
208
|
.angleSetpoint=${this.headingSetpoint ?? void 0}
|
|
209
209
|
.newAngleSetpoint=${this.newHeadingSetpoint}
|
|
210
210
|
.atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compass.js","sources":["../../../src/navigation-instruments/compass/compass.ts"],"sourcesContent":["import {LitElement, PropertyValues, css, html, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType} from '../watch/tickmark.js';\nimport {\n CogArrowStyle,\n HdgArrowStyle,\n cogArrow,\n hdgArrow,\n} from '../course-arrows/course-arrows.js';\nimport {\n CompassCenterReadout,\n CompassReadoutSource,\n centerReadoutStyles,\n renderCenterReadouts,\n resolveCompassCenterReadouts,\n} from '../readout/center-readout.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {\n applyPinnedHostSize,\n computeRadialFrame,\n measureContainerPx,\n NORTH_ARROW_WIDTH_PX,\n NSWE_LABEL_WIDTH_PX,\n type RadialFrame,\n} from '../../svghelpers/radial-frame.js';\nimport {\n VesselImage,\n VesselImageSize,\n WatchCircleType,\n RotType,\n RotPosition,\n} from '../watch/watch.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {ROT_ZERO_DEADBAND_DEG} from '../rate-of-turn/rot-renderer.js';\nimport {customElement} from '../../decorator.js';\nimport {InstrumentState, Priority} from '../types.js';\nexport {RotType};\nexport {HdgArrowStyle, CogArrowStyle};\nexport {CompassReadoutSource};\nexport type {CompassCenterReadout};\n\nexport enum CompassDirection {\n NorthUp = 'northUp',\n HeadingUp = 'headingUp',\n CourseUp = 'courseUp',\n}\n\nexport enum CompassPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n rot = 'rot',\n wind = 'wind',\n current = 'current',\n}\n\n/**\n * `<obc-compass>` – Full-featured compass with HDG/COG arrows, rate-of-turn indicator, and environmental overlays.\n *\n * Renders a circular compass instrument that displays heading (HDG) and\n * course-over-ground (COG) as rotating arrows over a triple-ring watch face.\n * It supports wind and current indicators, a vessel silhouette, heading\n * setpoint with auto at-setpoint detection, advice zones, and a rate-of-turn\n * (ROT) dot indicator. The compass can be oriented north-up, heading-up, or\n * course-up.\n *\n * ## Features\n *\n * - **Direction modes**: `northUp` (default), `headingUp`, or `courseUp`\n * via the `direction` property.\n * - **HDG / COG arrows**: Two styled arrows overlay the watch face,\n * rotating independently.\n * - **Heading setpoint**: Optional setpoint marker with auto at-setpoint\n * detection via `headingSetpoint`, `atHeadingSetpoint`, and deadband\n * tuning properties.\n * - **Advice zones**: Pass `headingAdvices` to render caution/alert arcs;\n * triggered state is derived from whether the current heading falls\n * inside the advice range.\n * - **Rate of turn**: Animated ROT indicator driven by\n * `rateOfTurnDegreesPerMinute` (deg/min, the maritime / AIS convention).\n * Supports spinning dots (`rotType=\"dots\"`) — the dot animation is\n * amplified by `rotDotAnimationFactor` so small physical values still\n * read at a glance — and a banana-shaped arc bar (`rotType=\"bar\"`)\n * showing the rate of turn as an arc anchored at the current heading.\n * Bar extent is driven by the physical value only (gain is not applied).\n * Position on the outer scale ring or inner circle via `rotPosition`.\n * - **Environmental overlays**: Wind speed/direction and current\n * speed/direction indicators on the watch face.\n * - **Vessel image**: Configurable vessel silhouette centered on the\n * compass, rotating with heading.\n * - **Arrow styles**: The HDG and COG arrows each select their look via\n * `hdgArrowStyle` (`arrowHead` default, `needle`, `vector`, `beamLine`)\n * and `cogArrowStyle` (`arrowHead` default, `needle`, `vector`,\n * `velocityVector`).\n * - **Center readouts**: `centerReadouts` replaces the vessel with up to\n * three readouts (first on top, the rest below a horizontal divider);\n * values bind to the instrument's own inputs per entry `source`.\n * - **Color priority**: Set `priority` to `Priority.enhanced` to use the\n * blue/enhanced color palette instead of the default gray/regular palette\n * (default: `Priority.regular`).\n *\n * ## Usage Guidelines\n *\n * - Set `heading` and `courseOverGround` to the current sensor values\n * in degrees.\n * - Use `direction` to control the compass orientation mode.\n * - Use `headingSetpoint` to show a target heading marker.\n * - Pass `headingAdvices` as an array of `AngleAdvice` objects for\n * caution/alert zones.\n * - Set `currentWindSpeedKnots` / `windFromDirection` and `currentSpeed` /\n * `currentFromDirection` to display environmental indicators.\n *\n * ## Example\n *\n * ```html\n * <obc-compass\n * heading=\"45\"\n * courseOverGround=\"50\"\n * direction=\"northUp\"\n * headingSetpoint=\"90\"\n * priority=\"regular\"\n * vesselImage=\"genericTop\"\n * ></obc-compass>\n * ```\n *\n *\n * @ignition-base-height: 512px\n * @ignition-base-width: 512px\n * @stable\n */\n@customElement('obc-compass')\nexport class ObcCompass extends LitElement {\n /** The current heading of the vessel in degrees. */\n @property({type: Number}) heading = 0;\n /** The current course over ground in degrees. */\n @property({type: Number}) courseOverGround = 0;\n\n /** The set point for the heading in degrees. */\n @property({type: Number}) headingSetpoint: number | null = null;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) newHeadingSetpoint: number | undefined;\n /**\n * Indicates if the vessel is at the heading set point.\n * @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==false\n */\n @property({type: Boolean}) atHeadingSetpoint: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) headingSetpointAtZeroDeadband: number = 0.5;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) headingSetpointOverride: boolean = false;\n /**\n * Enables automatic at heading set point calculation.\n * @availableWhen headingSetpoint!=null\n */\n @property({type: Boolean, attribute: false}) autoAtHeadingSetpoint: boolean =\n true;\n /**\n * The deadband for the heading set point in degrees.\n * @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==true\n */\n @property({type: Number}) autoAtHeadingSetpointDeadband: number = 2;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) animateSetpoint: boolean = false;\n /**\n * Indicates if the compass is being touched.\n * @availableWhen headingSetpoint!=null\n */\n @property({type: Boolean}) touching: boolean = false;\n /** An array of angle advices for the compass. */\n @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];\n /**\n * The wind speed in knots.\n * @availableWhen windFromDirection!=null\n */\n @property({type: Number}) currentWindSpeedKnots: number | null = null;\n /**\n * The direction the wind is coming from in degrees.\n * @availableWhen currentWindSpeedKnots!=null\n */\n @property({type: Number}) windFromDirection: number | null = null;\n /**\n * The current speed, number of arrows.\n * @availableWhen currentFromDirection!=null\n */\n @property({type: Number}) currentSpeed: number | null = null;\n /**\n * The direction the current is coming from in degrees.\n * @availableWhen currentSpeed!=null\n */\n @property({type: Number}) currentFromDirection: number | null = null;\n /**\n * The image of the vessel. Hidden while `centerReadouts` is non-empty.\n * @availableWhen centerReadouts==[]\n */\n @property({type: String}) vesselImage: VesselImage = VesselImage.genericTop;\n /**\n * Center readouts replacing the vessel: the first entry renders on top,\n * the rest side by side below a horizontal divider. Values bind per entry\n * `source` (`hdg` → `heading`, `cog` → `courseOverGround`, `rot` →\n * `rateOfTurnDegreesPerMinute`, a dash when unset) and colors follow\n * `priorityElements`. While non-empty, the crosshair's center is cut out\n * so the readouts sit on a clean face.\n */\n @property({type: Array, attribute: false})\n centerReadouts: CompassCenterReadout[] = [];\n /** HDG arrow style: `arrowHead` (default), `needle`, `vector`, or `beamLine`. */\n @property({type: String}) hdgArrowStyle: HdgArrowStyle =\n HdgArrowStyle.arrowHead;\n /** COG arrow style: `arrowHead` (default), `needle`, `vector`, or `velocityVector`. */\n @property({type: String}) cogArrowStyle: CogArrowStyle =\n CogArrowStyle.arrowHead;\n /**\n * Measured rate of turn in degrees per minute (positive = starboard).\n * Drives both the bar extent and (after multiplication by\n * `rotDotAnimationFactor`) the spinning dot animation.\n * When `undefined`, falls back to the deprecated `rotationsPerMinute`.\n */\n @property({type: Number}) rateOfTurnDegreesPerMinute: number | undefined;\n /**\n * Visual amplification applied only to the spinning dot animation\n * (not to the bar extent). Default `18` keeps the legacy visual feel\n * (≈1 rpm at 20°/min).\n * @availableWhen rotType==dots\n */\n @property({type: Number}) rotDotAnimationFactor: number = 18;\n /**\n * Legacy rate-of-turn input, in rotations per minute. When\n * `rateOfTurnDegreesPerMinute` is `undefined`, this value is used\n * (unconverted) as the fallback ROT, driving both the spinning dot ring\n * and the bar extent.\n * @deprecated Use `rateOfTurnDegreesPerMinute` (and optionally\n * `rotDotAnimationFactor`) instead. Takes effect only when\n * `rateOfTurnDegreesPerMinute` is `undefined`.\n */\n @property({type: Number}) rotationsPerMinute: number = 1;\n /** ROT display mode: `'dots'` (spinning dots, default) or `'bar'` (a rate-of-turn arc anchored at the current heading, its length proportional to the rate of turn). */\n @property({type: String}) rotType: RotType = RotType.dots;\n /** ROT track position: `'innerCircle'` (default) or `'scale'` (on the outer ring). */\n @property({type: String}) rotPosition: RotPosition = RotPosition.innerCircle;\n /**\n * Bar-extent reference value in **degrees per minute**. The bar fills the\n * full ±`rotArcExtent` arc when the measured ROT equals ±`rotMaxValue`.\n * Default `60` aligns with ES-TRIN 2025/1 Art. 3.02.\n *\n * Note: prior to the introduction of `rateOfTurnDegreesPerMinute` this\n * property was interpreted in rotations per minute. The unit changed when\n * the physical ROT API was introduced.\n * @availableWhen rotType==bar\n */\n @property({type: Number}) rotMaxValue: number = 60;\n /** @availableWhen rotType==bar */\n @property({type: Number}) rotArcExtent: number = 60;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n /** @availableWhen rotType==bar */\n @property({type: Number}) rotAtZeroDeadband: number = ROT_ZERO_DEADBAND_DEG;\n @property({type: String}) direction: CompassDirection =\n CompassDirection.NorthUp;\n @property({type: String}) state: InstrumentState = InstrumentState.active;\n /** Color priority: `Priority.enhanced` uses the blue/enhanced color palette, `Priority.regular` (default) uses the standard palette. */\n @property({type: String}) priority: Priority = Priority.regular;\n /** @availableWhen priority==enhanced */\n @property({type: Array, attribute: false})\n priorityElements: CompassPriorityElement[] = [CompassPriorityElement.hdg];\n /** Show compass NSEW labels and north arrow. */\n @property({type: Boolean}) showLabels: boolean = false;\n /** When true, labels and north arrow are placed inside the outer ring. */\n @property({type: Boolean}) tickmarksInside: boolean = false;\n /**\n * Outer-ring diameter in CSS pixels. When set, the instrument renders at a\n * fixed intrinsic size derived from the ring, arc shape and label reserve —\n * so instruments sharing the same value have identical ring circumference\n * regardless of label width or arc extent (like obc-donut-chart's\n * fixedHeight). When unset (default), the instrument fills its container.\n */\n @property({type: Number, attribute: 'face-diameter'})\n faceDiameter: number | undefined;\n\n private _headingSp = new SetpointBundle({\n angularWraparound: true,\n onAnimationEnd: () => this.requestUpdate(),\n });\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\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._headingSp.dispose();\n }\n\n // @ts-expect-error TS6133: The controller ensures that the render\n // function is called on resize of the element\n private _resizeController = new ResizeController(this, {});\n\n /**\n * Resolved rate of turn in degrees per minute, used to compute the bar\n * extent. Prefers the new physical API; falls back to the deprecated\n * `rotationsPerMinute` so existing consumers keep their visuals during\n * the deprecation window.\n */\n private get _effectiveRotDegPerMin(): number {\n return this.rateOfTurnDegreesPerMinute ?? this.rotationsPerMinute;\n }\n\n /**\n * Pixel cost of the outside decor: the always-rendered north-arrow glyph\n * plus, only while shown, the NSWE labels (both keep a constant on-screen\n * size via `1/scale` terms). Feeds the frame's width-aware reserve,\n * replacing the former empirical `72 + delta(clientSize)` padding.\n * Wind/current symbols at their default radius are covered by the base\n * padding of 72.\n */\n private getOutsideDecorPx(): number {\n if (this.tickmarksInside) {\n return 0;\n }\n return NORTH_ARROW_WIDTH_PX + (this.showLabels ? NSWE_LABEL_WIDTH_PX : 0);\n }\n\n /** Whether the host size styles were set by applyPinnedHostSize. */\n private _hostSizePinned = false;\n private _frame: RadialFrame | undefined;\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n this._hostSizePinned = applyPinnedHostSize(\n this,\n this._frame,\n this._hostSizePinned\n );\n }\n\n private get angleAdviceRaw(): AngleAdviceRaw[] {\n return this.headingAdvices.map(({minAngle, maxAngle, hinted, type}) => {\n const state =\n this.heading >= minAngle && this.heading <= maxAngle\n ? AdviceState.triggered\n : hinted\n ? AdviceState.hinted\n : AdviceState.regular;\n return {minAngle, maxAngle, type, state};\n });\n }\n\n private priorityFor(element: CompassPriorityElement): Priority {\n const selected = Array.isArray(this.priorityElements)\n ? this.priorityElements\n : [];\n return selected.includes(element) ? this.priority : Priority.regular;\n }\n\n private colorFor(element: CompassPriorityElement): string | undefined {\n return this.priorityFor(element) === Priority.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : undefined;\n }\n\n private readoutPriorityFor(source: CompassReadoutSource): Priority {\n switch (source) {\n case CompassReadoutSource.hdg:\n return this.priorityFor(CompassPriorityElement.hdg);\n case CompassReadoutSource.cog:\n return this.priorityFor(CompassPriorityElement.cog);\n case CompassReadoutSource.rot:\n return this.priorityFor(CompassPriorityElement.rot);\n }\n }\n\n private get hasCenterReadouts(): boolean {\n return this.centerReadouts.length > 0;\n }\n\n private getRotation(): number | undefined {\n if (this.direction === CompassDirection.NorthUp) {\n return undefined;\n } else if (this.direction === CompassDirection.HeadingUp) {\n return -this.heading;\n } else if (this.direction === CompassDirection.CourseUp) {\n return -this.courseOverGround;\n }\n return undefined;\n }\n\n override render() {\n const tickmarks: Tickmark[] = [\n {angle: 0, type: TickmarkType.main},\n {angle: 90, type: TickmarkType.main},\n {angle: 180, type: TickmarkType.main},\n {angle: 270, type: TickmarkType.main},\n ];\n\n const frame = computeRadialFrame({\n basePadding: 72,\n labelWidthPx: this.getOutsideDecorPx(),\n containerPx: measureContainerPx(this),\n faceDiameter: this.faceDiameter,\n });\n this._frame = frame;\n const viewBox = frame.viewBox;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .arcFrame=${frame}\n .advices=${this.angleAdviceRaw}\n .tickmarks=${tickmarks}\n .state=${this.state}\n .watchCircleType=${WatchCircleType.triple}\n .showLabels=${this.showLabels && !frame.labelsHidden}\n .tickmarksInside=${this.tickmarksInside}\n .crosshairEnabled=${true}\n .crosshairCenterCutout=${this.hasCenterReadouts}\n .northArrow=${!frame.labelsHidden}\n .angleSetpoint=${this.headingSetpoint ?? undefined}\n .newAngleSetpoint=${this.newHeadingSetpoint}\n .atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}\n .angleSetpointAtZeroDeadband=${this.headingSetpointAtZeroDeadband}\n .setpointOverride=${this.headingSetpointOverride}\n .priority=${this.priority}\n .animateSetpoint=${this.animateSetpoint}\n .vessels=${this.hasCenterReadouts\n ? []\n : [\n {\n size: VesselImageSize.medium,\n vesselImage: this.vesselImage,\n transform: `rotate(${this.heading}deg)`,\n },\n ]}\n .windKnots=${this.currentWindSpeedKnots}\n .windFromDirectionDeg=${this.windFromDirection}\n .windColor=${this.colorFor(CompassPriorityElement.wind)}\n .current=${this.currentSpeed}\n .currentFromDirectionDeg=${this.currentFromDirection}\n .currentColor=${this.colorFor(CompassPriorityElement.current)}\n .rotation=${this.getRotation()}\n .rotType=${this.rotType}\n .rotPosition=${this.rotPosition}\n .rotStartAngle=${this.heading + (this.getRotation() ?? 0)}\n .rotEndAngle=${this.heading +\n (this._effectiveRotDegPerMin / (this.rotMaxValue || 1)) *\n this.rotArcExtent +\n (this.getRotation() ?? 0)}\n .rotPriority=${this.priorityFor(CompassPriorityElement.rot)}\n .rotPortStarboard=${this.rotPortStarboard}\n .rotAtZeroDeadband=${this.rotAtZeroDeadband}\n .rateOfTurnDegreesPerMinute=${this.rateOfTurnDegreesPerMinute}\n .rotDotAnimationFactor=${this.rotDotAnimationFactor}\n .rotationsPerMinute=${this.rotationsPerMinute}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\">\n ${hdgArrow(\n this.hdgArrowStyle,\n this.heading + (this.getRotation() ?? 0),\n this.priorityFor(CompassPriorityElement.hdg)\n )}\n ${cogArrow(\n this.cogArrowStyle,\n this.courseOverGround + (this.getRotation() ?? 0),\n this.priorityFor(CompassPriorityElement.cog)\n )}\n </svg>\n ${this.hasCenterReadouts\n ? html`<div class=\"center-readout-overlay\">\n ${renderCenterReadouts(\n resolveCompassCenterReadouts(this.centerReadouts, {\n heading: this.heading,\n courseOverGround: this.courseOverGround,\n rateOfTurnDegreesPerMinute: this.rateOfTurnDegreesPerMinute,\n priorityFor: (source) => this.readoutPriorityFor(source),\n })\n )}\n </div>`\n : nothing}\n </div>\n `;\n }\n\n static override styles = [\n centerReadoutStyles,\n 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 .center-readout-overlay {\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n }\n\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-compass': ObcCompass;\n }\n}\n"],"names":["CompassDirection","CompassPriorityElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"compass.js","sources":["../../../src/navigation-instruments/compass/compass.ts"],"sourcesContent":["import {LitElement, PropertyValues, css, html, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType} from '../watch/tickmark.js';\nimport {\n CogArrowStyle,\n HdgArrowStyle,\n cogArrow,\n hdgArrow,\n} from '../course-arrows/course-arrows.js';\nimport {\n CompassCenterReadout,\n CompassReadoutSource,\n centerReadoutStyles,\n renderCenterReadouts,\n resolveCompassCenterReadouts,\n} from '../readout/center-readout.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {\n applyPinnedHostSize,\n computeRadialFrame,\n measureContainerPx,\n NORTH_ARROW_WIDTH_PX,\n NSWE_LABEL_WIDTH_PX,\n type RadialFrame,\n} from '../../svghelpers/radial-frame.js';\nimport {\n VesselImage,\n VesselImageSize,\n WatchCircleType,\n RotType,\n RotPosition,\n} from '../watch/watch.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {ROT_ZERO_DEADBAND_DEG} from '../rate-of-turn/rot-renderer.js';\nimport {customElement} from '../../decorator.js';\nimport {InstrumentState, Priority} from '../types.js';\nexport {RotType};\nexport {HdgArrowStyle, CogArrowStyle};\nexport {CompassReadoutSource};\nexport type {CompassCenterReadout};\n\nexport enum CompassDirection {\n NorthUp = 'northUp',\n HeadingUp = 'headingUp',\n CourseUp = 'courseUp',\n}\n\nexport enum CompassPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n rot = 'rot',\n wind = 'wind',\n current = 'current',\n}\n\n/**\n * `<obc-compass>` – Full-featured compass with HDG/COG arrows, rate-of-turn indicator, and environmental overlays.\n *\n * Renders a circular compass instrument that displays heading (HDG) and\n * course-over-ground (COG) as rotating arrows over a triple-ring watch face.\n * It supports wind and current indicators, a vessel silhouette, heading\n * setpoint with auto at-setpoint detection, advice zones, and a rate-of-turn\n * (ROT) dot indicator. The compass can be oriented north-up, heading-up, or\n * course-up.\n *\n * ## Features\n *\n * - **Direction modes**: `northUp` (default), `headingUp`, or `courseUp`\n * via the `direction` property.\n * - **HDG / COG arrows**: Two styled arrows overlay the watch face,\n * rotating independently.\n * - **Heading setpoint**: Optional setpoint marker with auto at-setpoint\n * detection via `headingSetpoint`, `atHeadingSetpoint`, and deadband\n * tuning properties.\n * - **Advice zones**: Pass `headingAdvices` to render caution/alert arcs;\n * triggered state is derived from whether the current heading falls\n * inside the advice range.\n * - **Rate of turn**: Animated ROT indicator driven by\n * `rateOfTurnDegreesPerMinute` (deg/min, the maritime / AIS convention).\n * Supports spinning dots (`rotType=\"dots\"`) — the dot animation is\n * amplified by `rotDotAnimationFactor` so small physical values still\n * read at a glance — and a banana-shaped arc bar (`rotType=\"bar\"`)\n * showing the rate of turn as an arc anchored at the current heading.\n * Bar extent is driven by the physical value only (gain is not applied).\n * Position on the outer scale ring or inner circle via `rotPosition`.\n * - **Environmental overlays**: Wind speed/direction and current\n * speed/direction indicators on the watch face.\n * - **Vessel image**: Configurable vessel silhouette centered on the\n * compass, rotating with heading.\n * - **Arrow styles**: The HDG and COG arrows each select their look via\n * `hdgArrowStyle` (`arrowHead` default, `needle`, `vector`, `beamLine`)\n * and `cogArrowStyle` (`arrowHead` default, `needle`, `vector`,\n * `velocityVector`).\n * - **Center readouts**: `centerReadouts` replaces the vessel with up to\n * three readouts (first on top, the rest below a horizontal divider);\n * values bind to the instrument's own inputs per entry `source`.\n * - **Color priority**: Set `priority` to `Priority.enhanced` to use the\n * blue/enhanced color palette instead of the default gray/regular palette\n * (default: `Priority.regular`).\n *\n * ## Usage Guidelines\n *\n * - Set `heading` and `courseOverGround` to the current sensor values\n * in degrees.\n * - Use `direction` to control the compass orientation mode.\n * - Use `headingSetpoint` to show a target heading marker.\n * - Pass `headingAdvices` as an array of `AngleAdvice` objects for\n * caution/alert zones.\n * - Set `currentWindSpeedKnots` / `windFromDirection` and `currentSpeed` /\n * `currentFromDirection` to display environmental indicators.\n *\n * ## Example\n *\n * ```html\n * <obc-compass\n * heading=\"45\"\n * courseOverGround=\"50\"\n * direction=\"northUp\"\n * headingSetpoint=\"90\"\n * priority=\"regular\"\n * vesselImage=\"genericTop\"\n * ></obc-compass>\n * ```\n *\n *\n * @ignition-base-height: 512px\n * @ignition-base-width: 512px\n * @stable\n */\n@customElement('obc-compass')\nexport class ObcCompass extends LitElement {\n /** The current heading of the vessel in degrees. */\n @property({type: Number}) heading = 0;\n /** The current course over ground in degrees. */\n @property({type: Number}) courseOverGround = 0;\n\n /** The set point for the heading in degrees. */\n @property({type: Number}) headingSetpoint: number | null = null;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) newHeadingSetpoint: number | undefined;\n /**\n * Indicates if the vessel is at the heading set point.\n * @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==false\n */\n @property({type: Boolean}) atHeadingSetpoint: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) headingSetpointAtZeroDeadband: number = 0.5;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) headingSetpointOverride: boolean = false;\n /**\n * Enables automatic at heading set point calculation.\n * @availableWhen headingSetpoint!=null\n */\n @property({type: Boolean, attribute: false}) autoAtHeadingSetpoint: boolean =\n true;\n /**\n * The deadband for the heading set point in degrees.\n * @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==true\n */\n @property({type: Number}) autoAtHeadingSetpointDeadband: number = 2;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) animateSetpoint: boolean = false;\n /**\n * Indicates if the compass is being touched.\n * @availableWhen headingSetpoint!=null\n */\n @property({type: Boolean}) touching: boolean = false;\n /** An array of angle advices for the compass. */\n @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];\n /**\n * The wind speed in knots.\n * @availableWhen windFromDirection!=null\n */\n @property({type: Number}) currentWindSpeedKnots: number | null = null;\n /**\n * The direction the wind is coming from in degrees.\n * @availableWhen currentWindSpeedKnots!=null\n */\n @property({type: Number}) windFromDirection: number | null = null;\n /**\n * The current speed, number of arrows.\n * @availableWhen currentFromDirection!=null\n */\n @property({type: Number}) currentSpeed: number | null = null;\n /**\n * The direction the current is coming from in degrees.\n * @availableWhen currentSpeed!=null\n */\n @property({type: Number}) currentFromDirection: number | null = null;\n /**\n * The image of the vessel. Hidden while `centerReadouts` is non-empty.\n * @availableWhen centerReadouts==[]\n */\n @property({type: String}) vesselImage: VesselImage = VesselImage.genericTop;\n /**\n * Center readouts replacing the vessel: the first entry renders on top,\n * the rest side by side below a horizontal divider. Values bind per entry\n * `source` (`hdg` → `heading`, `cog` → `courseOverGround`, `rot` →\n * `rateOfTurnDegreesPerMinute`, a dash when unset) and colors follow\n * `priorityElements`. While non-empty, the crosshair's center is cut out\n * so the readouts sit on a clean face.\n */\n @property({type: Array, attribute: false})\n centerReadouts: CompassCenterReadout[] = [];\n /** HDG arrow style: `arrowHead` (default), `needle`, `vector`, or `beamLine`. */\n @property({type: String}) hdgArrowStyle: HdgArrowStyle =\n HdgArrowStyle.arrowHead;\n /** COG arrow style: `arrowHead` (default), `needle`, `vector`, or `velocityVector`. */\n @property({type: String}) cogArrowStyle: CogArrowStyle =\n CogArrowStyle.arrowHead;\n /**\n * Measured rate of turn in degrees per minute (positive = starboard).\n * Drives both the bar extent and (after multiplication by\n * `rotDotAnimationFactor`) the spinning dot animation.\n * When `undefined`, falls back to the deprecated `rotationsPerMinute`.\n */\n @property({type: Number}) rateOfTurnDegreesPerMinute: number | undefined;\n /**\n * Visual amplification applied only to the spinning dot animation\n * (not to the bar extent). Default `18` keeps the legacy visual feel\n * (≈1 rpm at 20°/min).\n * @availableWhen rotType==dots\n */\n @property({type: Number}) rotDotAnimationFactor: number = 18;\n /**\n * Legacy rate-of-turn input, in rotations per minute. When\n * `rateOfTurnDegreesPerMinute` is `undefined`, this value is used\n * (unconverted) as the fallback ROT, driving both the spinning dot ring\n * and the bar extent.\n * @deprecated Use `rateOfTurnDegreesPerMinute` (and optionally\n * `rotDotAnimationFactor`) instead. Takes effect only when\n * `rateOfTurnDegreesPerMinute` is `undefined`.\n */\n @property({type: Number}) rotationsPerMinute: number = 1;\n /** ROT display mode: `'dots'` (spinning dots, default) or `'bar'` (a rate-of-turn arc anchored at the current heading, its length proportional to the rate of turn). */\n @property({type: String}) rotType: RotType = RotType.dots;\n /** ROT track position: `'innerCircle'` (default) or `'scale'` (on the outer ring). */\n @property({type: String}) rotPosition: RotPosition = RotPosition.innerCircle;\n /**\n * Bar-extent reference value in **degrees per minute**. The bar fills the\n * full ±`rotArcExtent` arc when the measured ROT equals ±`rotMaxValue`.\n * Default `60` aligns with ES-TRIN 2025/1 Art. 3.02.\n *\n * Note: prior to the introduction of `rateOfTurnDegreesPerMinute` this\n * property was interpreted in rotations per minute. The unit changed when\n * the physical ROT API was introduced.\n * @availableWhen rotType==bar\n */\n @property({type: Number}) rotMaxValue: number = 60;\n /** @availableWhen rotType==bar */\n @property({type: Number}) rotArcExtent: number = 60;\n @property({type: Boolean}) rotPortStarboard: boolean = false;\n /** @availableWhen rotType==bar */\n @property({type: Number}) rotAtZeroDeadband: number = ROT_ZERO_DEADBAND_DEG;\n @property({type: String}) direction: CompassDirection =\n CompassDirection.NorthUp;\n @property({type: String}) state: InstrumentState = InstrumentState.active;\n /** Color priority: `Priority.enhanced` uses the blue/enhanced color palette, `Priority.regular` (default) uses the standard palette. */\n @property({type: String}) priority: Priority = Priority.regular;\n /** @availableWhen priority==enhanced */\n @property({type: Array, attribute: false})\n priorityElements: CompassPriorityElement[] = [CompassPriorityElement.hdg];\n /** Show compass NSEW labels. The north arrow is always shown, independent of this flag. */\n @property({type: Boolean}) showLabels: boolean = false;\n /** When true, labels and north arrow are placed inside the outer ring. */\n @property({type: Boolean}) tickmarksInside: boolean = false;\n /**\n * Outer-ring diameter in CSS pixels. When set, the instrument renders at a\n * fixed intrinsic size derived from the ring, arc shape and label reserve —\n * so instruments sharing the same value have identical ring circumference\n * regardless of label width or arc extent (like obc-donut-chart's\n * fixedHeight). When unset (default), the instrument fills its container.\n */\n @property({type: Number, attribute: 'face-diameter'})\n faceDiameter: number | undefined;\n\n private _headingSp = new SetpointBundle({\n angularWraparound: true,\n onAnimationEnd: () => this.requestUpdate(),\n });\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\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._headingSp.dispose();\n }\n\n // @ts-expect-error TS6133: The controller ensures that the render\n // function is called on resize of the element\n private _resizeController = new ResizeController(this, {});\n\n /**\n * Resolved rate of turn in degrees per minute, used to compute the bar\n * extent. Prefers the new physical API; falls back to the deprecated\n * `rotationsPerMinute` so existing consumers keep their visuals during\n * the deprecation window.\n */\n private get _effectiveRotDegPerMin(): number {\n return this.rateOfTurnDegreesPerMinute ?? this.rotationsPerMinute;\n }\n\n /**\n * Pixel cost of the outside decor: the always-rendered north-arrow glyph\n * plus, only while shown, the NSWE labels (both keep a constant on-screen\n * size via `1/scale` terms). Feeds the frame's width-aware reserve,\n * replacing the former empirical `72 + delta(clientSize)` padding.\n * Wind/current symbols at their default radius are covered by the base\n * padding of 72.\n */\n private getOutsideDecorPx(): number {\n if (this.tickmarksInside) {\n return 0;\n }\n return NORTH_ARROW_WIDTH_PX + (this.showLabels ? NSWE_LABEL_WIDTH_PX : 0);\n }\n\n /** Whether the host size styles were set by applyPinnedHostSize. */\n private _hostSizePinned = false;\n private _frame: RadialFrame | undefined;\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n this._hostSizePinned = applyPinnedHostSize(\n this,\n this._frame,\n this._hostSizePinned\n );\n }\n\n private get angleAdviceRaw(): AngleAdviceRaw[] {\n return this.headingAdvices.map(({minAngle, maxAngle, hinted, type}) => {\n const state =\n this.heading >= minAngle && this.heading <= maxAngle\n ? AdviceState.triggered\n : hinted\n ? AdviceState.hinted\n : AdviceState.regular;\n return {minAngle, maxAngle, type, state};\n });\n }\n\n private priorityFor(element: CompassPriorityElement): Priority {\n const selected = Array.isArray(this.priorityElements)\n ? this.priorityElements\n : [];\n return selected.includes(element) ? this.priority : Priority.regular;\n }\n\n private colorFor(element: CompassPriorityElement): string | undefined {\n return this.priorityFor(element) === Priority.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : undefined;\n }\n\n private readoutPriorityFor(source: CompassReadoutSource): Priority {\n switch (source) {\n case CompassReadoutSource.hdg:\n return this.priorityFor(CompassPriorityElement.hdg);\n case CompassReadoutSource.cog:\n return this.priorityFor(CompassPriorityElement.cog);\n case CompassReadoutSource.rot:\n return this.priorityFor(CompassPriorityElement.rot);\n }\n }\n\n private get hasCenterReadouts(): boolean {\n return this.centerReadouts.length > 0;\n }\n\n private getRotation(): number | undefined {\n if (this.direction === CompassDirection.NorthUp) {\n return undefined;\n } else if (this.direction === CompassDirection.HeadingUp) {\n return -this.heading;\n } else if (this.direction === CompassDirection.CourseUp) {\n return -this.courseOverGround;\n }\n return undefined;\n }\n\n override render() {\n const tickmarks: Tickmark[] = [\n {angle: 0, type: TickmarkType.main},\n {angle: 90, type: TickmarkType.main},\n {angle: 180, type: TickmarkType.main},\n {angle: 270, type: TickmarkType.main},\n ];\n\n const frame = computeRadialFrame({\n basePadding: 72,\n labelWidthPx: this.getOutsideDecorPx(),\n containerPx: measureContainerPx(this),\n faceDiameter: this.faceDiameter,\n });\n this._frame = frame;\n const viewBox = frame.viewBox;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .arcFrame=${frame}\n .advices=${this.angleAdviceRaw}\n .tickmarks=${tickmarks}\n .state=${this.state}\n .watchCircleType=${WatchCircleType.triple}\n .showLabels=${this.showLabels && !frame.labelsHidden}\n .tickmarksInside=${this.tickmarksInside}\n .crosshairEnabled=${true}\n .crosshairCenterCutout=${this.hasCenterReadouts}\n .northArrow=${true}\n .angleSetpoint=${this.headingSetpoint ?? undefined}\n .newAngleSetpoint=${this.newHeadingSetpoint}\n .atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}\n .angleSetpointAtZeroDeadband=${this.headingSetpointAtZeroDeadband}\n .setpointOverride=${this.headingSetpointOverride}\n .priority=${this.priority}\n .animateSetpoint=${this.animateSetpoint}\n .vessels=${this.hasCenterReadouts\n ? []\n : [\n {\n size: VesselImageSize.medium,\n vesselImage: this.vesselImage,\n transform: `rotate(${this.heading}deg)`,\n },\n ]}\n .windKnots=${this.currentWindSpeedKnots}\n .windFromDirectionDeg=${this.windFromDirection}\n .windColor=${this.colorFor(CompassPriorityElement.wind)}\n .current=${this.currentSpeed}\n .currentFromDirectionDeg=${this.currentFromDirection}\n .currentColor=${this.colorFor(CompassPriorityElement.current)}\n .rotation=${this.getRotation()}\n .rotType=${this.rotType}\n .rotPosition=${this.rotPosition}\n .rotStartAngle=${this.heading + (this.getRotation() ?? 0)}\n .rotEndAngle=${this.heading +\n (this._effectiveRotDegPerMin / (this.rotMaxValue || 1)) *\n this.rotArcExtent +\n (this.getRotation() ?? 0)}\n .rotPriority=${this.priorityFor(CompassPriorityElement.rot)}\n .rotPortStarboard=${this.rotPortStarboard}\n .rotAtZeroDeadband=${this.rotAtZeroDeadband}\n .rateOfTurnDegreesPerMinute=${this.rateOfTurnDegreesPerMinute}\n .rotDotAnimationFactor=${this.rotDotAnimationFactor}\n .rotationsPerMinute=${this.rotationsPerMinute}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\">\n ${hdgArrow(\n this.hdgArrowStyle,\n this.heading + (this.getRotation() ?? 0),\n this.priorityFor(CompassPriorityElement.hdg)\n )}\n ${cogArrow(\n this.cogArrowStyle,\n this.courseOverGround + (this.getRotation() ?? 0),\n this.priorityFor(CompassPriorityElement.cog)\n )}\n </svg>\n ${this.hasCenterReadouts\n ? html`<div class=\"center-readout-overlay\">\n ${renderCenterReadouts(\n resolveCompassCenterReadouts(this.centerReadouts, {\n heading: this.heading,\n courseOverGround: this.courseOverGround,\n rateOfTurnDegreesPerMinute: this.rateOfTurnDegreesPerMinute,\n priorityFor: (source) => this.readoutPriorityFor(source),\n })\n )}\n </div>`\n : nothing}\n </div>\n `;\n }\n\n static override styles = [\n centerReadoutStyles,\n 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 .center-readout-overlay {\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n }\n\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-compass': ObcCompass;\n }\n}\n"],"names":["CompassDirection","CompassPriorityElement"],"mappings":"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"}
|
|
@@ -32,6 +32,9 @@ export declare function clampCurrentSpeed(value: number | null): number | null;
|
|
|
32
32
|
* the enhanced (blue) palette.
|
|
33
33
|
* - **Vessel image**: configurable silhouette rotating with
|
|
34
34
|
* `vesselHeadingDeg` (vessel type).
|
|
35
|
+
* - **Pattern toggle & wave tuning**: `hasPattern` switches the band pattern
|
|
36
|
+
* off; `waveLength`, `waveHeight` and `waveSpeed` tune the band spacing,
|
|
37
|
+
* intensity and drift motion.
|
|
35
38
|
*
|
|
36
39
|
* ## Usage Guidelines
|
|
37
40
|
*
|
|
@@ -64,6 +67,28 @@ export declare class ObcCurrent extends LitElement {
|
|
|
64
67
|
currentFromDirection: number | null;
|
|
65
68
|
/** Color priority: `Priority.enhanced` uses the blue/enhanced palette (default: `Priority.regular`). */
|
|
66
69
|
priority: Priority;
|
|
70
|
+
/**
|
|
71
|
+
* Show the force-graphics band pattern behind the watch face.
|
|
72
|
+
* @availableWhen currentFromDirection!=null
|
|
73
|
+
*/
|
|
74
|
+
hasPattern: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Wavelength of the pattern bands as a multiplier on the design spacing
|
|
77
|
+
* (1 = design, 0.5 = twice as dense).
|
|
78
|
+
* @availableWhen hasPattern==true && currentFromDirection!=null
|
|
79
|
+
*/
|
|
80
|
+
waveLength: number;
|
|
81
|
+
/**
|
|
82
|
+
* Wave intensity: the peak opacity the pattern bands fade up to (0–1).
|
|
83
|
+
* @availableWhen hasPattern==true && currentFromDirection!=null
|
|
84
|
+
*/
|
|
85
|
+
waveHeight: number;
|
|
86
|
+
/**
|
|
87
|
+
* Drift speed of the pattern in wavelengths per second, moving with the
|
|
88
|
+
* flow (negative drifts against it); 0 keeps the pattern static.
|
|
89
|
+
* @availableWhen hasPattern==true && currentFromDirection!=null
|
|
90
|
+
*/
|
|
91
|
+
waveSpeed: number;
|
|
67
92
|
/**
|
|
68
93
|
* The image of the vessel.
|
|
69
94
|
* @availableWhen type==vessel
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"current.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/current/current.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAGzD,OAAO,EACL,WAAW,EAIZ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAGrC,oBAAY,WAAW;IACrB,MAAM,WAAW;IACjB,SAAS,cAAc;CACxB;
|
|
1
|
+
{"version":3,"file":"current.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/current/current.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAA2B,MAAM,KAAK,CAAC;AAGzD,OAAO,EACL,WAAW,EAIZ,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAGrC,oBAAY,WAAW;IACrB,MAAM,WAAW;IACjB,SAAS,cAAc;CACxB;AAeD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAKrE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBACa,UAAW,SAAQ,UAAU;IACxC,2FAA2F;IACjE,IAAI,EAAE,WAAW,CAAsB;IACjE;;;;OAIG;IACuB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAC7D,2DAA2D;IACjC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACrE,wGAAwG;IAC9E,QAAQ,EAAE,QAAQ,CAAoB;IAChE;;;OAGG;IAC0C,UAAU,UAAQ;IAC/D;;;;OAIG;IACuB,UAAU,SAAK;IACzC;;;OAGG;IACuB,UAAU,SAAK;IACzC;;;;OAIG;IACuB,SAAS,SAAK;IACxC;;;OAGG;IACuB,WAAW,EAAE,WAAW,CAA0B;IAC5E;;;OAGG;IACuB,gBAAgB,EAAE,MAAM,CAAK;IAEvD,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,QAAQ,GAEnB;IAEQ,MAAM;IAuCf,OAAO,CAAC,kBAAkB;IAuB1B,OAAgB,MAAM,0BAA2B;CAClD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,aAAa,EAAE,UAAU,CAAC;KAC3B;CACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { unsafeCSS, LitElement, html, nothing } from "lit";
|
|
2
2
|
import { property } from "lit/decorators.js";
|
|
3
3
|
import compentStyle from "./current.css.js";
|
|
4
|
-
import {
|
|
4
|
+
import { innerRingRadiusFor, WatchCircleType } from "../watch/watch.js";
|
|
5
5
|
import { renderCurrentForcePattern } from "../watch/force-pattern.js";
|
|
6
6
|
import { Priority } from "../types.js";
|
|
7
7
|
import { customElement } from "../../decorator.js";
|
|
@@ -23,7 +23,9 @@ var CurrentType = /* @__PURE__ */ ((CurrentType2) => {
|
|
|
23
23
|
})(CurrentType || {});
|
|
24
24
|
const CURRENT_PATTERN_SCALE_VESSEL = 1.39;
|
|
25
25
|
const CURRENT_PATTERN_SCALE_DIRECTION = 2;
|
|
26
|
-
const CURRENT_ICON_PERIPHERY_RADIUS =
|
|
26
|
+
const CURRENT_ICON_PERIPHERY_RADIUS = innerRingRadiusFor(
|
|
27
|
+
WatchCircleType.double
|
|
28
|
+
);
|
|
27
29
|
const CURRENT_DIRECTION_ICON_SCALE = 7;
|
|
28
30
|
function clampCurrentSpeed(value) {
|
|
29
31
|
if (value == null || !Number.isFinite(value)) {
|
|
@@ -38,6 +40,10 @@ let ObcCurrent = class extends LitElement {
|
|
|
38
40
|
this.currentSpeed = null;
|
|
39
41
|
this.currentFromDirection = null;
|
|
40
42
|
this.priority = Priority.regular;
|
|
43
|
+
this.hasPattern = true;
|
|
44
|
+
this.waveLength = 1;
|
|
45
|
+
this.waveHeight = 1;
|
|
46
|
+
this.waveSpeed = 0;
|
|
41
47
|
this.vesselImage = VesselImage.genericTop;
|
|
42
48
|
this.vesselHeadingDeg = 0;
|
|
43
49
|
}
|
|
@@ -80,7 +86,7 @@ let ObcCurrent = class extends LitElement {
|
|
|
80
86
|
`;
|
|
81
87
|
}
|
|
82
88
|
renderForcePattern(watchCircleType) {
|
|
83
|
-
if (this.currentFromDirection == null) {
|
|
89
|
+
if (!this.hasPattern || this.currentFromDirection == null) {
|
|
84
90
|
return nothing;
|
|
85
91
|
}
|
|
86
92
|
return html`
|
|
@@ -89,7 +95,10 @@ let ObcCurrent = class extends LitElement {
|
|
|
89
95
|
fromDirectionDeg: this.currentFromDirection,
|
|
90
96
|
radius: innerRingRadiusFor(watchCircleType),
|
|
91
97
|
patternScale: this.isVesselType ? CURRENT_PATTERN_SCALE_VESSEL : CURRENT_PATTERN_SCALE_DIRECTION,
|
|
92
|
-
color: this.enhanced ? "var(--instrument-enhanced-tertiary-color)" : void 0
|
|
98
|
+
color: this.enhanced ? "var(--instrument-enhanced-tertiary-color)" : void 0,
|
|
99
|
+
waveLength: this.waveLength,
|
|
100
|
+
waveHeight: this.waveHeight,
|
|
101
|
+
waveSpeed: this.waveSpeed
|
|
93
102
|
})}
|
|
94
103
|
</svg>
|
|
95
104
|
`;
|
|
@@ -108,6 +117,18 @@ __decorateClass([
|
|
|
108
117
|
__decorateClass([
|
|
109
118
|
property({ type: String })
|
|
110
119
|
], ObcCurrent.prototype, "priority", 2);
|
|
120
|
+
__decorateClass([
|
|
121
|
+
property({ type: Boolean, attribute: false })
|
|
122
|
+
], ObcCurrent.prototype, "hasPattern", 2);
|
|
123
|
+
__decorateClass([
|
|
124
|
+
property({ type: Number })
|
|
125
|
+
], ObcCurrent.prototype, "waveLength", 2);
|
|
126
|
+
__decorateClass([
|
|
127
|
+
property({ type: Number })
|
|
128
|
+
], ObcCurrent.prototype, "waveHeight", 2);
|
|
129
|
+
__decorateClass([
|
|
130
|
+
property({ type: Number })
|
|
131
|
+
], ObcCurrent.prototype, "waveSpeed", 2);
|
|
111
132
|
__decorateClass([
|
|
112
133
|
property({ type: String })
|
|
113
134
|
], ObcCurrent.prototype, "vesselImage", 2);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"current.js","sources":["../../../src/navigation-instruments/current/current.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './current.css?inline';\nimport {\n VesselImage,\n VesselImageSize,\n WatchCircleType,\n innerRingRadiusFor,\n} from '../watch/watch.js';\nimport {renderCurrentForcePattern} from '../watch/force-pattern.js';\nimport {Priority} from '../types.js';\nimport {customElement} from '../../decorator.js';\n\nexport enum CurrentType {\n vessel = 'vessel',\n direction = 'direction',\n}\n\nconst CURRENT_PATTERN_SCALE_VESSEL = 1.39;\nconst CURRENT_PATTERN_SCALE_DIRECTION = 2.0;\n/** Chevron-tip anchor radius for the peripheral icon (vessel type), from Figma. */\nconst CURRENT_ICON_PERIPHERY_RADIUS = 116;\n/** Scale of the centered 24-unit chevron glyph (direction type), from Figma (168/24). */\nconst CURRENT_DIRECTION_ICON_SCALE = 7;\n\n/**\n * Round a current speed to the nearest chevron bucket (`current-0` …\n * `current-4` icons) and clamp it into that range. Non-finite input maps to\n * `null` (no icon).\n */\nexport function clampCurrentSpeed(value: number | null): number | null {\n if (value == null || !Number.isFinite(value)) {\n return null;\n }\n return Math.min(4, Math.max(0, Math.round(value)));\n}\n\n/**\n * `<obc-current>` – Water-current instrument with direction chevrons and a\n * force-graphics band pattern.\n *\n * Renders the current's from-direction and strength on a circular watch\n * face. Two layouts are available via `type`: `vessel` (default) shows a\n * vessel silhouette on a double-ring track face with a chevron icon at the\n * periphery pointing with the flow; `direction` shows a single-ring face\n * with a large centered chevron icon. In both, a soft band pattern fills the\n * face, rotated perpendicular to the flow.\n *\n * ## Features\n *\n * - **Types**: `vessel` (track face + vessel + peripheral icon) or\n * `direction` (single ring + large centered icon) via `type`.\n * - **Strength buckets**: `currentSpeed` selects the chevron icon\n * (`0`–`4` = number of chevrons); values are rounded and clamped.\n * - **Color priority**: `priority=enhanced` switches the pattern and icon to\n * the enhanced (blue) palette.\n * - **Vessel image**: configurable silhouette rotating with\n * `vesselHeadingDeg` (vessel type).\n *\n * ## Usage Guidelines\n *\n * Set `currentSpeed` and `currentFromDirection` to the sensor values. Use\n * `obc-wind` for the analogous wind instrument; use `obc-compass` when the\n * current indicator should overlay a full compass.\n *\n * ## Example\n *\n * ```html\n * <obc-current\n * currentSpeed=\"3\"\n * currentFromDirection=\"330\"\n * vesselHeadingDeg=\"15\"\n * ></obc-current>\n * ```\n *\n * @experimental\n */\n@customElement('obc-current')\nexport class ObcCurrent extends LitElement {\n /** Layout type: `vessel` (track face with vessel) or `direction` (large centered icon). */\n @property({type: String}) type: CurrentType = CurrentType.vessel;\n /**\n * The current strength as a chevron bucket (0–4 = number of chevrons);\n * rounded and clamped. `null` hides the icon.\n * @availableWhen currentFromDirection!=null\n */\n @property({type: Number}) currentSpeed: number | null = null;\n /** The direction the current is coming from in degrees. */\n @property({type: Number}) currentFromDirection: number | null = null;\n /** Color priority: `Priority.enhanced` uses the blue/enhanced palette (default: `Priority.regular`). */\n @property({type: String}) priority: Priority = Priority.regular;\n /**\n * The image of the vessel.\n * @availableWhen type==vessel\n */\n @property({type: String}) vesselImage: VesselImage = VesselImage.genericTop;\n /**\n * Vessel heading in degrees.\n * @availableWhen type==vessel\n */\n @property({type: Number}) vesselHeadingDeg: number = 0;\n\n private get isVesselType(): boolean {\n return this.type !== CurrentType.direction;\n }\n\n private get enhanced(): boolean {\n return this.priority === Priority.enhanced;\n }\n\n override render() {\n const isVessel = this.isVesselType;\n const watchCircleType = isVessel\n ? WatchCircleType.double\n : WatchCircleType.single;\n const vessels = isVessel\n ? [\n {\n size: VesselImageSize.medium,\n transform: `rotate(${this.vesselHeadingDeg}deg)`,\n vesselImage: this.vesselImage,\n },\n ]\n : [];\n return html`\n <div class=\"wrapper\">\n ${this.renderForcePattern(watchCircleType)}\n <obc-watch\n .watchCircleType=${watchCircleType}\n .priority=${this.priority}\n .vessels=${vessels}\n .current=${clampCurrentSpeed(this.currentSpeed)}\n .currentFromDirectionDeg=${this.currentFromDirection}\n .currentSymbolRadius=${CURRENT_ICON_PERIPHERY_RADIUS}\n .currentIconCentered=${!isVessel}\n .scaleCurrentIcon=${isVessel ? 1 : CURRENT_DIRECTION_ICON_SCALE}\n .currentColor=${this.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : undefined}\n .showLabels=${true}\n .insideLabelsFlush=${true}\n crosshairEnabled\n northArrow\n tickmarksInside\n ></obc-watch>\n </div>\n `;\n }\n\n private renderForcePattern(watchCircleType: WatchCircleType) {\n if (this.currentFromDirection == null) {\n return nothing;\n }\n return html`\n <svg width=\"100%\" height=\"100%\" viewBox=\"-200 -200 400 400\">\n ${renderCurrentForcePattern({\n fromDirectionDeg: this.currentFromDirection,\n radius: innerRingRadiusFor(watchCircleType),\n patternScale: this.isVesselType\n ? CURRENT_PATTERN_SCALE_VESSEL\n : CURRENT_PATTERN_SCALE_DIRECTION,\n color: this.enhanced\n ? 'var(--instrument-enhanced-tertiary-color)'\n : undefined,\n })}\n </svg>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-current': ObcCurrent;\n }\n}\n"],"names":["CurrentType"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"current.js","sources":["../../../src/navigation-instruments/current/current.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport compentStyle from './current.css?inline';\nimport {\n VesselImage,\n VesselImageSize,\n WatchCircleType,\n innerRingRadiusFor,\n} from '../watch/watch.js';\nimport {renderCurrentForcePattern} from '../watch/force-pattern.js';\nimport {Priority} from '../types.js';\nimport {customElement} from '../../decorator.js';\n\nexport enum CurrentType {\n vessel = 'vessel',\n direction = 'direction',\n}\n\nconst CURRENT_PATTERN_SCALE_VESSEL = 1.39;\nconst CURRENT_PATTERN_SCALE_DIRECTION = 2.0;\n/**\n * Chevron-tip anchor radius for the peripheral icon (vessel type): the tip\n * sits on the track band's inner edge (112), so the 48-unit glyph box fills\n * the band (112–160) exactly, per the OpenBridge 6.1 design.\n */\nconst CURRENT_ICON_PERIPHERY_RADIUS = innerRingRadiusFor(\n WatchCircleType.double\n);\n/** Scale of the centered 24-unit chevron glyph (direction type), from Figma (168/24). */\nconst CURRENT_DIRECTION_ICON_SCALE = 7;\n\n/**\n * Round a current speed to the nearest chevron bucket (`current-0` …\n * `current-4` icons) and clamp it into that range. Non-finite input maps to\n * `null` (no icon).\n */\nexport function clampCurrentSpeed(value: number | null): number | null {\n if (value == null || !Number.isFinite(value)) {\n return null;\n }\n return Math.min(4, Math.max(0, Math.round(value)));\n}\n\n/**\n * `<obc-current>` – Water-current instrument with direction chevrons and a\n * force-graphics band pattern.\n *\n * Renders the current's from-direction and strength on a circular watch\n * face. Two layouts are available via `type`: `vessel` (default) shows a\n * vessel silhouette on a double-ring track face with a chevron icon at the\n * periphery pointing with the flow; `direction` shows a single-ring face\n * with a large centered chevron icon. In both, a soft band pattern fills the\n * face, rotated perpendicular to the flow.\n *\n * ## Features\n *\n * - **Types**: `vessel` (track face + vessel + peripheral icon) or\n * `direction` (single ring + large centered icon) via `type`.\n * - **Strength buckets**: `currentSpeed` selects the chevron icon\n * (`0`–`4` = number of chevrons); values are rounded and clamped.\n * - **Color priority**: `priority=enhanced` switches the pattern and icon to\n * the enhanced (blue) palette.\n * - **Vessel image**: configurable silhouette rotating with\n * `vesselHeadingDeg` (vessel type).\n * - **Pattern toggle & wave tuning**: `hasPattern` switches the band pattern\n * off; `waveLength`, `waveHeight` and `waveSpeed` tune the band spacing,\n * intensity and drift motion.\n *\n * ## Usage Guidelines\n *\n * Set `currentSpeed` and `currentFromDirection` to the sensor values. Use\n * `obc-wind` for the analogous wind instrument; use `obc-compass` when the\n * current indicator should overlay a full compass.\n *\n * ## Example\n *\n * ```html\n * <obc-current\n * currentSpeed=\"3\"\n * currentFromDirection=\"330\"\n * vesselHeadingDeg=\"15\"\n * ></obc-current>\n * ```\n *\n * @experimental\n */\n@customElement('obc-current')\nexport class ObcCurrent extends LitElement {\n /** Layout type: `vessel` (track face with vessel) or `direction` (large centered icon). */\n @property({type: String}) type: CurrentType = CurrentType.vessel;\n /**\n * The current strength as a chevron bucket (0–4 = number of chevrons);\n * rounded and clamped. `null` hides the icon.\n * @availableWhen currentFromDirection!=null\n */\n @property({type: Number}) currentSpeed: number | null = null;\n /** The direction the current is coming from in degrees. */\n @property({type: Number}) currentFromDirection: number | null = null;\n /** Color priority: `Priority.enhanced` uses the blue/enhanced palette (default: `Priority.regular`). */\n @property({type: String}) priority: Priority = Priority.regular;\n /**\n * Show the force-graphics band pattern behind the watch face.\n * @availableWhen currentFromDirection!=null\n */\n @property({type: Boolean, attribute: false}) hasPattern = true;\n /**\n * Wavelength of the pattern bands as a multiplier on the design spacing\n * (1 = design, 0.5 = twice as dense).\n * @availableWhen hasPattern==true && currentFromDirection!=null\n */\n @property({type: Number}) waveLength = 1;\n /**\n * Wave intensity: the peak opacity the pattern bands fade up to (0–1).\n * @availableWhen hasPattern==true && currentFromDirection!=null\n */\n @property({type: Number}) waveHeight = 1;\n /**\n * Drift speed of the pattern in wavelengths per second, moving with the\n * flow (negative drifts against it); 0 keeps the pattern static.\n * @availableWhen hasPattern==true && currentFromDirection!=null\n */\n @property({type: Number}) waveSpeed = 0;\n /**\n * The image of the vessel.\n * @availableWhen type==vessel\n */\n @property({type: String}) vesselImage: VesselImage = VesselImage.genericTop;\n /**\n * Vessel heading in degrees.\n * @availableWhen type==vessel\n */\n @property({type: Number}) vesselHeadingDeg: number = 0;\n\n private get isVesselType(): boolean {\n return this.type !== CurrentType.direction;\n }\n\n private get enhanced(): boolean {\n return this.priority === Priority.enhanced;\n }\n\n override render() {\n const isVessel = this.isVesselType;\n const watchCircleType = isVessel\n ? WatchCircleType.double\n : WatchCircleType.single;\n const vessels = isVessel\n ? [\n {\n size: VesselImageSize.medium,\n transform: `rotate(${this.vesselHeadingDeg}deg)`,\n vesselImage: this.vesselImage,\n },\n ]\n : [];\n return html`\n <div class=\"wrapper\">\n ${this.renderForcePattern(watchCircleType)}\n <obc-watch\n .watchCircleType=${watchCircleType}\n .priority=${this.priority}\n .vessels=${vessels}\n .current=${clampCurrentSpeed(this.currentSpeed)}\n .currentFromDirectionDeg=${this.currentFromDirection}\n .currentSymbolRadius=${CURRENT_ICON_PERIPHERY_RADIUS}\n .currentIconCentered=${!isVessel}\n .scaleCurrentIcon=${isVessel ? 1 : CURRENT_DIRECTION_ICON_SCALE}\n .currentColor=${this.enhanced\n ? 'var(--instrument-enhanced-secondary-color)'\n : undefined}\n .showLabels=${true}\n .insideLabelsFlush=${true}\n crosshairEnabled\n northArrow\n tickmarksInside\n ></obc-watch>\n </div>\n `;\n }\n\n private renderForcePattern(watchCircleType: WatchCircleType) {\n if (!this.hasPattern || this.currentFromDirection == null) {\n return nothing;\n }\n return html`\n <svg width=\"100%\" height=\"100%\" viewBox=\"-200 -200 400 400\">\n ${renderCurrentForcePattern({\n fromDirectionDeg: this.currentFromDirection,\n radius: innerRingRadiusFor(watchCircleType),\n patternScale: this.isVesselType\n ? CURRENT_PATTERN_SCALE_VESSEL\n : CURRENT_PATTERN_SCALE_DIRECTION,\n color: this.enhanced\n ? 'var(--instrument-enhanced-tertiary-color)'\n : undefined,\n waveLength: this.waveLength,\n waveHeight: this.waveHeight,\n waveSpeed: this.waveSpeed,\n })}\n </svg>\n `;\n }\n\n static override styles = unsafeCSS(compentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-current': ObcCurrent;\n }\n}\n"],"names":["CurrentType"],"mappings":";;;;;;;;;;;;;;;;;;AAaO,IAAK,gCAAAA,iBAAL;AACLA,eAAA,QAAA,IAAS;AACTA,eAAA,WAAA,IAAY;AAFF,SAAAA;AAAA,GAAA,eAAA,CAAA,CAAA;AAKZ,MAAM,+BAA+B;AACrC,MAAM,kCAAkC;AAMxC,MAAM,gCAAgC;AAAA,EACpC,gBAAgB;AAClB;AAEA,MAAM,+BAA+B;AAO9B,SAAS,kBAAkB,OAAqC;AACrE,MAAI,SAAS,QAAQ,CAAC,OAAO,SAAS,KAAK,GAAG;AAC5C,WAAO;AAAA,EACT;AACA,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,CAAC;AACnD;AA8CO,IAAM,aAAN,cAAyB,WAAW;AAAA,EAApC,cAAA;AAAA,UAAA,GAAA,SAAA;AAEqB,SAAA,OAAoB;AAMpB,SAAA,eAA8B;AAE9B,SAAA,uBAAsC;AAEtC,SAAA,WAAqB,SAAS;AAKX,SAAA,aAAa;AAMhC,SAAA,aAAa;AAKb,SAAA,aAAa;AAMb,SAAA,YAAY;AAKZ,SAAA,cAA2B,YAAY;AAKvC,SAAA,mBAA2B;AAAA,EAAA;AAAA,EAErD,IAAY,eAAwB;AAClC,WAAO,KAAK,SAAS;AAAA,EACvB;AAAA,EAEA,IAAY,WAAoB;AAC9B,WAAO,KAAK,aAAa,SAAS;AAAA,EACpC;AAAA,EAES,SAAS;AAChB,UAAM,WAAW,KAAK;AACtB,UAAM,kBAAkB,WACpB,gBAAgB,SAChB,gBAAgB;AACpB,UAAM,UAAU,WACZ;AAAA,MACE;AAAA,QACE,MAAM,gBAAgB;AAAA,QACtB,WAAW,UAAU,KAAK,gBAAgB;AAAA,QAC1C,aAAa,KAAK;AAAA,MAAA;AAAA,IACpB,IAEF,CAAA;AACJ,WAAO;AAAA;AAAA,UAED,KAAK,mBAAmB,eAAe,CAAC;AAAA;AAAA,6BAErB,eAAe;AAAA,sBACtB,KAAK,QAAQ;AAAA,qBACd,OAAO;AAAA,qBACP,kBAAkB,KAAK,YAAY,CAAC;AAAA,qCACpB,KAAK,oBAAoB;AAAA,iCAC7B,6BAA6B;AAAA,iCAC7B,CAAC,QAAQ;AAAA,8BACZ,WAAW,IAAI,4BAA4B;AAAA,0BAC/C,KAAK,WACjB,+CACA,MAAS;AAAA,wBACC,IAAI;AAAA,+BACG,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjC;AAAA,EAEQ,mBAAmB,iBAAkC;AAC3D,QAAI,CAAC,KAAK,cAAc,KAAK,wBAAwB,MAAM;AACzD,aAAO;AAAA,IACT;AACA,WAAO;AAAA;AAAA,UAED,0BAA0B;AAAA,MAC1B,kBAAkB,KAAK;AAAA,MACvB,QAAQ,mBAAmB,eAAe;AAAA,MAC1C,cAAc,KAAK,eACf,+BACA;AAAA,MACJ,OAAO,KAAK,WACR,8CACA;AAAA,MACJ,YAAY,KAAK;AAAA,MACjB,YAAY,KAAK;AAAA,MACjB,WAAW,KAAK;AAAA,IAAA,CACjB,CAAC;AAAA;AAAA;AAAA,EAGR;AAGF;AArHa,WAoHK,SAAS,UAAU,YAAY;AAlHrB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAFb,WAEe,WAAA,QAAA,CAAA;AAMA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GARb,WAQe,WAAA,gBAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAVb,WAUe,WAAA,wBAAA,CAAA;AAEA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAZb,WAYe,WAAA,YAAA,CAAA;AAKmB,gBAAA;AAAA,EAA5C,SAAS,EAAC,MAAM,SAAS,WAAW,OAAM;AAAA,GAjBhC,WAiBkC,WAAA,cAAA,CAAA;AAMnB,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAvBb,WAuBe,WAAA,cAAA,CAAA;AAKA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA5Bb,WA4Be,WAAA,cAAA,CAAA;AAMA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAlCb,WAkCe,WAAA,aAAA,CAAA;AAKA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GAvCb,WAuCe,WAAA,eAAA,CAAA;AAKA,gBAAA;AAAA,EAAzB,SAAS,EAAC,MAAM,OAAA,CAAO;AAAA,GA5Cb,WA4Ce,WAAA,oBAAA,CAAA;AA5Cf,aAAN,gBAAA;AAAA,EADN,cAAc,aAAa;AAAA,GACf,UAAA;"}
|
|
@@ -181,7 +181,7 @@ let ObcHeading = class extends LitElement {
|
|
|
181
181
|
.tickmarksInside=${this.tickmarksInside}
|
|
182
182
|
.crosshairEnabled=${true}
|
|
183
183
|
.crosshairCenterCutout=${this.hasCenterReadouts}
|
|
184
|
-
.northArrow=${
|
|
184
|
+
.northArrow=${true}
|
|
185
185
|
.angleSetpoint=${this.headingSetpoint ?? void 0}
|
|
186
186
|
.newAngleSetpoint=${this.newHeadingSetpoint}
|
|
187
187
|
.atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heading.js","sources":["../../../src/navigation-instruments/heading/heading.ts"],"sourcesContent":["import {LitElement, PropertyValues, css, html, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType} from '../watch/tickmark.js';\nimport {\n CogArrowStyle,\n HdgArrowStyle,\n cogArrow,\n hdgArrow,\n} from '../course-arrows/course-arrows.js';\nimport {\n CompassCenterReadout,\n CompassReadoutSource,\n centerReadoutStyles,\n renderCenterReadouts,\n resolveCompassCenterReadouts,\n} from '../readout/center-readout.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {\n applyPinnedHostSize,\n computeRadialFrame,\n measureContainerPx,\n NORTH_ARROW_WIDTH_PX,\n NSWE_LABEL_WIDTH_PX,\n type RadialFrame,\n} from '../../svghelpers/radial-frame.js';\nimport {VesselImage, VesselImageSize, WatchCircleType} from '../watch/watch.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {Priority} from '../types.js';\nimport {customElement} from '../../decorator.js';\nexport {HdgArrowStyle, CogArrowStyle};\nexport {CompassReadoutSource};\nexport type {CompassCenterReadout};\n\nexport enum CompassDirection {\n NorthUp = 'northUp',\n HeadingUp = 'headingUp',\n CourseUp = 'courseUp',\n}\n\nexport enum HeadingPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n}\n\n/**\n * `<obc-heading>` – Heading instrument with HDG/COG arrows over a single-ring\n * watch face, with optional vessel silhouette and center readouts.\n *\n * Renders a circular instrument that displays heading (HDG) and course over\n * ground (COG) as rotating arrows. It supports a heading setpoint with auto\n * at-setpoint detection, advice zones, north-up/heading-up/course-up\n * orientation, an optional vessel image, and center readouts replacing the\n * vessel.\n *\n * ## Features\n *\n * - **Direction modes**: `northUp` (default), `headingUp`, or `courseUp`\n * via the `direction` property.\n * - **HDG / COG arrows**: Two arrows overlay the watch face, rotating\n * independently; their look is selected per arrow via `hdgArrowStyle`\n * (`needle` default, `arrowHead`, `vector`, `beamLine`) and\n * `cogArrowStyle` (`needle` default, `arrowHead`, `vector`,\n * `velocityVector`).\n * - **Vessel image**: Optional vessel silhouette via `vesselImage`\n * (hidden by default), centered and rotating with heading.\n * - **Center readouts**: `centerReadouts` replaces the vessel with up to\n * three readouts (first on top, the rest below a horizontal divider);\n * values bind to the instrument's own inputs per entry `source`.\n * - **Heading setpoint**: Optional setpoint marker with auto at-setpoint\n * detection via `headingSetpoint`, `atHeadingSetpoint`, and deadband\n * tuning properties.\n * - **Advice zones**: Pass `headingAdvices` to render caution/alert arcs.\n * - **Color priority**: Set `priority` to `Priority.enhanced` and select\n * the accented elements via `priorityElements`.\n *\n * ## Usage Guidelines\n *\n * - Set `heading` and `courseOverGround` to the current sensor values in\n * degrees.\n * - Use `obc-compass` instead when rate-of-turn, wind or current overlays\n * are needed — this instrument is the reduced heading-focused variant.\n *\n * ## Example\n *\n * ```html\n * <obc-heading\n * heading=\"45\"\n * courseOverGround=\"50\"\n * direction=\"northUp\"\n * headingSetpoint=\"90\"\n * ></obc-heading>\n * ```\n *\n * @ignition-base-height: 512px\n * @ignition-base-width: 512px\n * @stable\n */\n@customElement('obc-heading')\nexport class ObcHeading extends LitElement {\n @property({type: Number}) heading = 0;\n @property({type: Number}) courseOverGround = 0;\n\n @property({type: Number}) headingSetpoint: number | null = null;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) newHeadingSetpoint: number | undefined;\n /** @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==false */\n @property({type: Boolean}) atHeadingSetpoint: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) headingSetpointAtZeroDeadband: number = 0.5;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) headingSetpointOverride: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean, attribute: false}) autoAtHeadingSetpoint: boolean =\n true;\n /** @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==true */\n @property({type: Number}) autoAtHeadingSetpointDeadband: number = 2;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) animateSetpoint: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) touching: boolean = false;\n @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];\n @property({type: String}) direction: CompassDirection =\n CompassDirection.NorthUp;\n @property({type: String}) priority: Priority = Priority.regular;\n /** @availableWhen priority==enhanced */\n @property({type: Array, attribute: false})\n priorityElements: HeadingPriorityElement[] = [HeadingPriorityElement.hdg];\n /**\n * The vessel silhouette shown in the center, rotating with heading. When\n * unset (default) no vessel is shown; hidden while `centerReadouts` is\n * non-empty.\n * @availableWhen centerReadouts==[]\n */\n @property({type: String}) vesselImage: VesselImage | undefined;\n /**\n * Center readouts replacing the vessel: the first entry renders on top,\n * the rest side by side below a horizontal divider. Values bind per entry\n * `source` (`hdg` → `heading`, `cog` → `courseOverGround`; `rot` has no\n * input on this instrument and renders a dash) and colors follow\n * `priorityElements`. While non-empty, the crosshair's center is cut out\n * so the readouts sit on a clean face.\n */\n @property({type: Array, attribute: false})\n centerReadouts: CompassCenterReadout[] = [];\n /** HDG arrow style: `needle` (default), `arrowHead`, `vector`, or `beamLine`. */\n @property({type: String}) hdgArrowStyle: HdgArrowStyle = HdgArrowStyle.needle;\n /** COG arrow style: `needle` (default), `arrowHead`, `vector`, or `velocityVector`. */\n @property({type: String}) cogArrowStyle: CogArrowStyle = CogArrowStyle.needle;\n /** Show compass NSEW labels. */\n @property({type: Boolean}) showLabels: boolean = false;\n /** When true, labels and north arrow are placed inside the outer ring. */\n @property({type: Boolean}) tickmarksInside: boolean = false;\n /**\n * Outer-ring diameter in CSS pixels. When set, the instrument renders at a\n * fixed intrinsic size derived from the ring, arc shape and label reserve —\n * so instruments sharing the same value have identical ring circumference\n * regardless of label width or arc extent (like obc-donut-chart's\n * fixedHeight). When unset (default), the instrument fills its container.\n */\n @property({type: Number, attribute: 'face-diameter'})\n faceDiameter: number | undefined;\n\n private _headingSp = new SetpointBundle({\n angularWraparound: true,\n onAnimationEnd: () => this.requestUpdate(),\n });\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\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._headingSp.dispose();\n }\n\n // @ts-expect-error TS6133: The controller ensures that the render\n // function is called on resize of the element\n private _resizeController = new ResizeController(this, {});\n\n /**\n * Pixel cost of the outside decor: the always-rendered north-arrow glyph\n * plus, only while shown, the NSWE labels (both keep a constant on-screen\n * size via `1/scale` terms). Feeds the frame's width-aware reserve,\n * replacing the former empirical `72 + delta(clientSize)` padding.\n */\n private getOutsideDecorPx(): number {\n if (this.tickmarksInside) {\n return 0;\n }\n return NORTH_ARROW_WIDTH_PX + (this.showLabels ? NSWE_LABEL_WIDTH_PX : 0);\n }\n\n /** Whether the host size styles were set by applyPinnedHostSize. */\n private _hostSizePinned = false;\n private _frame: RadialFrame | undefined;\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n this._hostSizePinned = applyPinnedHostSize(\n this,\n this._frame,\n this._hostSizePinned\n );\n }\n\n private get angleAdviceRaw(): AngleAdviceRaw[] {\n return this.headingAdvices.map(({minAngle, maxAngle, hinted, type}) => {\n const state =\n this.heading >= minAngle && this.heading <= maxAngle\n ? AdviceState.triggered\n : hinted\n ? AdviceState.hinted\n : AdviceState.regular;\n return {minAngle, maxAngle, type, state};\n });\n }\n\n private priorityFor(element: HeadingPriorityElement): Priority {\n const selected = Array.isArray(this.priorityElements)\n ? this.priorityElements\n : [];\n return selected.includes(element) ? this.priority : Priority.regular;\n }\n\n private readoutPriorityFor(source: CompassReadoutSource): Priority {\n if (source === CompassReadoutSource.hdg) {\n return this.priorityFor(HeadingPriorityElement.hdg);\n }\n if (source === CompassReadoutSource.cog) {\n return this.priorityFor(HeadingPriorityElement.cog);\n }\n return Priority.regular;\n }\n\n private get hasCenterReadouts(): boolean {\n return this.centerReadouts.length > 0;\n }\n\n /**\n * The face gains the double-band ring while center content (vessel or\n * readouts) is shown, per the design's vessel/center-label faces.\n */\n private get watchCircleType(): WatchCircleType {\n return this.vesselImage !== undefined || this.hasCenterReadouts\n ? WatchCircleType.double\n : WatchCircleType.single;\n }\n\n private getRotation(): number | undefined {\n if (this.direction === CompassDirection.NorthUp) {\n return undefined;\n } else if (this.direction === CompassDirection.HeadingUp) {\n return -this.heading;\n } else if (this.direction === CompassDirection.CourseUp) {\n return -this.courseOverGround;\n }\n return undefined;\n }\n\n override render() {\n const tickmarks: Tickmark[] = [\n {angle: 0, type: TickmarkType.main},\n {angle: 90, type: TickmarkType.main},\n {angle: 180, type: TickmarkType.main},\n {angle: 270, type: TickmarkType.main},\n ];\n\n const frame = computeRadialFrame({\n basePadding: 72,\n labelWidthPx: this.getOutsideDecorPx(),\n containerPx: measureContainerPx(this),\n faceDiameter: this.faceDiameter,\n });\n this._frame = frame;\n const viewBox = frame.viewBox;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .arcFrame=${frame}\n .advices=${this.angleAdviceRaw}\n .tickmarks=${tickmarks}\n .watchCircleType=${this.watchCircleType}\n .vessels=${this.vesselImage !== undefined && !this.hasCenterReadouts\n ? [\n {\n size: VesselImageSize.medium,\n vesselImage: this.vesselImage,\n transform: `rotate(${this.heading}deg)`,\n },\n ]\n : []}\n .showLabels=${this.showLabels && !frame.labelsHidden}\n .tickmarksInside=${this.tickmarksInside}\n .crosshairEnabled=${true}\n .crosshairCenterCutout=${this.hasCenterReadouts}\n .northArrow=${!frame.labelsHidden}\n .angleSetpoint=${this.headingSetpoint ?? undefined}\n .newAngleSetpoint=${this.newHeadingSetpoint}\n .atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}\n .angleSetpointAtZeroDeadband=${this.headingSetpointAtZeroDeadband}\n .setpointOverride=${this.headingSetpointOverride}\n .priority=${this.priority}\n .animateSetpoint=${this.animateSetpoint}\n .rotation=${this.getRotation()}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\">\n ${hdgArrow(\n this.hdgArrowStyle,\n this.heading + (this.getRotation() ?? 0),\n this.priorityFor(HeadingPriorityElement.hdg)\n )}\n ${cogArrow(\n this.cogArrowStyle,\n this.courseOverGround + (this.getRotation() ?? 0),\n this.priorityFor(HeadingPriorityElement.cog)\n )}\n </svg>\n ${this.hasCenterReadouts\n ? html`<div class=\"center-readout-overlay\">\n ${renderCenterReadouts(\n resolveCompassCenterReadouts(this.centerReadouts, {\n heading: this.heading,\n courseOverGround: this.courseOverGround,\n priorityFor: (source) => this.readoutPriorityFor(source),\n })\n )}\n </div>`\n : nothing}\n </div>\n `;\n }\n\n static override styles = [\n centerReadoutStyles,\n 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 .center-readout-overlay {\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n }\n\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-heading': ObcHeading;\n }\n}\n"],"names":["CompassDirection","HeadingPriorityElement"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"heading.js","sources":["../../../src/navigation-instruments/heading/heading.ts"],"sourcesContent":["import {LitElement, PropertyValues, css, html, nothing} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport '../watch/watch.js';\nimport {Tickmark, TickmarkType} from '../watch/tickmark.js';\nimport {\n CogArrowStyle,\n HdgArrowStyle,\n cogArrow,\n hdgArrow,\n} from '../course-arrows/course-arrows.js';\nimport {\n CompassCenterReadout,\n CompassReadoutSource,\n centerReadoutStyles,\n renderCenterReadouts,\n resolveCompassCenterReadouts,\n} from '../readout/center-readout.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {\n applyPinnedHostSize,\n computeRadialFrame,\n measureContainerPx,\n NORTH_ARROW_WIDTH_PX,\n NSWE_LABEL_WIDTH_PX,\n type RadialFrame,\n} from '../../svghelpers/radial-frame.js';\nimport {VesselImage, VesselImageSize, WatchCircleType} from '../watch/watch.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {Priority} from '../types.js';\nimport {customElement} from '../../decorator.js';\nexport {HdgArrowStyle, CogArrowStyle};\nexport {CompassReadoutSource};\nexport type {CompassCenterReadout};\n\nexport enum CompassDirection {\n NorthUp = 'northUp',\n HeadingUp = 'headingUp',\n CourseUp = 'courseUp',\n}\n\nexport enum HeadingPriorityElement {\n hdg = 'hdg',\n cog = 'cog',\n}\n\n/**\n * `<obc-heading>` – Heading instrument with HDG/COG arrows over a single-ring\n * watch face, with optional vessel silhouette and center readouts.\n *\n * Renders a circular instrument that displays heading (HDG) and course over\n * ground (COG) as rotating arrows. It supports a heading setpoint with auto\n * at-setpoint detection, advice zones, north-up/heading-up/course-up\n * orientation, an optional vessel image, and center readouts replacing the\n * vessel.\n *\n * ## Features\n *\n * - **Direction modes**: `northUp` (default), `headingUp`, or `courseUp`\n * via the `direction` property.\n * - **HDG / COG arrows**: Two arrows overlay the watch face, rotating\n * independently; their look is selected per arrow via `hdgArrowStyle`\n * (`needle` default, `arrowHead`, `vector`, `beamLine`) and\n * `cogArrowStyle` (`needle` default, `arrowHead`, `vector`,\n * `velocityVector`).\n * - **Vessel image**: Optional vessel silhouette via `vesselImage`\n * (hidden by default), centered and rotating with heading.\n * - **Center readouts**: `centerReadouts` replaces the vessel with up to\n * three readouts (first on top, the rest below a horizontal divider);\n * values bind to the instrument's own inputs per entry `source`.\n * - **Heading setpoint**: Optional setpoint marker with auto at-setpoint\n * detection via `headingSetpoint`, `atHeadingSetpoint`, and deadband\n * tuning properties.\n * - **Advice zones**: Pass `headingAdvices` to render caution/alert arcs.\n * - **Color priority**: Set `priority` to `Priority.enhanced` and select\n * the accented elements via `priorityElements`.\n *\n * ## Usage Guidelines\n *\n * - Set `heading` and `courseOverGround` to the current sensor values in\n * degrees.\n * - Use `obc-compass` instead when rate-of-turn, wind or current overlays\n * are needed — this instrument is the reduced heading-focused variant.\n *\n * ## Example\n *\n * ```html\n * <obc-heading\n * heading=\"45\"\n * courseOverGround=\"50\"\n * direction=\"northUp\"\n * headingSetpoint=\"90\"\n * ></obc-heading>\n * ```\n *\n * @ignition-base-height: 512px\n * @ignition-base-width: 512px\n * @stable\n */\n@customElement('obc-heading')\nexport class ObcHeading extends LitElement {\n @property({type: Number}) heading = 0;\n @property({type: Number}) courseOverGround = 0;\n\n @property({type: Number}) headingSetpoint: number | null = null;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) newHeadingSetpoint: number | undefined;\n /** @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==false */\n @property({type: Boolean}) atHeadingSetpoint: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Number}) headingSetpointAtZeroDeadband: number = 0.5;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) headingSetpointOverride: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean, attribute: false}) autoAtHeadingSetpoint: boolean =\n true;\n /** @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==true */\n @property({type: Number}) autoAtHeadingSetpointDeadband: number = 2;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) animateSetpoint: boolean = false;\n /** @availableWhen headingSetpoint!=null */\n @property({type: Boolean}) touching: boolean = false;\n @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];\n @property({type: String}) direction: CompassDirection =\n CompassDirection.NorthUp;\n @property({type: String}) priority: Priority = Priority.regular;\n /** @availableWhen priority==enhanced */\n @property({type: Array, attribute: false})\n priorityElements: HeadingPriorityElement[] = [HeadingPriorityElement.hdg];\n /**\n * The vessel silhouette shown in the center, rotating with heading. When\n * unset (default) no vessel is shown; hidden while `centerReadouts` is\n * non-empty.\n * @availableWhen centerReadouts==[]\n */\n @property({type: String}) vesselImage: VesselImage | undefined;\n /**\n * Center readouts replacing the vessel: the first entry renders on top,\n * the rest side by side below a horizontal divider. Values bind per entry\n * `source` (`hdg` → `heading`, `cog` → `courseOverGround`; `rot` has no\n * input on this instrument and renders a dash) and colors follow\n * `priorityElements`. While non-empty, the crosshair's center is cut out\n * so the readouts sit on a clean face.\n */\n @property({type: Array, attribute: false})\n centerReadouts: CompassCenterReadout[] = [];\n /** HDG arrow style: `needle` (default), `arrowHead`, `vector`, or `beamLine`. */\n @property({type: String}) hdgArrowStyle: HdgArrowStyle = HdgArrowStyle.needle;\n /** COG arrow style: `needle` (default), `arrowHead`, `vector`, or `velocityVector`. */\n @property({type: String}) cogArrowStyle: CogArrowStyle = CogArrowStyle.needle;\n /** Show compass NSEW labels. */\n @property({type: Boolean}) showLabels: boolean = false;\n /** When true, labels and north arrow are placed inside the outer ring. */\n @property({type: Boolean}) tickmarksInside: boolean = false;\n /**\n * Outer-ring diameter in CSS pixels. When set, the instrument renders at a\n * fixed intrinsic size derived from the ring, arc shape and label reserve —\n * so instruments sharing the same value have identical ring circumference\n * regardless of label width or arc extent (like obc-donut-chart's\n * fixedHeight). When unset (default), the instrument fills its container.\n */\n @property({type: Number, attribute: 'face-diameter'})\n faceDiameter: number | undefined;\n\n private _headingSp = new SetpointBundle({\n angularWraparound: true,\n onAnimationEnd: () => this.requestUpdate(),\n });\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\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._headingSp.dispose();\n }\n\n // @ts-expect-error TS6133: The controller ensures that the render\n // function is called on resize of the element\n private _resizeController = new ResizeController(this, {});\n\n /**\n * Pixel cost of the outside decor: the always-rendered north-arrow glyph\n * plus, only while shown, the NSWE labels (both keep a constant on-screen\n * size via `1/scale` terms). Feeds the frame's width-aware reserve,\n * replacing the former empirical `72 + delta(clientSize)` padding.\n */\n private getOutsideDecorPx(): number {\n if (this.tickmarksInside) {\n return 0;\n }\n return NORTH_ARROW_WIDTH_PX + (this.showLabels ? NSWE_LABEL_WIDTH_PX : 0);\n }\n\n /** Whether the host size styles were set by applyPinnedHostSize. */\n private _hostSizePinned = false;\n private _frame: RadialFrame | undefined;\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n this._hostSizePinned = applyPinnedHostSize(\n this,\n this._frame,\n this._hostSizePinned\n );\n }\n\n private get angleAdviceRaw(): AngleAdviceRaw[] {\n return this.headingAdvices.map(({minAngle, maxAngle, hinted, type}) => {\n const state =\n this.heading >= minAngle && this.heading <= maxAngle\n ? AdviceState.triggered\n : hinted\n ? AdviceState.hinted\n : AdviceState.regular;\n return {minAngle, maxAngle, type, state};\n });\n }\n\n private priorityFor(element: HeadingPriorityElement): Priority {\n const selected = Array.isArray(this.priorityElements)\n ? this.priorityElements\n : [];\n return selected.includes(element) ? this.priority : Priority.regular;\n }\n\n private readoutPriorityFor(source: CompassReadoutSource): Priority {\n if (source === CompassReadoutSource.hdg) {\n return this.priorityFor(HeadingPriorityElement.hdg);\n }\n if (source === CompassReadoutSource.cog) {\n return this.priorityFor(HeadingPriorityElement.cog);\n }\n return Priority.regular;\n }\n\n private get hasCenterReadouts(): boolean {\n return this.centerReadouts.length > 0;\n }\n\n /**\n * The face gains the double-band ring while center content (vessel or\n * readouts) is shown, per the design's vessel/center-label faces.\n */\n private get watchCircleType(): WatchCircleType {\n return this.vesselImage !== undefined || this.hasCenterReadouts\n ? WatchCircleType.double\n : WatchCircleType.single;\n }\n\n private getRotation(): number | undefined {\n if (this.direction === CompassDirection.NorthUp) {\n return undefined;\n } else if (this.direction === CompassDirection.HeadingUp) {\n return -this.heading;\n } else if (this.direction === CompassDirection.CourseUp) {\n return -this.courseOverGround;\n }\n return undefined;\n }\n\n override render() {\n const tickmarks: Tickmark[] = [\n {angle: 0, type: TickmarkType.main},\n {angle: 90, type: TickmarkType.main},\n {angle: 180, type: TickmarkType.main},\n {angle: 270, type: TickmarkType.main},\n ];\n\n const frame = computeRadialFrame({\n basePadding: 72,\n labelWidthPx: this.getOutsideDecorPx(),\n containerPx: measureContainerPx(this),\n faceDiameter: this.faceDiameter,\n });\n this._frame = frame;\n const viewBox = frame.viewBox;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .arcFrame=${frame}\n .advices=${this.angleAdviceRaw}\n .tickmarks=${tickmarks}\n .watchCircleType=${this.watchCircleType}\n .vessels=${this.vesselImage !== undefined && !this.hasCenterReadouts\n ? [\n {\n size: VesselImageSize.medium,\n vesselImage: this.vesselImage,\n transform: `rotate(${this.heading}deg)`,\n },\n ]\n : []}\n .showLabels=${this.showLabels && !frame.labelsHidden}\n .tickmarksInside=${this.tickmarksInside}\n .crosshairEnabled=${true}\n .crosshairCenterCutout=${this.hasCenterReadouts}\n .northArrow=${true}\n .angleSetpoint=${this.headingSetpoint ?? undefined}\n .newAngleSetpoint=${this.newHeadingSetpoint}\n .atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}\n .angleSetpointAtZeroDeadband=${this.headingSetpointAtZeroDeadband}\n .setpointOverride=${this.headingSetpointOverride}\n .priority=${this.priority}\n .animateSetpoint=${this.animateSetpoint}\n .rotation=${this.getRotation()}\n >\n </obc-watch>\n <svg viewBox=\"${viewBox}\">\n ${hdgArrow(\n this.hdgArrowStyle,\n this.heading + (this.getRotation() ?? 0),\n this.priorityFor(HeadingPriorityElement.hdg)\n )}\n ${cogArrow(\n this.cogArrowStyle,\n this.courseOverGround + (this.getRotation() ?? 0),\n this.priorityFor(HeadingPriorityElement.cog)\n )}\n </svg>\n ${this.hasCenterReadouts\n ? html`<div class=\"center-readout-overlay\">\n ${renderCenterReadouts(\n resolveCompassCenterReadouts(this.centerReadouts, {\n heading: this.heading,\n courseOverGround: this.courseOverGround,\n priorityFor: (source) => this.readoutPriorityFor(source),\n })\n )}\n </div>`\n : nothing}\n </div>\n `;\n }\n\n static override styles = [\n centerReadoutStyles,\n 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 .center-readout-overlay {\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n }\n\n :host {\n display: block;\n width: 100%;\n height: 100%;\n }\n `,\n ];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-heading': ObcHeading;\n }\n}\n"],"names":["CompassDirection","HeadingPriorityElement"],"mappings":"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"}
|
|
@@ -122,6 +122,12 @@ export declare class ObcPitchRollHeave extends LitElement {
|
|
|
122
122
|
* `obc-watch` renders its crosshair after the bands, i.e. on top of them.
|
|
123
123
|
* Drawing it here puts it under the watch layer, so the bands and the heave
|
|
124
124
|
* column mask it naturally.
|
|
125
|
+
*
|
|
126
|
+
* In `single-scale` nothing frames the segment above the vessel (the other
|
|
127
|
+
* three arms end under the pitch band, roll band and heave column), so the
|
|
128
|
+
* vertical arm stops at the centre instead of continuing upward. In
|
|
129
|
+
* `dual-scale` the top roll band gives it a natural endpoint, so the full
|
|
130
|
+
* arm is kept.
|
|
125
131
|
*/
|
|
126
132
|
private renderCrosshair;
|
|
127
133
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pitch-roll-heave.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/pitch-roll-heave/pitch-roll-heave.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAkD,MAAM,KAAK,CAAC;AAEhF,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EAOZ,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAgBrC,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,mDAAmD,CAAC;AAE3D,oBAAY,qBAAqB;IAC/B,2EAA2E;IAC3E,WAAW,iBAAiB;IAC5B,8DAA8D;IAC9D,SAAS,eAAe;CACzB;AAED,oBAAY,6BAA6B;IACvC,KAAK,UAAU;IACf,IAAI,SAAS;IACb,KAAK,UAAU;CAChB;AA2ED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBACa,iBAAkB,SAAQ,UAAU;IACrB,IAAI,EAAE,qBAAqB,CACjB;IAEV,KAAK,SAAK;IACV,IAAI,SAAK;IACT,KAAK,SAAK;IACV,WAAW,SAAK;IAChB,WAAW,SAAK;IAChB,UAAU,SAAK;IACf,UAAU,SAAK;IACf,aAAa,SAAK;IAClB,aAAa,SAAK;IAC5C,gFAAgF;IACtD,UAAU,SAAM;IAE1C;;;;OAIG;IACuB,aAAa,SAAM;IAC7C,8CAA8C;IACpB,YAAY,SAAM;IACjB,YAAY,UAAS;IAEhD;;;;;OAKG;IACwB,UAAU,UAAS;IAC9C,sCAAsC;IACZ,UAAU,SAAW;IAC/C,sCAAsC;IACZ,SAAS,SAAU;IAC7C,sCAAsC;IACZ,UAAU,SAAW;IAC/C;;;OAGG;IACuB,IAAI,SAAS;IACvC;;;OAGG;IACuB,SAAS,SAAO;IAC1C,sCAAsC;IACZ,cAAc,SAAK;IAE7C,4DAA4D;IAClC,eAAe,EAAE,WAAW,CAAuB;IAC7E,4DAA4D;IAClC,eAAe,EAAE,WAAW,CAAuB;IAC7E,4DAA4D;IAClC,cAAc,SAAK;IAEnB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAa;IAC/C,aAAa,EAAE,MAAM,GAAG,SAAS,CAAa;IACxE,+CAA+C;IACpB,kBAAkB,UAAS;IACtD,8CAA8C;IACnB,iBAAiB,UAAS;IAC5B,WAAW,EAAE,YAAY,EAAE,CAAM;IAEhC,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,gBAAgB,EAAE,6BAA6B,EAAE,CAI/C;IAEF,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,QAAQ;IAMhB,OAAO,KAAK,wBAAwB,GAKnC;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,8EAA8E;IAC9E,OAAO,KAAK,YAAY,GAEvB;IAED;;;OAGG;IACH,OAAO,KAAK,sBAAsB,GAKjC;IAED;;;;OAIG;IACH,OAAO,KAAK,qBAAqB,GAIhC;IAEQ,MAAM;IAuEf
|
|
1
|
+
{"version":3,"file":"pitch-roll-heave.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/pitch-roll-heave/pitch-roll-heave.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAkD,MAAM,KAAK,CAAC;AAEhF,OAAO,mBAAmB,CAAC;AAC3B,OAAO,EACL,WAAW,EAOZ,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAgBrC,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,mDAAmD,CAAC;AAE3D,oBAAY,qBAAqB;IAC/B,2EAA2E;IAC3E,WAAW,iBAAiB;IAC5B,8DAA8D;IAC9D,SAAS,eAAe;CACzB;AAED,oBAAY,6BAA6B;IACvC,KAAK,UAAU;IACf,IAAI,SAAS;IACb,KAAK,UAAU;CAChB;AA2ED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBACa,iBAAkB,SAAQ,UAAU;IACrB,IAAI,EAAE,qBAAqB,CACjB;IAEV,KAAK,SAAK;IACV,IAAI,SAAK;IACT,KAAK,SAAK;IACV,WAAW,SAAK;IAChB,WAAW,SAAK;IAChB,UAAU,SAAK;IACf,UAAU,SAAK;IACf,aAAa,SAAK;IAClB,aAAa,SAAK;IAC5C,gFAAgF;IACtD,UAAU,SAAM;IAE1C;;;;OAIG;IACuB,aAAa,SAAM;IAC7C,8CAA8C;IACpB,YAAY,SAAM;IACjB,YAAY,UAAS;IAEhD;;;;;OAKG;IACwB,UAAU,UAAS;IAC9C,sCAAsC;IACZ,UAAU,SAAW;IAC/C,sCAAsC;IACZ,SAAS,SAAU;IAC7C,sCAAsC;IACZ,UAAU,SAAW;IAC/C;;;OAGG;IACuB,IAAI,SAAS;IACvC;;;OAGG;IACuB,SAAS,SAAO;IAC1C,sCAAsC;IACZ,cAAc,SAAK;IAE7C,4DAA4D;IAClC,eAAe,EAAE,WAAW,CAAuB;IAC7E,4DAA4D;IAClC,eAAe,EAAE,WAAW,CAAuB;IAC7E,4DAA4D;IAClC,cAAc,SAAK;IAEnB,cAAc,EAAE,MAAM,GAAG,SAAS,CAAa;IAC/C,aAAa,EAAE,MAAM,GAAG,SAAS,CAAa;IACxE,+CAA+C;IACpB,kBAAkB,UAAS;IACtD,8CAA8C;IACnB,iBAAiB,UAAS;IAC5B,WAAW,EAAE,YAAY,EAAE,CAAM;IAEhC,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,gBAAgB,EAAE,6BAA6B,EAAE,CAI/C;IAEF,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,QAAQ;IAMhB,OAAO,KAAK,wBAAwB,GAKnC;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,8EAA8E;IAC9E,OAAO,KAAK,YAAY,GAEvB;IAED;;;OAGG;IACH,OAAO,KAAK,sBAAsB,GAKjC;IAED;;;;OAIG;IACH,OAAO,KAAK,qBAAqB,GAIhC;IAEQ,MAAM;IAuEf;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,eAAe;IAiBvB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAe5B;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;;;;;;;OAQG;IACH,OAAO,CAAC,iBAAiB;IA+CzB,OAAO,KAAK,YAAY,GAWvB;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,UAAU;IA2IlB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IA4GxB,uEAAuE;IACvE,OAAO,CAAC,UAAU;IA4BlB,yEAAyE;IACzE,OAAO,CAAC,eAAe;IAqGvB,OAAO,CAAC,OAAO;IAqCf,OAAgB,MAAM,4BA2BpB;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,sBAAsB,EAAE,iBAAiB,CAAC;KAC3C;CACF"}
|