@oicl/openbridge-webcomponents 2.0.0-next.55 → 2.0.0-next.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +395 -123
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +326 -2
  4. package/dist/automation/automation-tank/automation-tank.d.ts +11 -0
  5. package/dist/automation/automation-tank/automation-tank.d.ts.map +1 -1
  6. package/dist/automation/automation-tank/automation-tank.js.map +1 -1
  7. package/dist/navigation-instruments/compass-sector/compass-sector.css.js +12 -0
  8. package/dist/navigation-instruments/compass-sector/compass-sector.css.js.map +1 -1
  9. package/dist/navigation-instruments/compass-sector/compass-sector.d.ts +23 -0
  10. package/dist/navigation-instruments/compass-sector/compass-sector.d.ts.map +1 -1
  11. package/dist/navigation-instruments/compass-sector/compass-sector.js +47 -0
  12. package/dist/navigation-instruments/compass-sector/compass-sector.js.map +1 -1
  13. package/dist/navigation-instruments/pitch/pitch.d.ts +37 -0
  14. package/dist/navigation-instruments/pitch/pitch.d.ts.map +1 -1
  15. package/dist/navigation-instruments/pitch/pitch.js +130 -62
  16. package/dist/navigation-instruments/pitch/pitch.js.map +1 -1
  17. package/dist/navigation-instruments/pitch-roll/pitch-roll.d.ts +7 -0
  18. package/dist/navigation-instruments/pitch-roll/pitch-roll.d.ts.map +1 -1
  19. package/dist/navigation-instruments/pitch-roll/pitch-roll.js +58 -2
  20. package/dist/navigation-instruments/pitch-roll/pitch-roll.js.map +1 -1
  21. package/dist/navigation-instruments/roll/roll.d.ts +37 -0
  22. package/dist/navigation-instruments/roll/roll.d.ts.map +1 -1
  23. package/dist/navigation-instruments/roll/roll.js +119 -63
  24. package/dist/navigation-instruments/roll/roll.js.map +1 -1
  25. package/dist/navigation-instruments/rot-sector/rot-sector.d.ts +15 -0
  26. package/dist/navigation-instruments/rot-sector/rot-sector.d.ts.map +1 -1
  27. package/dist/navigation-instruments/rot-sector/rot-sector.js +53 -1
  28. package/dist/navigation-instruments/rot-sector/rot-sector.js.map +1 -1
  29. package/package.json +1 -1
@@ -206553,6 +206553,18 @@ const componentStyle$c = i$7`
206553
206553
  height: 100%;
206554
206554
  }
206555
206555
 
206556
+ .container > .readout {
206557
+ left: 50%;
206558
+ width: auto;
206559
+ height: auto;
206560
+ transform: translate(-50%, -50%);
206561
+ }
206562
+
206563
+ obc-readout::part(value-wrapper),
206564
+ obc-readout::part(meta-wrapper) {
206565
+ justify-self: center;
206566
+ }
206567
+
206556
206568
  :host {
206557
206569
  display: block;
206558
206570
  width: 100%;
@@ -206650,6 +206662,7 @@ let ObcCompassSector = class extends i$4 {
206650
206662
  ];
206651
206663
  this.tickmarksInside = false;
206652
206664
  this.zoomToFitArc = false;
206665
+ this.hasReadout = false;
206653
206666
  this._headingSp = new SetpointBundle({
206654
206667
  angularWraparound: true,
206655
206668
  onAnimationEnd: () => this.requestUpdate()
@@ -206837,6 +206850,32 @@ let ObcCompassSector = class extends i$4 {
206837
206850
  const selected = Array.isArray(this.priorityElements) ? this.priorityElements : [];
206838
206851
  return selected.includes(element) ? this.priority : Priority.regular;
206839
206852
  }
206853
+ /**
206854
+ * Vertical placement of the readout as a percentage of the host height.
206855
+ *
206856
+ * With `zoomToFitArc` the arc is reframed by `computeZoomToFitArcFrame`, whose
206857
+ * `radiusOffset`/`viewBox` depend on the arc's *absolute* orientation (which
206858
+ * cardinal axes its bounding box crosses), not just its bend. The arc itself
206859
+ * is always rotated back to the top, so it stays put on screen — but a
206860
+ * frame-derived offset would swing wildly as `heading` rotates the bbox around
206861
+ * the circle. So in zoom we use a fixed offset, which keeps the readout steady
206862
+ * under the (stationary) arc regardless of heading.
206863
+ *
206864
+ * Without zoom the viewBox is the fixed, origin-symmetric 120° framing, so the
206865
+ * geometry is orientation-independent: place the readout halfway down the inner
206866
+ * radius from the watch center toward the arc's inner edge.
206867
+ */
206868
+ get _readoutTopPercent() {
206869
+ if (this.zoomToFitArc) {
206870
+ return 70;
206871
+ }
206872
+ const [, vy, , vh] = this._cachedViewBox.split(" ").map(Number);
206873
+ if (!vh || Number.isNaN(vy)) {
206874
+ return 50;
206875
+ }
206876
+ const anchorY = -INNER_RADIUS * 0.5;
206877
+ return Math.round((anchorY - vy) / vh * 1e3) / 10;
206878
+ }
206840
206879
  // ---------------------------------------------------------------------------
206841
206880
  // Render
206842
206881
  // ---------------------------------------------------------------------------
@@ -206918,6 +206957,22 @@ let ObcCompassSector = class extends i$4 {
206918
206957
  rOff
206919
206958
  )}
206920
206959
  </svg>
206960
+ ${this.hasReadout ? b`<div class="readout" style="top: ${this._readoutTopPercent}%">
206961
+ <obc-readout
206962
+ .variant=${ReadoutVariant.enhanced}
206963
+ .direction=${ReadoutDirection.vertical}
206964
+ .hasSetpoint=${false}
206965
+ .hasAdvice=${false}
206966
+ .value=${this.heading}
206967
+ .fractionDigits=${0}
206968
+ .valuePriority=${this.priorityFor(
206969
+ "hdg"
206970
+ /* hdg */
206971
+ )}
206972
+ label="HDG"
206973
+ unit="DEG"
206974
+ ></obc-readout>
206975
+ </div>` : A}
206921
206976
  </div>
206922
206977
  `;
