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

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 (24) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +592 -239
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +292 -8
  4. package/dist/building-blocks/instrument-radial/instrument-radial.d.ts +10 -0
  5. package/dist/building-blocks/instrument-radial/instrument-radial.d.ts.map +1 -1
  6. package/dist/building-blocks/instrument-radial/instrument-radial.js +86 -21
  7. package/dist/building-blocks/instrument-radial/instrument-radial.js.map +1 -1
  8. package/dist/navigation-instruments/gauge-radial/gauge-radial.css.js +99 -0
  9. package/dist/navigation-instruments/gauge-radial/gauge-radial.css.js.map +1 -0
  10. package/dist/navigation-instruments/gauge-radial/gauge-radial.d.ts +42 -7
  11. package/dist/navigation-instruments/gauge-radial/gauge-radial.d.ts.map +1 -1
  12. package/dist/navigation-instruments/gauge-radial/gauge-radial.js +178 -31
  13. package/dist/navigation-instruments/gauge-radial/gauge-radial.js.map +1 -1
  14. package/dist/navigation-instruments/readout/readout.css.js +4 -0
  15. package/dist/navigation-instruments/readout/readout.css.js.map +1 -1
  16. package/dist/navigation-instruments/watch/tickmark.d.ts +2 -1
  17. package/dist/navigation-instruments/watch/tickmark.d.ts.map +1 -1
  18. package/dist/navigation-instruments/watch/tickmark.js +24 -4
  19. package/dist/navigation-instruments/watch/tickmark.js.map +1 -1
  20. package/dist/navigation-instruments/watch/watch.d.ts +23 -1
  21. package/dist/navigation-instruments/watch/watch.d.ts.map +1 -1
  22. package/dist/navigation-instruments/watch/watch.js +48 -20
  23. package/dist/navigation-instruments/watch/watch.js.map +1 -1
  24. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"readout.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"readout.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -19,7 +19,7 @@ export declare enum TickmarkStyle {
19
19
  enhanced = "enhanced"
20
20
  }
21
21
  export declare function tickmarkColor(style: TickmarkStyle, tickmarkType?: TickmarkType): string;
22
- export declare function tickmark(angle: number, { size, style, scale, text, inside, textRadius, rotation, maxDigits, color, radiusOffset, }: {
22
+ export declare function tickmark(angle: number, { size, style, scale, text, inside, textRadius, rotation, maxDigits, color, radiusOffset, endLabelsMaxMin, }: {
23
23
  size: TickmarkType;
24
24
  style: TickmarkStyle;
25
25
  scale: number;
@@ -30,5 +30,6 @@ export declare function tickmark(angle: number, { size, style, scale, text, insi
30
30
  maxDigits: number;
31
31
  color?: string;
32
32
  radiusOffset?: number;
33
+ endLabelsMaxMin?: boolean;
33
34
  }): SVGTemplateResult | SVGTemplateResult[];
34
35
  //# sourceMappingURL=tickmark.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tickmark.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/watch/tickmark.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAM,MAAM,KAAK,CAAC;AAE3C,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,oBAAY,YAAY;IACtB,aAAa,kBAAkB;IAC/B,QAAQ,aAAa;IACrB,IAAI,SAAS;IACb,OAAO,YAAY;IACnB,SAAS,cAAc;IACvB,QAAQ,aAAa;IACrB,QAAQ,aAAa;CACtB;AAED,oBAAY,aAAa;IACvB,OAAO,YAAY;IACnB,QAAQ,aAAa;CACtB;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,aAAa,EACpB,YAAY,CAAC,EAAE,YAAY,GAC1B,MAAM,CASR;AAED,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,EACb,EACE,IAAI,EACJ,KAAK,EACL,KAAK,EACL,IAAI,EACJ,MAAM,EACN,UAAU,EACV,QAAQ,EACR,SAAS,EACT,KAAK,EACL,YAAgB,GACjB,EAAE;IACD,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GACA,iBAAiB,GAAG,iBAAiB,EAAE,CAmEzC"}
1
+ {"version":3,"file":"tickmark.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/watch/tickmark.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAM,MAAM,KAAK,CAAC;AAE3C,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,oBAAY,YAAY;IACtB,aAAa,kBAAkB;IAC/B,QAAQ,aAAa;IACrB,IAAI,SAAS;IACb,OAAO,YAAY;IACnB,SAAS,cAAc;IACvB,QAAQ,aAAa;IACrB,QAAQ,aAAa;CACtB;AAED,oBAAY,aAAa;IACvB,OAAO,YAAY;IACnB,QAAQ,aAAa;CACtB;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,aAAa,EACpB,YAAY,CAAC,EAAE,YAAY,GAC1B,MAAM,CASR;AAED,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,EACb,EACE,IAAI,EACJ,KAAK,EACL,KAAK,EACL,IAAI,EACJ,MAAM,EACN,UAAU,EACV,QAAQ,EACR,SAAS,EACT,KAAK,EACL,YAAgB,EAChB,eAAuB,GACxB,EAAE;IACD,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,GACA,iBAAiB,GAAG,iBAAiB,EAAE,CAwEzC"}
@@ -34,7 +34,8 @@ function tickmark(angle, {
34
34
  rotation,
35
35
  maxDigits,
36
36
  color,
37
- radiusOffset = 0
37
+ radiusOffset = 0,
38
+ endLabelsMaxMin = false
38
39
  }) {
39
40
  if (scale === Infinity || scale < 0) {
40
41
  throw new Error("Tick scale is not valid");
@@ -60,7 +61,9 @@ function tickmark(angle, {
60
61
  innerRadius = 328 / 2 + rOff;
61
62
  outerRadius = 336 / 2 + rOff;
62
63
  } else {
63
- return [textSvg(text ?? "", angle, inside, scale, textRadius)];
64
+ return [
65
+ textSvg(text ?? "", { angle, inside, scale, textRadius, endLabelsMaxMin })
66
+ ];
64
67
  }
65
68
  if (inside) {
66
69
  const outerRingRadius = 368 / 2 + rOff;
@@ -79,7 +82,10 @@ function tickmark(angle, {
79
82
  const tick = svg`<line x1=${x1} y1=${y1} x2=${x2} y2=${y2} stroke=${colorName} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>`;
80
83
  if (text) {
81
84
  if (rotation === void 0) {
82
- return [tick, textSvg(text, angle, inside, scale, textRadius)];
85
+ return [
86
+ tick,
87
+ textSvg(text, { angle, inside, scale, textRadius, endLabelsMaxMin })
88
+ ];
83
89
  } else {
84
90
  const newRadius = textRadius + (4 / scale + 5) * (inside ? -1 : 1) * maxDigits / 2;
85
91
  const textX = Math.sin(rad) * newRadius;
@@ -92,7 +98,21 @@ function tickmark(angle, {
92
98
  }
93
99
  return tick;
94
100
  }
95
- function textSvg(text, angle, inside, scale, textRadius) {
101
+ function textSvg(text, {
102
+ angle,
103
+ inside,
104
+ scale,
105
+ textRadius,
106
+ endLabelsMaxMin = false
107
+ }) {
108
+ const radHoriz = angle * Math.PI / 180;
109
+ if (endLabelsMaxMin && Math.abs(Math.cos(radHoriz)) < 1e-6) {
110
+ const sin = Math.sin(radHoriz);
111
+ const inward = inside ? (6 + (text.length - 1) * 2.5) / scale : 14 / scale;
112
+ const x = sin * (textRadius - inward);
113
+ const y = inside ? -(6 / scale) : 12 / scale;
114
+ return svg`<text x=${x} y=${y} class="label bottom ${inside ? "inside" : ""}">${text}</text>`;
115
+ }
96
116
  let positionClass;
97
117
  if (angle === 0) {
98
118
  positionClass = "top";
@@ -1 +1 @@
1
- {"version":3,"file":"tickmark.js","sources":["../../../src/navigation-instruments/watch/tickmark.ts"],"sourcesContent":["import {SVGTemplateResult, svg} from 'lit';\n\nexport interface Tickmark {\n angle: number;\n type: TickmarkType;\n text?: string;\n color?: string;\n}\n\nexport enum TickmarkType {\n zeroLineThick = 'zeroLineThick',\n zeroLine = 'zeroLine',\n main = 'main',\n primary = 'primary',\n secondary = 'secondary',\n tertiary = 'tertiary',\n textOnly = 'textOnly',\n}\n\nexport enum TickmarkStyle {\n regular = 'regular',\n enhanced = 'enhanced',\n}\n\nexport function tickmarkColor(\n style: TickmarkStyle,\n tickmarkType?: TickmarkType\n): string {\n if (style === TickmarkStyle.regular) {\n return 'var(--instrument-tick-mark-tertiary-color)';\n } else {\n if (tickmarkType === TickmarkType.tertiary) {\n return 'var(--instrument-tick-mark-secondary-color)';\n }\n return 'var(--instrument-tick-mark-primary-color)';\n }\n}\n\nexport function tickmark(\n angle: number,\n {\n size,\n style,\n scale,\n text,\n inside,\n textRadius,\n rotation,\n maxDigits,\n color,\n radiusOffset = 0,\n }: {\n size: TickmarkType;\n style: TickmarkStyle;\n scale: number;\n text?: string;\n inside: boolean;\n textRadius: number;\n rotation?: number;\n maxDigits: number;\n color?: string;\n radiusOffset?: number;\n }\n): SVGTemplateResult | SVGTemplateResult[] {\n // check if scale is not infinite\n if (scale === Infinity || scale < 0) {\n throw new Error('Tick scale is not valid');\n }\n const rOff = radiusOffset;\n let innerRadius: number;\n let outerRadius: number;\n textRadius = textRadius + (3 / scale + 3) * (inside ? -1 : 1);\n const rad = (angle * Math.PI) / 180;\n if (size === TickmarkType.primary) {\n innerRadius = 328 / 2 + rOff;\n outerRadius = 368 / 2 + rOff;\n } else if (size === TickmarkType.secondary) {\n innerRadius = 328 / 2 + rOff;\n outerRadius = 344 / 2 + rOff;\n } else if (size === TickmarkType.main || size === TickmarkType.zeroLine) {\n innerRadius = 320 / 2 + rOff;\n outerRadius = 368 / 2 + rOff;\n } else if (size === TickmarkType.zeroLineThick) {\n innerRadius = 224 / 2 + rOff;\n outerRadius = 368 / 2 + rOff;\n } else if (size === TickmarkType.tertiary) {\n innerRadius = 328 / 2 + rOff;\n outerRadius = 336 / 2 + rOff;\n } else {\n return [textSvg(text ?? '', angle, inside, scale, textRadius)];\n }\n\n // When inside, anchor ticks at the outer ring edge and grow inward,\n // preserving the same gap from the ring edge as the outside case.\n // Outside: gap = innerRadius - RING2 (320/2). E.g. secondary: 164 - 160 = 4px gap.\n // Inside: mirror that gap from the outer ring (368/2).\n if (inside) {\n const outerRingRadius = 368 / 2 + rOff;\n const ring2Radius = 320 / 2 + rOff;\n const tickLength = outerRadius - innerRadius;\n const gapFromRingEdge = Math.max(0, innerRadius - ring2Radius);\n outerRadius = outerRingRadius - gapFromRingEdge;\n innerRadius = outerRadius - tickLength;\n }\n const colorName = color ?? tickmarkColor(style, size);\n\n const x1 = Math.sin(rad) * innerRadius;\n const y1 = -Math.cos(rad) * innerRadius;\n const x2 = Math.sin(rad) * outerRadius;\n const y2 = -Math.cos(rad) * outerRadius;\n const strokeWidth =\n size === TickmarkType.zeroLine || size === TickmarkType.zeroLineThick\n ? 4\n : 1;\n const tick = svg`<line x1=${x1} y1=${y1} x2=${x2} y2=${y2} stroke=${colorName} stroke-width=${strokeWidth} vector-effect=\"non-scaling-stroke\"/>`;\n if (text) {\n if (rotation === undefined) {\n return [tick, textSvg(text, angle, inside, scale, textRadius)];\n } else {\n const newRadius =\n textRadius + ((4 / scale + 5) * (inside ? -1 : 1) * maxDigits) / 2;\n const textX = Math.sin(rad) * newRadius;\n const textY = -Math.cos(rad) * newRadius;\n return [\n tick,\n svg`<text x=${textX} y=${textY} class=\"label rotate ${inside ? 'inside' : ''}\" transform=\"rotate(${-rotation})\" transform-origin=\"${textX} ${textY}\">${text}</text>`,\n ];\n }\n }\n return tick;\n}\n\nfunction textSvg(\n text: string,\n angle: number,\n inside: boolean,\n scale: number,\n textRadius: number\n) {\n let positionClass;\n if (angle === 0) {\n positionClass = 'top';\n } else if (angle < 180 && angle > 0) {\n positionClass = 'right';\n } else if (angle === 180) {\n positionClass = 'bottom';\n } else {\n positionClass = 'left';\n }\n const rad = (angle * Math.PI) / 180;\n const insideGain = inside ? -1 : 1;\n const yOffset = (7 / scale) * insideGain;\n const xOffset = (6 / scale) * insideGain;\n\n let textX = Math.sin(rad) * (textRadius + xOffset);\n if (angle > 180) {\n textX += (4 / scale) * insideGain;\n } else if (angle < 180 && angle > 0) {\n textX -= (4 / scale) * insideGain;\n }\n const textY = -Math.cos(rad) * (textRadius + yOffset);\n return svg`<text x=${textX} y=${textY} class=\"label ${positionClass} ${inside ? 'inside' : ''}\">${text}</text>`;\n}\n"],"names":["TickmarkType","TickmarkStyle"],"mappings":"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"}
1
+ {"version":3,"file":"tickmark.js","sources":["../../../src/navigation-instruments/watch/tickmark.ts"],"sourcesContent":["import {SVGTemplateResult, svg} from 'lit';\n\nexport interface Tickmark {\n angle: number;\n type: TickmarkType;\n text?: string;\n color?: string;\n}\n\nexport enum TickmarkType {\n zeroLineThick = 'zeroLineThick',\n zeroLine = 'zeroLine',\n main = 'main',\n primary = 'primary',\n secondary = 'secondary',\n tertiary = 'tertiary',\n textOnly = 'textOnly',\n}\n\nexport enum TickmarkStyle {\n regular = 'regular',\n enhanced = 'enhanced',\n}\n\nexport function tickmarkColor(\n style: TickmarkStyle,\n tickmarkType?: TickmarkType\n): string {\n if (style === TickmarkStyle.regular) {\n return 'var(--instrument-tick-mark-tertiary-color)';\n } else {\n if (tickmarkType === TickmarkType.tertiary) {\n return 'var(--instrument-tick-mark-secondary-color)';\n }\n return 'var(--instrument-tick-mark-primary-color)';\n }\n}\n\nexport function tickmark(\n angle: number,\n {\n size,\n style,\n scale,\n text,\n inside,\n textRadius,\n rotation,\n maxDigits,\n color,\n radiusOffset = 0,\n endLabelsMaxMin = false,\n }: {\n size: TickmarkType;\n style: TickmarkStyle;\n scale: number;\n text?: string;\n inside: boolean;\n textRadius: number;\n rotation?: number;\n maxDigits: number;\n color?: string;\n radiusOffset?: number;\n endLabelsMaxMin?: boolean;\n }\n): SVGTemplateResult | SVGTemplateResult[] {\n // check if scale is not infinite\n if (scale === Infinity || scale < 0) {\n throw new Error('Tick scale is not valid');\n }\n const rOff = radiusOffset;\n let innerRadius: number;\n let outerRadius: number;\n textRadius = textRadius + (3 / scale + 3) * (inside ? -1 : 1);\n const rad = (angle * Math.PI) / 180;\n if (size === TickmarkType.primary) {\n innerRadius = 328 / 2 + rOff;\n outerRadius = 368 / 2 + rOff;\n } else if (size === TickmarkType.secondary) {\n innerRadius = 328 / 2 + rOff;\n outerRadius = 344 / 2 + rOff;\n } else if (size === TickmarkType.main || size === TickmarkType.zeroLine) {\n innerRadius = 320 / 2 + rOff;\n outerRadius = 368 / 2 + rOff;\n } else if (size === TickmarkType.zeroLineThick) {\n innerRadius = 224 / 2 + rOff;\n outerRadius = 368 / 2 + rOff;\n } else if (size === TickmarkType.tertiary) {\n innerRadius = 328 / 2 + rOff;\n outerRadius = 336 / 2 + rOff;\n } else {\n return [\n textSvg(text ?? '', {angle, inside, scale, textRadius, endLabelsMaxMin}),\n ];\n }\n\n // When inside, anchor ticks at the outer ring edge and grow inward,\n // preserving the same gap from the ring edge as the outside case.\n // Outside: gap = innerRadius - RING2 (320/2). E.g. secondary: 164 - 160 = 4px gap.\n // Inside: mirror that gap from the outer ring (368/2).\n if (inside) {\n const outerRingRadius = 368 / 2 + rOff;\n const ring2Radius = 320 / 2 + rOff;\n const tickLength = outerRadius - innerRadius;\n const gapFromRingEdge = Math.max(0, innerRadius - ring2Radius);\n outerRadius = outerRingRadius - gapFromRingEdge;\n innerRadius = outerRadius - tickLength;\n }\n const colorName = color ?? tickmarkColor(style, size);\n\n const x1 = Math.sin(rad) * innerRadius;\n const y1 = -Math.cos(rad) * innerRadius;\n const x2 = Math.sin(rad) * outerRadius;\n const y2 = -Math.cos(rad) * outerRadius;\n const strokeWidth =\n size === TickmarkType.zeroLine || size === TickmarkType.zeroLineThick\n ? 4\n : 1;\n const tick = svg`<line x1=${x1} y1=${y1} x2=${x2} y2=${y2} stroke=${colorName} stroke-width=${strokeWidth} vector-effect=\"non-scaling-stroke\"/>`;\n if (text) {\n if (rotation === undefined) {\n return [\n tick,\n textSvg(text, {angle, inside, scale, textRadius, endLabelsMaxMin}),\n ];\n } else {\n const newRadius =\n textRadius + ((4 / scale + 5) * (inside ? -1 : 1) * maxDigits) / 2;\n const textX = Math.sin(rad) * newRadius;\n const textY = -Math.cos(rad) * newRadius;\n return [\n tick,\n svg`<text x=${textX} y=${textY} class=\"label rotate ${inside ? 'inside' : ''}\" transform=\"rotate(${-rotation})\" transform-origin=\"${textX} ${textY}\">${text}</text>`,\n ];\n }\n }\n return tick;\n}\n\nfunction textSvg(\n text: string,\n {\n angle,\n inside,\n scale,\n textRadius,\n endLabelsMaxMin = false,\n }: {\n angle: number;\n inside: boolean;\n scale: number;\n textRadius: number;\n endLabelsMaxMin?: boolean;\n }\n) {\n const radHoriz = (angle * Math.PI) / 180;\n // \"Max-min\" placement: horizontal end labels (±90°) sit off the dead-center\n // tick (below outside / lifted inside), inset inward by label width.\n if (endLabelsMaxMin && Math.abs(Math.cos(radHoriz)) < 1e-6) {\n const sin = Math.sin(radHoriz);\n const inward = inside ? (6 + (text.length - 1) * 2.5) / scale : 14 / scale;\n const x = sin * (textRadius - inward);\n const y = inside ? -(6 / scale) : 12 / scale;\n return svg`<text x=${x} y=${y} class=\"label bottom ${inside ? 'inside' : ''}\">${text}</text>`;\n }\n\n let positionClass;\n if (angle === 0) {\n positionClass = 'top';\n } else if (angle < 180 && angle > 0) {\n positionClass = 'right';\n } else if (angle === 180) {\n positionClass = 'bottom';\n } else {\n positionClass = 'left';\n }\n const rad = (angle * Math.PI) / 180;\n const insideGain = inside ? -1 : 1;\n const yOffset = (7 / scale) * insideGain;\n const xOffset = (6 / scale) * insideGain;\n\n let textX = Math.sin(rad) * (textRadius + xOffset);\n if (angle > 180) {\n textX += (4 / scale) * insideGain;\n } else if (angle < 180 && angle > 0) {\n textX -= (4 / scale) * insideGain;\n }\n const textY = -Math.cos(rad) * (textRadius + yOffset);\n return svg`<text x=${textX} y=${textY} class=\"label ${positionClass} ${inside ? 'inside' : ''}\">${text}</text>`;\n}\n"],"names":["TickmarkType","TickmarkStyle"],"mappings":";AASO,IAAK,iCAAAA,kBAAL;AACLA,gBAAA,eAAA,IAAgB;AAChBA,gBAAA,UAAA,IAAW;AACXA,gBAAA,MAAA,IAAO;AACPA,gBAAA,SAAA,IAAU;AACVA,gBAAA,WAAA,IAAY;AACZA,gBAAA,UAAA,IAAW;AACXA,gBAAA,UAAA,IAAW;AAPD,SAAAA;AAAA,GAAA,gBAAA,CAAA,CAAA;AAUL,IAAK,kCAAAC,mBAAL;AACLA,iBAAA,SAAA,IAAU;AACVA,iBAAA,UAAA,IAAW;AAFD,SAAAA;AAAA,GAAA,iBAAA,CAAA,CAAA;AAKL,SAAS,cACd,OACA,cACQ;AACR,MAAI,UAAU,WAAuB;AACnC,WAAO;AAAA,EACT,OAAO;AACL,QAAI,iBAAiB,YAAuB;AAC1C,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACF;AAEO,SAAS,SACd,OACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,kBAAkB;AACpB,GAayC;AAEzC,MAAI,UAAU,YAAY,QAAQ,GAAG;AACnC,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AACA,QAAM,OAAO;AACb,MAAI;AACJ,MAAI;AACJ,eAAa,cAAc,IAAI,QAAQ,MAAM,SAAS,KAAK;AAC3D,QAAM,MAAO,QAAQ,KAAK,KAAM;AAChC,MAAI,SAAS,WAAsB;AACjC,kBAAc,MAAM,IAAI;AACxB,kBAAc,MAAM,IAAI;AAAA,EAC1B,WAAW,SAAS,aAAwB;AAC1C,kBAAc,MAAM,IAAI;AACxB,kBAAc,MAAM,IAAI;AAAA,EAC1B,WAAW,SAAS,UAAqB,SAAS,YAAuB;AACvE,kBAAc,MAAM,IAAI;AACxB,kBAAc,MAAM,IAAI;AAAA,EAC1B,WAAW,SAAS,iBAA4B;AAC9C,kBAAc,MAAM,IAAI;AACxB,kBAAc,MAAM,IAAI;AAAA,EAC1B,WAAW,SAAS,YAAuB;AACzC,kBAAc,MAAM,IAAI;AACxB,kBAAc,MAAM,IAAI;AAAA,EAC1B,OAAO;AACL,WAAO;AAAA,MACL,QAAQ,QAAQ,IAAI,EAAC,OAAO,QAAQ,OAAO,YAAY,gBAAA,CAAgB;AAAA,IAAA;AAAA,EAE3E;AAMA,MAAI,QAAQ;AACV,UAAM,kBAAkB,MAAM,IAAI;AAClC,UAAM,cAAc,MAAM,IAAI;AAC9B,UAAM,aAAa,cAAc;AACjC,UAAM,kBAAkB,KAAK,IAAI,GAAG,cAAc,WAAW;AAC7D,kBAAc,kBAAkB;AAChC,kBAAc,cAAc;AAAA,EAC9B;AACA,QAAM,YAAY,SAAS,cAAc,OAAO,IAAI;AAEpD,QAAM,KAAK,KAAK,IAAI,GAAG,IAAI;AAC3B,QAAM,KAAK,CAAC,KAAK,IAAI,GAAG,IAAI;AAC5B,QAAM,KAAK,KAAK,IAAI,GAAG,IAAI;AAC3B,QAAM,KAAK,CAAC,KAAK,IAAI,GAAG,IAAI;AAC5B,QAAM,cACJ,SAAS,cAAyB,SAAS,kBACvC,IACA;AACN,QAAM,OAAO,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,SAAS,iBAAiB,WAAW;AACzG,MAAI,MAAM;AACR,QAAI,aAAa,QAAW;AAC1B,aAAO;AAAA,QACL;AAAA,QACA,QAAQ,MAAM,EAAC,OAAO,QAAQ,OAAO,YAAY,iBAAgB;AAAA,MAAA;AAAA,IAErE,OAAO;AACL,YAAM,YACJ,cAAe,IAAI,QAAQ,MAAM,SAAS,KAAK,KAAK,YAAa;AACnE,YAAM,QAAQ,KAAK,IAAI,GAAG,IAAI;AAC9B,YAAM,QAAQ,CAAC,KAAK,IAAI,GAAG,IAAI;AAC/B,aAAO;AAAA,QACL;AAAA,QACA,cAAc,KAAK,MAAM,KAAK,wBAAwB,SAAS,WAAW,EAAE,uBAAuB,CAAC,QAAQ,wBAAwB,KAAK,IAAI,KAAK,KAAK,IAAI;AAAA,MAAA;AAAA,IAE/J;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,QACP,MACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAkB;AACpB,GAOA;AACA,QAAM,WAAY,QAAQ,KAAK,KAAM;AAGrC,MAAI,mBAAmB,KAAK,IAAI,KAAK,IAAI,QAAQ,CAAC,IAAI,MAAM;AAC1D,UAAM,MAAM,KAAK,IAAI,QAAQ;AAC7B,UAAM,SAAS,UAAU,KAAK,KAAK,SAAS,KAAK,OAAO,QAAQ,KAAK;AACrE,UAAM,IAAI,OAAO,aAAa;AAC9B,UAAM,IAAI,SAAS,EAAE,IAAI,SAAS,KAAK;AACvC,WAAO,cAAc,CAAC,MAAM,CAAC,wBAAwB,SAAS,WAAW,EAAE,KAAK,IAAI;AAAA,EACtF;AAEA,MAAI;AACJ,MAAI,UAAU,GAAG;AACf,oBAAgB;AAAA,EAClB,WAAW,QAAQ,OAAO,QAAQ,GAAG;AACnC,oBAAgB;AAAA,EAClB,WAAW,UAAU,KAAK;AACxB,oBAAgB;AAAA,EAClB,OAAO;AACL,oBAAgB;AAAA,EAClB;AACA,QAAM,MAAO,QAAQ,KAAK,KAAM;AAChC,QAAM,aAAa,SAAS,KAAK;AACjC,QAAM,UAAW,IAAI,QAAS;AAC9B,QAAM,UAAW,IAAI,QAAS;AAE9B,MAAI,QAAQ,KAAK,IAAI,GAAG,KAAK,aAAa;AAC1C,MAAI,QAAQ,KAAK;AACf,aAAU,IAAI,QAAS;AAAA,EACzB,WAAW,QAAQ,OAAO,QAAQ,GAAG;AACnC,aAAU,IAAI,QAAS;AAAA,EACzB;AACA,QAAM,QAAQ,CAAC,KAAK,IAAI,GAAG,KAAK,aAAa;AAC7C,SAAO,cAAc,KAAK,MAAM,KAAK,iBAAiB,aAAa,IAAI,SAAS,WAAW,EAAE,KAAK,IAAI;AACxG;"}
@@ -100,7 +100,7 @@ export declare function innerRingRadiusFor(type: WatchCircleType): number;
100
100
  * @property {number|undefined} rateOfTurnDegreesPerMinute - Measured rate of turn in degrees per minute (the maritime/AIS convention, see ES-TRIN 2025/1 Art. 3.02 and ITU-R M.1371). Sign controls direction (positive = starboard/clockwise). When defined, this drives both the dot animation (multiplied by `rotDotAnimationFactor`) and the port/starboard direction sign.
101
101
  * @property {number} rotDotAnimationFactor - Visual amplification factor applied only to the spinning-dot animation (not to bar extent). Default `18` keeps the legacy visual feel (≈1 rpm at 20°/min).
102
102
  * @property {number} rotationsPerMinute - **Deprecated.** Spin speed of the ROT dot ring in rotations per minute. Sign controls direction (positive = clockwise). Use `rateOfTurnDegreesPerMinute` instead.
103
- * @property {ZoomToFitArcFrame|undefined} arcFrame - Pre-computed zoom-to-fit arc frame. When set, the watch skips its own `computeZoomToFitArcFrame()` call and uses these values directly. Consumer instruments (e.g. rudder, instrument-radial) should compute the frame once and pass it here to avoid redundant computation.
103
+ * @property {ZoomToFitArcFrame|undefined} arcFrame - Pre-computed zoom-to-fit arc frame. When set, the watch skips its own `computeZoomToFitArcFrame()` call and uses these values directly. Consumer instruments (e.g. rudder, instrument-radial) should compute the frame once and pass it here to avoid redundant computation. If you pass `arcFrame`, you own keeping it in sync with `areas` / `watchCircleType` — obc-watch will NOT recompute it, so a stale frame renders stale geometry.
104
104
  */
105
105
  export declare class ObcWatch extends LitElement {
106
106
  private _setpointId;
@@ -147,8 +147,21 @@ export declare class ObcWatch extends LitElement {
147
147
  currentSymbolRadius: number | null;
148
148
  currentColor: string | undefined;
149
149
  starboardPortIndicator: boolean;
150
+ /** Top clip, % of height. Ignored when `zoomToFitArc` is true. */
150
151
  clipTop: number;
152
+ /** Bottom clip, % of height. Ignored when `zoomToFitArc` is true. */
151
153
  clipBottom: number;
154
+ /** Left clip, % of width — horizontal counterpart of clipTop/bottom (90° sectors). Ignored when `zoomToFitArc`. */
155
+ clipLeft: number;
156
+ /** Right clip, % of width — horizontal counterpart of clipTop/bottom (90° sectors). Ignored when `zoomToFitArc`. */
157
+ clipRight: number;
158
+ /**
159
+ * Place the horizontal end labels (±90°, e.g. min/max) below the tick instead
160
+ * of beside it. This is the "Max-min" label placement from the radial label
161
+ * model (External / Internal / Max-min) — see PR #903 / design discussion.
162
+ * Currently only used by the 180° sector of `obc-gauge-radial`.
163
+ */
164
+ endLabelsMaxMin: boolean;
152
165
  scaleWindIcon: number;
153
166
  rotation: number | undefined;
154
167
  zoomToFitArc: boolean;
@@ -186,6 +199,15 @@ export declare class ObcWatch extends LitElement {
186
199
  updated(changed: PropertyValues): void;
187
200
  private get innerRingRadius();
188
201
  private _rOff;
202
+ /**
203
+ * Radius for a dial-band edge under zoom: additive (`base + _rOff`), keeping
204
+ * band thickness constant in SVG units. INVARIANT: every band-edge radius
205
+ * (rings, value arc, bars, needles, inside-label `textRadius`) must go through
206
+ * this — mixing additive and multiplicative offsets misaligns ticks, labels,
207
+ * advice masks and arcs. The proportional experiments were removed for this
208
+ * reason (PR #903).
209
+ */
210
+ private _bandRadius;
189
211
  private watchCircle;
190
212
  private _renderTickFadeDefs;
191
213
  private renderCrosshair;
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/watch/watch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/watch/watch.ts"],"names":[],"mappings":"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"}
@@ -88,6 +88,9 @@ let ObcWatch = class extends LitElement {
88
88
  this.starboardPortIndicator = false;
89
89
  this.clipTop = 0;
90
90
  this.clipBottom = 0;
91
+ this.clipLeft = 0;
92
+ this.clipRight = 0;
93
+ this.endLabelsMaxMin = false;
91
94
  this.scaleWindIcon = 1;
92
95
  this.zoomToFitArc = false;
93
96
  this.tickFadeAngle = 0;
@@ -161,6 +164,17 @@ let ObcWatch = class extends LitElement {
161
164
  get innerRingRadius() {
162
165
  return innerRingRadiusFor(this.watchCircleType);
163
166
  }
167
+ /**
168
+ * Radius for a dial-band edge under zoom: additive (`base + _rOff`), keeping
169
+ * band thickness constant in SVG units. INVARIANT: every band-edge radius
170
+ * (rings, value arc, bars, needles, inside-label `textRadius`) must go through
171
+ * this — mixing additive and multiplicative offsets misaligns ticks, labels,
172
+ * advice masks and arcs. The proportional experiments were removed for this
173
+ * reason (PR #903).
174
+ */
175
+ _bandRadius(base) {
176
+ return base + this._rOff;
177
+ }
164
178
  watchCircle() {
165
179
  const rings = [];
166
180
  if (this.state !== InstrumentState.off) {
@@ -168,14 +182,16 @@ let ObcWatch = class extends LitElement {
168
182
  <circle
169
183
  cx="0"
170
184
  cy="0"
171
- r="${172 + this._rOff}"
185
+ r="${this._bandRadius(172)}"
172
186
  stroke="var(--instrument-frame-primary-color)"
173
187
  fill="none"
174
188
  stroke-width="24"
175
189
  />`);
176
190
  if (this.watchCircleType !== "single") {
177
- const r1 = RING2_RADIUS + this._rOff;
178
- const r2 = (this.watchCircleType === "doubleThin" ? RING3B_RADIUS : RING3_RADIUS) + this._rOff;
191
+ const r1 = this._bandRadius(RING2_RADIUS);
192
+ const r2 = this._bandRadius(
193
+ this.watchCircleType === "doubleThin" ? RING3B_RADIUS : RING3_RADIUS
194
+ );
179
195
  const r = (r1 + r2) / 2;
180
196
  const strokeWidth = r1 - r2;
181
197
  rings.push(
@@ -187,8 +203,8 @@ let ObcWatch = class extends LitElement {
187
203
  );
188
204
  }
189
205
  if (this.watchCircleType === "triple") {
190
- const r1 = RING3_RADIUS + this._rOff;
191
- const r2 = RING4_RADIUS + this._rOff;
206
+ const r1 = this._bandRadius(RING3_RADIUS);
207
+ const r2 = this._bandRadius(RING4_RADIUS);
192
208
  const r = (r1 + r2) / 2;
193
209
  const strokeWidth = r1 - r2;
194
210
  rings.push(
@@ -203,8 +219,8 @@ let ObcWatch = class extends LitElement {
203
219
  const svgPath = roundedArch({
204
220
  startAngle: area.startAngle,
205
221
  endAngle: area.endAngle,
206
- R: OUTER_RING_RADIUS + this._rOff,
207
- r: this.innerRingRadius + this._rOff,
222
+ R: this._bandRadius(OUTER_RING_RADIUS),
223
+ r: this._bandRadius(this.innerRingRadius),
208
224
  roundOutsideCut: area.roundOutsideCut,
209
225
  roundInsideCut: area.roundInsideCut
210
226
  });
@@ -234,7 +250,7 @@ let ObcWatch = class extends LitElement {
234
250
  if (this.state !== InstrumentState.off) {
235
251
  result.push(
236
252
  circle("outerRing", {
237
- radius: OUTER_RING_RADIUS + this._rOff,
253
+ radius: this._bandRadius(OUTER_RING_RADIUS),
238
254
  strokeWidth: 1,
239
255
  strokeColor: "var(--instrument-frame-tertiary-color)",
240
256
  strokePosition: "center",
@@ -243,7 +259,7 @@ let ObcWatch = class extends LitElement {
243
259
  );
244
260
  result.push(svg`
245
261
  ${circle("innerRing", {
246
- radius: this.innerRingRadius + this._rOff,
262
+ radius: this._bandRadius(this.innerRingRadius),
247
263
  strokeWidth: 1,
248
264
  strokeColor: "var(--instrument-frame-tertiary-color)",
249
265
  strokePosition: "center",
@@ -253,7 +269,7 @@ let ObcWatch = class extends LitElement {
253
269
  } else {
254
270
  result.push(svg`
255
271
  ${circle("innerRing", {
256
- radius: OUTER_RING_RADIUS + this._rOff,
272
+ radius: this._bandRadius(OUTER_RING_RADIUS),
257
273
  strokeWidth: 1,
258
274
  strokeColor: "var(--instrument-frame-tertiary-color)",
259
275
  strokePosition: "center",
@@ -281,7 +297,7 @@ let ObcWatch = class extends LitElement {
281
297
  const largeArc = b - a > 180 ? 1 : 0;
282
298
  return `M 0 0 L ${x1} ${y1} A ${R} ${R} 0 ${largeArc} 1 ${x2} ${y2} Z`;
283
299
  };
284
- const Rm = (OUTER_RING_RADIUS + this.innerRingRadius) / 2 + this._rOff;
300
+ const Rm = (this._bandRadius(OUTER_RING_RADIUS) + this._bandRadius(this.innerRingRadius)) / 2;
285
301
  const gx = (deg) => Rm * Math.sin(toRad(deg));
286
302
  const gy = (deg) => -Rm * Math.cos(toRad(deg));
287
303
  return svg`
@@ -375,8 +391,8 @@ let ObcWatch = class extends LitElement {
375
391
  const startAngle = Math.min(bar.startAngle, bar.endAngle);
376
392
  const endAngle = Math.max(bar.startAngle, bar.endAngle);
377
393
  const arc = roundedArch({
378
- r: RING3_RADIUS + this._rOff,
379
- R: RING2_RADIUS + this._rOff,
394
+ r: this._bandRadius(RING3_RADIUS),
395
+ R: this._bandRadius(RING2_RADIUS),
380
396
  startAngle,
381
397
  endAngle,
382
398
  roundInsideCut: false,
@@ -417,7 +433,7 @@ let ObcWatch = class extends LitElement {
417
433
  return svg`
418
434
  <rect
419
435
  transform="rotate(${needle.angle})"
420
- x="-4" y="${-(RING2_RADIUS + this._rOff)}" width="8" height="48" rx="4"
436
+ x="-4" y="${-this._bandRadius(RING2_RADIUS)}" width="8" height="48" rx="4"
421
437
  fill=${needle.fillColor}
422
438
  stroke=${needle.strokeColor}
423
439
  stroke-width="1"
@@ -478,15 +494,17 @@ let ObcWatch = class extends LitElement {
478
494
  viewBox = frame.viewBox;
479
495
  } else {
480
496
  this._rOff = 0;
481
- width = (176 + this.getPadding()) * 2;
482
- height = width * (1 - this.clipTop / 100 - this.clipBottom / 100);
483
- const top = -width / 2 + width * this.clipTop / 100;
484
- viewBox = `-${width / 2} ${top} ${width} ${height}`;
497
+ const full = (176 + this.getPadding()) * 2;
498
+ width = full * (1 - this.clipLeft / 100 - this.clipRight / 100);
499
+ height = full * (1 - this.clipTop / 100 - this.clipBottom / 100);
500
+ const left = -full / 2 + full * this.clipLeft / 100;
501
+ const top = -full / 2 + full * this.clipTop / 100;
502
+ viewBox = `${left} ${top} ${width} ${height}`;
485
503
  }
486
504
  const rOff = this._rOff;
487
505
  const scale = this.getScale({ width, height });
488
506
  const angleSetpoint = this.renderSetpoint();
489
- const textRadius = (this.tickmarksInside ? this.innerRingRadius : OUTER_RING_RADIUS) + rOff;
507
+ const textRadius = this.tickmarksInside ? this._bandRadius(this.innerRingRadius) : this._bandRadius(OUTER_RING_RADIUS);
490
508
  const maxDigits = Math.max(
491
509
  ...this.tickmarks.map((t) => t.text?.length ?? 0)
492
510
  );
@@ -501,7 +519,8 @@ let ObcWatch = class extends LitElement {
501
519
  rotation: this.rotation,
502
520
  maxDigits,
503
521
  color: t.color,
504
- radiusOffset: rOff
522
+ radiusOffset: rOff,
523
+ endLabelsMaxMin: this.endLabelsMaxMin
505
524
  })
506
525
  );
507
526
  const advices = this.advices ? this.advices.map((a) => renderAdvice(a, rOff)) : nothing;
@@ -866,6 +885,15 @@ __decorateClass([
866
885
  __decorateClass([
867
886
  property({ type: Number })
868
887
  ], ObcWatch.prototype, "clipBottom", 2);
888
+ __decorateClass([
889
+ property({ type: Number })
890
+ ], ObcWatch.prototype, "clipLeft", 2);
891
+ __decorateClass([
892
+ property({ type: Number })
893
+ ], ObcWatch.prototype, "clipRight", 2);
894
+ __decorateClass([
895
+ property({ type: Boolean })
896
+ ], ObcWatch.prototype, "endLabelsMaxMin", 2);
869
897
  __decorateClass([
870
898
  property({ type: Number })
871
899
  ], ObcWatch.prototype, "scaleWindIcon", 2);