206923
206978
  }
@@ -207001,6 +207056,9 @@ __decorateClass$D([
207001
207056
  __decorateClass$D([
207002
207057
  n$3({ type: Boolean })
207003
207058
  ], ObcCompassSector.prototype, "zoomToFitArc", 2);
207059
+ __decorateClass$D([
207060
+ n$3({ type: Boolean })
207061
+ ], ObcCompassSector.prototype, "hasReadout", 2);
207004
207062
  ObcCompassSector = __decorateClass$D([
207005
207063
  customElement("obc-compass-sector")
207006
207064
  ], ObcCompassSector);
@@ -216460,6 +216518,7 @@ let ObcPitchRoll = class extends i$4 {
216460
216518
  "roll"
216461
216519
  /* roll */
216462
216520
  ];
216521
+ this.hasReadout = false;
216463
216522
  this.zoomToFitArc = false;
216464
216523
  this.arcAngle = 30;
216465
216524
  }
@@ -216520,7 +216579,7 @@ let ObcPitchRoll = class extends i$4 {
216520
216579
  return b`
216521
216580
  <div class="container">
216522
216581
  <svg viewBox="${overlayViewBox}">
216523
- ${w`
216582
+ ${this.hasReadout ? A : w`
216524
216583
  <line
216525
216584
  x1="-150"
216526
216585
  y1="0"
@@ -216541,9 +216600,41 @@ let ObcPitchRoll = class extends i$4 {
216541
216600
  `}
216542
216601
  </svg>
216543
216602
  ${this.zoomToFitArc ? this.renderZoomedArcs(pitchReq, rollReq) : this.renderFullWatch(areas)}
216603
+ ${this.hasReadout ? b`<div class="readout">
216604
+ <div class="readout-group">
216605
+ ${this.renderReadout(
216606
+ this.pitch,
216607
+ "Pitch",
216608
+ "pitch"
216609
+ /* pitch */
216610
+ )}
216611
+ <div class="readout-divider"></div>
216612
+ ${this.renderReadout(
216613
+ this.roll,
216614
+ "Roll",
216615
+ "roll"
216616
+ /* roll */
216617
+ )}
216618
+ </div>
216619
+ </div>` : A}
216544
216620
  </div>
216545
216621
  `;
216546
216622
  }
216623
+ renderReadout(value, label, element) {
216624
+ return b`
216625
+ <obc-readout
216626
+ .variant=${ReadoutVariant.enhanced}
216627
+ .direction=${ReadoutDirection.vertical}
216628
+ .hasSetpoint=${false}
216629
+ .hasAdvice=${false}
216630
+ .value=${value}
216631
+ .fractionDigits=${0}
216632
+ .valuePriority=${this.priorityFor(element)}
216633
+ label=${label}
216634
+ unit="DEG"
216635
+ ></obc-readout>
216636
+ `;
216637
+ }
216547
216638
  /**
216548
216639
  * Zoomed-arc layer: four CSS-rotated `<obc-watch>` instances, each
216549
216640
  * containing a single arc rendered at the watch's natural top
@@ -216873,7 +216964,7 @@ let ObcPitchRoll = class extends i$4 {
216873
216964
  strokeColor: "var(--border-silhouette-color)"
216874
216965
  }
216875
216966
  ]}
216876
- .vessels=${[
216967
+ .vessels=${this.hasReadout ? [] : [
216877
216968
  {
216878
216969
  size: VesselImageSize.large,
216879
216970
  vesselImage: this.vesselImageSide,
@@ -216986,6 +217077,25 @@ ObcPitchRoll.styles = i$7`
216986
217077
  width: 100%;
216987
217078
  height: 100%;
216988
217079
  }
217080
+
217081
+ .readout {
217082
+ display: flex;
217083
+ align-items: center;
217084
+ justify-content: center;
217085
+ }
217086
+
217087
+ .readout-group {
217088
+ display: flex;
217089
+ flex-direction: column;
217090
+ align-items: center;
217091
+ width: fit-content;
217092
+ }
217093
+
217094
+ .readout-divider {
217095
+ align-self: stretch;
217096
+ height: 1px;
217097
+ background: var(--border-divider-color);
217098
+ }
216989
217099
  `;
216990
217100
  __decorateClass$k([
216991
217101
  n$3({ type: Number })
@@ -217032,6 +217142,9 @@ __decorateClass$k([
217032
217142
  __decorateClass$k([
217033
217143
  n$3({ type: Array, attribute: false })
217034
217144
  ], ObcPitchRoll.prototype, "priorityElements", 2);
217145
+ __decorateClass$k([
217146
+ n$3({ type: Boolean })
217147
+ ], ObcPitchRoll.prototype, "hasReadout", 2);
217035
217148
  __decorateClass$k([
217036
217149
  n$3({ type: Boolean })
217037
217150
  ], ObcPitchRoll.prototype, "zoomToFitArc", 2);
@@ -217069,8 +217182,17 @@ let ObcPitch = class extends i$4 {
217069
217182
  this.maxPitchAdvice = void 0;
217070
217183
  this.triggerPitchAdvice = false;
217071
217184
  this.zoomToFitArc = false;
217185
+ this.hasReadout = false;
217186
+ this.type = "single-scale";
217187
+ this.priority = Priority.regular;
217072
217188
  this.arcAngle = 45;
217073
217189
  }
217190
+ get scaleFillColor() {
217191
+ return this.priority === Priority.enhanced ? "var(--instrument-enhanced-tertiary-color)" : "var(--instrument-regular-tertiary-color)";
217192
+ }
217193
+ get indicatorColor() {
217194
+ return this.priority === Priority.enhanced ? "var(--instrument-enhanced-secondary-color)" : "var(--instrument-regular-secondary-color)";
217195
+ }
217074
217196
  render() {
217075
217197
  const arcAngle = normalizeArcAngle(this.arcAngle, 45);
217076
217198
  const x2 = watchRadius$1 * Math.cos(arcAngle * Math.PI / 180);
@@ -217108,96 +217230,128 @@ let ObcPitch = class extends i$4 {
217108
217230
  return b`
217109
217231
  <div class="container">
217110
217232
  <svg viewBox="${centreViewBox}">
217111
- ${w`
217112
- <line
217113
- x1="-${watchRadius$1}"
217114
- y1="0"
217115
- x2="${watchRadius$1}"
217116
- y2="0"
217117
- stroke="var(--instrument-frame-tertiary-color)"
217118
- />
217119
- <line
217120
- x1="0"
217121
- y1="0"
217122
- x2="${watchRadius$1 - 10}"
217123
- y2="0"
217124
- stroke="var(--instrument-enhanced-secondary-color)"
217125
- transform="${needleTransform}"
217126
- />
217127
- <g
217128
- style="transform: rotate(${this.pitch}deg) scale(${vesselScale}) translate(-80px, -80px);"
217129
- >
217130
- ${vesselImages[this.vesselImageSide]}
217131
- </g>
217132
- ${this.zoomToFitArc ? A : w`
217133
- <path
217134
- d="M ${x2} ${y3} A ${watchRadius$1} ${watchRadius$1} 0 1 1 ${x2} ${-y3}"
217135
- fill="none"
217136
- stroke="var(--instrument-frame-tertiary-color)"
217137
- />
217138
- `}
217139
- `}
217233
+ ${this.hasReadout ? A : w`
217234
+ <line
217235
+ x1="-${watchRadius$1}"
217236
+ y1="0"
217237
+ x2="${watchRadius$1}"
217238
+ y2="0"
217239
+ stroke="var(--instrument-frame-tertiary-color)"
217240
+ />
217241
+ <line
217242
+ x1="0"
217243
+ y1="0"
217244
+ x2="${watchRadius$1 - 10}"
217245
+ y2="0"
217246
+ stroke="${this.indicatorColor}"
217247
+ transform="${needleTransform}"
217248
+ />
217249
+ <g
217250
+ style="transform: rotate(${this.pitch}deg) scale(${vesselScale}) translate(-80px, -80px);"
217251
+ >
217252
+ ${this.zoomToFitArc ? vesselImages[this.vesselImageSide] : A}
217253
+ </g>
217254
+ `}
217255
+ ${this.zoomToFitArc ? A : this.type === "dual-scale" ? w`
217256
+ <path
217257
+ d="M ${x2} ${-y3} A ${watchRadius$1} ${watchRadius$1} 0 0 0 ${-x2} ${-y3}"
217258
+ fill="none"
217259
+ stroke="var(--instrument-frame-tertiary-color)"
217260
+ />
217261
+ <path
217262
+ d="M ${x2} ${y3} A ${watchRadius$1} ${watchRadius$1} 0 0 1 ${-x2} ${y3}"
217263
+ fill="none"
217264
+ stroke="var(--instrument-frame-tertiary-color)"
217265
+ />
217266
+ ` : w`
217267
+ <path
217268
+ d="M ${x2} ${y3} A ${watchRadius$1} ${watchRadius$1} 0 1 1 ${x2} ${-y3}"
217269
+ fill="none"
217270
+ stroke="var(--instrument-frame-tertiary-color)"
217271
+ />
217272
+ `}
217140
217273
  </svg>
217141
- <obc-watch
217142
- .watchCircleType=${WatchCircleType.double}
217143
- .zoomToFitArc=${this.zoomToFitArc}
217144
- .arcFrame=${this._arcFrame}
217145
- .areas=${areas}
217146
- .barAreas=${[
217274
+ ${this.renderScale(areas, false)}
217275
+ ${this.type === "dual-scale" ? this.renderScale(areas, true) : A}
217276
+ ${this.hasReadout ? b`<div class="readout">
217277
+ <obc-readout
217278
+ .variant=${ReadoutVariant.enhanced}
217279
+ .direction=${ReadoutDirection.vertical}
217280
+ .hasSetpoint=${false}
217281
+ .hasAdvice=${false}
217282
+ .value=${this.pitch}
217283
+ .fractionDigits=${0}
217284
+ .valuePriority=${this.priority}
217285
+ label="Pitch"
217286
+ unit="DEG"
217287
+ ></obc-readout>
217288
+ </div>` : A}
217289
+ </div>
217290
+ `;
217291
+ }
217292
+ // `opposite` rotates a second watch 180° onto the opposite (left) arc for
217293
+ // dual-scale — a rotation (opposite end of the indicator), not a mirror. A
217294
+ // separate watch keeps the zoomed `arcFrame` correct.
217295
+ renderScale(areas, opposite) {
217296
+ return b`
217297
+ <obc-watch
217298
+ class=${opposite ? "scale-opposite" : A}
217299
+ .priority=${this.priority}
217300
+ .watchCircleType=${WatchCircleType.double}
217301
+ .zoomToFitArc=${this.zoomToFitArc}
217302
+ .arcFrame=${this._arcFrame}
217303
+ tickmarksInside
217304
+ .areas=${areas}
217305
+ .barAreas=${[
217147
217306
  {
217148
217307
  startAngle: 90 + this.minAvgPitch,
217149
217308
  endAngle: 90 + this.maxAvgPitch,
217150
- fillColor: "var(--instrument-enhanced-tertiary-color)"
217309
+ fillColor: this.scaleFillColor
217151
217310
  }
217152
217311
  ]}
217153
- .needles=${[
217312
+ .needles=${[
217154
217313
  {
217155
217314
  angle: 90 + this.pitch,
217156
- fillColor: "var(--instrument-enhanced-secondary-color)",
217315
+ fillColor: this.indicatorColor,
217157
217316
  strokeColor: "var(--border-silhouette-color)"
217158
217317
  }
217159
217318
  ]}
217160
- .vessels=${this.zoomToFitArc ? [] : [
217319
+ .vessels=${opposite || this.zoomToFitArc || this.hasReadout ? [] : [
217161
217320
  {
217162
217321
  size: VesselImageSize.large,
217163
217322
  vesselImage: this.vesselImageSide,
217164
217323
  transform: `rotate(${this.pitch}deg)`
217165
217324
  }
217166
217325
  ]}
217167
- .tickmarks=${[
217168
- {
217169
- angle: 90,
217170
- type: TickmarkType$1.main
217171
- }
217172
- ]}
217173
- .advices=${this.advices}
217174
- ></obc-watch>
217175
- </div>
217326
+ .tickmarks=${[{ angle: 90, type: TickmarkType$1.main }]}
217327
+ .advices=${this.advices}
217328
+ ></obc-watch>
217176
217329
  `;
217177
217330
  }
217178
217331
  get advices() {
217179
- const advices = [];
217180
- if (this.maxPitchAdvice !== void 0) {
217181
- const arcAngle = normalizeArcAngle(this.arcAngle, 45);
217182
- const outer = Math.min(arcAngle, 30);
217183
- const inner = Math.min(this.maxPitchAdvice, outer);
217184
- const state = this.triggerPitchAdvice ? AdviceState.triggered : AdviceState.regular;
217185
- advices.push({
217332
+ if (this.maxPitchAdvice === void 0) {
217333
+ return [];
217334
+ }
217335
+ const arcAngle = normalizeArcAngle(this.arcAngle, 45);
217336
+ const outer = Math.min(arcAngle, 30);
217337
+ const inner = Math.min(this.maxPitchAdvice, outer);
217338
+ const state = this.triggerPitchAdvice ? AdviceState.triggered : AdviceState.regular;
217339
+ return [
217340
+ {
217186
217341
  minAngle: 90 - outer,
217187
217342
  maxAngle: 90 - inner,
217188
217343
  type: AdviceType.caution,
217189
217344
  state,
217190
217345
  hideMinTickmark: true
217191
- });
217192
- advices.push({
217346
+ },
217347
+ {
217193
217348
  minAngle: 90 + inner,
217194
217349
  maxAngle: 90 + outer,
217195
217350
  type: AdviceType.caution,
217196
217351
  state,
217197
217352
  hideMaxTickmark: true
217198
- });
217199
- }
217200
- return advices;
217353
+ }
217354
+ ];
217201
217355
  }
217202
217356
  };
217203
217357
  ObcPitch.styles = i$7`
@@ -217218,6 +217372,16 @@ ObcPitch.styles = i$7`
217218
217372
  width: 100%;
217219
217373
  height: 100%;
217220
217374
  }
217375
+
217376
+ .readout {
217377
+ display: flex;
217378
+ align-items: center;
217379
+ justify-content: center;
217380
+ }
217381
+
217382
+ .scale-opposite {
217383
+ transform: rotate(180deg);
217384
+ }
217221
217385
  `;
217222
217386
  __decorateClass$j([
217223
217387
  n$3({ type: Number })
@@ -217240,6 +217404,15 @@ __decorateClass$j([
217240
217404
  __decorateClass$j([
217241
217405
  n$3({ type: Boolean })
217242
217406
  ], ObcPitch.prototype, "zoomToFitArc", 2);
217407
+ __decorateClass$j([
217408
+ n$3({ type: Boolean })
217409
+ ], ObcPitch.prototype, "hasReadout", 2);
217410
+ __decorateClass$j([
217411
+ n$3({ type: String })
217412
+ ], ObcPitch.prototype, "type", 2);
217413
+ __decorateClass$j([
217414
+ n$3({ type: String })
217415
+ ], ObcPitch.prototype, "priority", 2);
217243
217416
  __decorateClass$j([
217244
217417
  n$3({ type: Number })
217245
217418
  ], ObcPitch.prototype, "arcAngle", 2);
@@ -218783,6 +218956,9 @@ let ObcRoll = class extends i$4 {
218783
218956
  this.maxRollAdvice = void 0;
218784
218957
  this.triggerRollAdvice = false;
218785
218958
  this.zoomToFitArc = false;
218959
+ this.hasReadout = false;
218960
+ this.type = "single-scale";
218961
+ this.priority = Priority.regular;
218786
218962
  this.arcAngle = 45;
218787
218963
  }
218788
218964
  get normalizedScaleForeImage() {
@@ -218791,6 +218967,12 @@ let ObcRoll = class extends i$4 {
218791
218967
  }
218792
218968
  return Math.max(0, Math.min(2, this.scaleForeImage));
218793
218969
  }
218970
+ get scaleFillColor() {
218971
+ return this.priority === Priority.enhanced ? "var(--instrument-enhanced-tertiary-color)" : "var(--instrument-regular-tertiary-color)";
218972
+ }
218973
+ get indicatorColor() {
218974
+ return this.priority === Priority.enhanced ? "var(--instrument-enhanced-secondary-color)" : "var(--instrument-regular-secondary-color)";
218975
+ }
218794
218976
  render() {
218795
218977
  const arcAngle = normalizeArcAngle(this.arcAngle, 45);
218796
218978
  const x2 = watchRadius * Math.sin(arcAngle * Math.PI / 180);
@@ -218828,97 +219010,117 @@ let ObcRoll = class extends i$4 {
218828
219010
  return b`
218829
219011
  <div class="container">
218830
219012
  <svg viewBox="${centreViewBox}">
218831
- ${w`
218832
- <line
218833
- x1="-${watchRadius}"
218834
- y1="0"
218835
- x2="${watchRadius}"
218836
- y2="0"
218837
- stroke="var(--instrument-frame-tertiary-color)"
218838
- />
218839
- <line
218840
- x1="0"
218841
- y1="0"
218842
- y2="${watchRadius - 10}"
218843
- x2="0"
218844
- stroke="var(--instrument-enhanced-secondary-color)"
218845
- transform="${needleTransform}"
218846
- />
218847
- <g
218848
- style="transform: rotate(${this.roll}deg) scale(${vesselScale * this.normalizedScaleForeImage}) translate(-80px, -80px);"
218849
- >
218850
- ${this.zoomToFitArc ? vesselImages[this.vesselImageFore] : A}
218851
- </g>
218852
- ${this.zoomToFitArc ? A : w`
218853
- <path
218854
- d="M ${-x2} ${y3} A ${watchRadius} ${watchRadius} 0 1 1 ${x2} ${y3}"
218855
- fill="none"
218856
- stroke="var(--instrument-frame-tertiary-color)"
218857
- />
218858
- `}
218859
- `}
219013
+ ${this.hasReadout ? A : w`
219014
+ <line
219015
+ x1="-${watchRadius}"
219016
+ y1="0"
219017
+ x2="${watchRadius}"
219018
+ y2="0"
219019
+ stroke="var(--instrument-frame-tertiary-color)"
219020
+ />
219021
+ <line
219022
+ x1="0"
219023
+ y1="0"
219024
+ y2="${watchRadius - 10}"
219025
+ x2="0"
219026
+ stroke="${this.indicatorColor}"
219027
+ transform="${needleTransform}"
219028
+ />
219029
+ <g
219030
+ style="transform: rotate(${this.roll}deg) scale(${vesselScale * this.normalizedScaleForeImage}) translate(-80px, -80px);"
219031
+ >
219032
+ ${this.zoomToFitArc ? vesselImages[this.vesselImageFore] : A}
219033
+ </g>
219034
+ `}
219035
+ ${this.zoomToFitArc ? A : w`
219036
+ <path
219037
+ d="M ${-x2} ${y3} A ${watchRadius} ${watchRadius} 0 1 1 ${x2} ${y3}"
219038
+ fill="none"
219039
+ stroke="var(--instrument-frame-tertiary-color)"
219040
+ />
219041
+ `}
218860
219042
  </svg>
218861
- <obc-watch
218862
- .watchCircleType=${WatchCircleType.double}
218863
- .zoomToFitArc=${this.zoomToFitArc}
218864
- .arcFrame=${this._arcFrame}
218865
- tickmarksInside
218866
- .areas=${areas}
218867
- .barAreas=${[
219043
+ ${this.renderScale(areas, false)}
219044
+ ${this.type === "dual-scale" ? this.renderScale(areas, true) : A}
219045
+ ${this.hasReadout ? b`<div class="readout">
219046
+ <obc-readout
219047
+ .variant=${ReadoutVariant.enhanced}
219048
+ .direction=${ReadoutDirection.vertical}
219049
+ .hasSetpoint=${false}
219050
+ .hasAdvice=${false}
219051
+ .value=${this.roll}
219052
+ .fractionDigits=${0}
219053
+ .valuePriority=${this.priority}
219054
+ label="Roll"
219055
+ unit="DEG"
219056
+ ></obc-readout>
219057
+ </div>` : A}
219058
+ </div>
219059
+ `;
219060
+ }
219061
+ // `top` rotates a second watch 180° onto the top arc for dual-scale — a
219062
+ // rotation (opposite end of the indicator), not a mirror. A separate watch
219063
+ // keeps the zoomed `arcFrame` correct.
219064
+ renderScale(areas, top) {
219065
+ return b`
219066
+ <obc-watch
219067
+ class=${top ? "scale-top" : A}
219068
+ .priority=${this.priority}
219069
+ .watchCircleType=${WatchCircleType.double}
219070
+ .zoomToFitArc=${this.zoomToFitArc}
219071
+ .arcFrame=${this._arcFrame}
219072
+ tickmarksInside
219073
+ .areas=${areas}
219074
+ .barAreas=${[
218868
219075
  {
218869
219076
  startAngle: 180 + this.minAvgRoll,
218870
219077
  endAngle: 180 + this.maxAvgRoll,
218871
- fillColor: "var(--instrument-enhanced-tertiary-color)"
219078
+ fillColor: this.scaleFillColor
218872
219079
  }
218873
219080
  ]}
218874
- .needles=${[
219081
+ .needles=${[
218875
219082
  {
218876
219083
  angle: 180 + this.roll,
218877
- fillColor: "var(--instrument-enhanced-secondary-color)",
219084
+ fillColor: this.indicatorColor,
218878
219085
  strokeColor: "var(--border-silhouette-color)"
218879
219086
  }
218880
219087
  ]}
218881
- .vessels=${this.zoomToFitArc ? [] : [
219088
+ .vessels=${top || this.zoomToFitArc || this.hasReadout ? [] : [
218882
219089
  {
218883
219090
  size: VesselImageSize.large,
218884
219091
  vesselImage: this.vesselImageFore,
218885
219092
  transform: `rotate(${this.roll}deg) scale(${this.normalizedScaleForeImage})`
218886
219093
  }
218887
219094
  ]}
218888
- .tickmarks=${[
218889
- {
218890
- angle: 180,
218891
- type: TickmarkType$1.main
218892
- }
218893
- ]}
218894
- .advices=${this.advices}
218895
- ></obc-watch>
218896
- </div>
219095
+ .tickmarks=${[{ angle: 180, type: TickmarkType$1.main }]}
219096
+ .advices=${this.advices}
219097
+ ></obc-watch>
218897
219098
  `;
218898
219099
  }
218899
219100
  get advices() {
218900
- const advices = [];
218901
- if (this.maxRollAdvice !== void 0) {
218902
- const arcAngle = normalizeArcAngle(this.arcAngle, 45);
218903
- const outer = Math.min(arcAngle, 45);
218904
- const inner = Math.min(this.maxRollAdvice, outer);
218905
- const state = this.triggerRollAdvice ? AdviceState.triggered : AdviceState.regular;
218906
- advices.push({
219101
+ if (this.maxRollAdvice === void 0) {
219102
+ return [];
219103
+ }
219104
+ const arcAngle = normalizeArcAngle(this.arcAngle, 45);
219105
+ const outer = Math.min(arcAngle, 45);
219106
+ const inner = Math.min(this.maxRollAdvice, outer);
219107
+ const state = this.triggerRollAdvice ? AdviceState.triggered : AdviceState.regular;
219108
+ return [
219109
+ {
218907
219110
  minAngle: 180 - outer,
218908
219111
  maxAngle: 180 - inner,
218909
219112
  type: AdviceType.caution,
218910
219113
  state,
218911
219114
  hideMinTickmark: true
218912
- });
218913
- advices.push({
219115
+ },
219116
+ {
218914
219117
  minAngle: 180 + inner,
218915
219118
  maxAngle: 180 + outer,
218916
219119
  type: AdviceType.caution,
218917
219120
  state,
218918
219121
  hideMaxTickmark: true
218919
- });
218920
- }
218921
- return advices;
219122
+ }
219123
+ ];
218922
219124
  }
218923
219125
  };
218924
219126
  ObcRoll.styles = i$7`
@@ -218939,6 +219141,16 @@ ObcRoll.styles = i$7`
218939
219141
  width: 100%;
218940
219142
  height: 100%;
218941
219143
  }
219144
+
219145
+ .readout {
219146
+ display: flex;
219147
+ align-items: center;
219148
+ justify-content: center;
219149
+ }
219150
+
219151
+ .scale-top {
219152
+ transform: rotate(180deg);
219153
+ }
218942
219154
  `;
218943
219155
  __decorateClass$d([
218944
219156
  n$3({ type: Number })
@@ -218964,6 +219176,15 @@ __decorateClass$d([
218964
219176
  __decorateClass$d([
218965
219177
  n$3({ type: Boolean })
218966
219178
  ], ObcRoll.prototype, "zoomToFitArc", 2);
219179
+ __decorateClass$d([
219180
+ n$3({ type: Boolean })
219181
+ ], ObcRoll.prototype, "hasReadout", 2);
219182
+ __decorateClass$d([
219183
+ n$3({ type: String })
219184
+ ], ObcRoll.prototype, "type", 2);
219185
+ __decorateClass$d([
219186
+ n$3({ type: String })
219187
+ ], ObcRoll.prototype, "priority", 2);
218967
219188
  __decorateClass$d([
218968
219189
  n$3({ type: Number })
218969
219190
  ], ObcRoll.prototype, "arcAngle", 2);
@@ -219226,6 +219447,7 @@ let ObcRotSector = class extends SetpointMixin(i$4) {
219226
219447
  this.advices = [];
219227
219448
  this.zoomToFitArc = false;
219228
219449
  this.rotArcExtent = 60;
219450
+ this.hasReadout = false;
219229
219451
  this.getAngle = (v2) => {
219230
219452
  if (!this.maxValue) return 0;
219231
219453
  return v2 / this.maxValue * this.rotArcExtent;
@@ -219260,6 +219482,22 @@ let ObcRotSector = class extends SetpointMixin(i$4) {
219260
219482
  }
219261
219483
  return "var(--instrument-enhanced-tertiary-color)";
219262
219484
  }
219485
+ /**
219486
+ * Vertical position of the readout, in % of the host. In the zoomed view the
219487
+ * arc's lower edge shifts with `rotArcExtent`, so the position is interpolated
219488
+ * between the narrow- and wide-arc anchors to keep a roughly constant gap
219489
+ * between the arc and the readout. The static (unzoomed) arc uses a fixed
219490
+ * position.
219491
+ */
219492
+ get _readoutTopPercent() {
219493
+ if (!this.zoomToFitArc) {
219494
+ return 60;
219495
+ }
219496
+ const narrowTop = 70;
219497
+ const wideTop = 66;
219498
+ const extent = Math.min(60, Math.max(10, this.rotArcExtent));
219499
+ return narrowTop + (wideTop - narrowTop) * (extent - 10) / (60 - 10);
219500
+ }
219263
219501
  render() {
219264
219502
  const barColor = this._barColor;
219265
219503
  return b`
@@ -219290,6 +219528,19 @@ let ObcRotSector = class extends SetpointMixin(i$4) {
219290
219528
  .zoomToFitArc=${this.zoomToFitArc}
219291
219529
  >
219292
219530
  </obc-instrument-radial>
219531
+ ${this.hasReadout ? b`<div class="readout" style="top: ${this._readoutTopPercent}%">
219532
+ <obc-readout
219533
+ .variant=${ReadoutVariant.enhanced}
219534
+ .direction=${ReadoutDirection.vertical}
219535
+ .hasSetpoint=${false}
219536
+ .hasAdvice=${false}
219537
+ .value=${this.value}
219538
+ .fractionDigits=${0}
219539
+ .valuePriority=${this.priority}
219540
+ label="ROT"
219541
+ unit="DEG/min"
219542
+ ></obc-readout>
219543
+ </div>` : A}
219293
219544
  `;
219294
219545
  }
219295
219546
  get _needleColor() {
@@ -219308,6 +219559,24 @@ let ObcRotSector = class extends SetpointMixin(i$4) {
219308
219559
  return "var(--instrument-enhanced-secondary-color)";
219309
219560
  }
219310
219561
  };
219562
+ ObcRotSector.styles = i$7`
219563
+ :host {
219564
+ position: relative;
219565
+ display: block;
219566
+ height: 100%;
219567
+ }
219568
+
219569
+ .readout {
219570
+ position: absolute;
219571
+ left: 50%;
219572
+ transform: translate(-50%, -50%);
219573
+ }
219574
+
219575
+ /* Center the value over the label/unit row instead of right-aligning it. */
219576
+ obc-readout::part(value-wrapper) {
219577
+ justify-self: center;
219578
+ }
219579
+ `;
219311
219580
  __decorateClass$b([
219312
219581
  n$3({ type: Number })
219313
219582
  ], ObcRotSector.prototype, "value", 2);
@@ -219353,6 +219622,9 @@ __decorateClass$b([
219353
219622
  __decorateClass$b([
219354
219623
  n$3({ type: Number })
219355
219624
  ], ObcRotSector.prototype, "rotArcExtent", 2);
219625
+ __decorateClass$b([
219626
+ n$3({ type: Boolean })
219627
+ ], ObcRotSector.prototype, "hasReadout", 2);
219356
219628
  ObcRotSector = __decorateClass$b([
219357
219629
  customElement("obc-rot-sector")
219358
219630
  ], ObcRotSector);