@oicl/openbridge-webcomponents 0.0.15-dev-20240923190011 → 0.0.15-dev-20240923191659

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. package/.storybook/main.ts +58 -58
  2. package/.storybook/preview.ts +55 -55
  3. package/custom-elements.json +3 -3
  4. package/dist/navigation-instruments/compass/arrow.js.map +1 -1
  5. package/dist/navigation-instruments/compass/compass.js.map +1 -1
  6. package/dist/navigation-instruments/compass/radial-tickmark.js.map +1 -1
  7. package/dist/navigation-instruments/compass-flat/compass-flat.js.map +1 -1
  8. package/dist/navigation-instruments/thruster/advice.js.map +1 -1
  9. package/dist/navigation-instruments/watch/advice.js.map +1 -1
  10. package/dist/navigation-instruments/watch/label.js.map +1 -1
  11. package/dist/navigation-instruments/watch/watch.js.map +1 -1
  12. package/dist/navigation-instruments/watch-flat/tickmark-flat.js.map +1 -1
  13. package/dist/navigation-instruments/watch-flat/watch-flat.js.map +1 -1
  14. package/dist/svghelpers/rectangular.js.map +1 -1
  15. package/oicl-openbridge-webcomponents-0.0.15-dev-20240923191659.tgz +0 -0
  16. package/package.json +83 -83
  17. package/src/navigation-instruments/compass/arrow.ts +61 -61
  18. package/src/navigation-instruments/compass/compass.stories.ts +37 -37
  19. package/src/navigation-instruments/compass/compass.ts +132 -132
  20. package/src/navigation-instruments/compass/radial-tickmark.ts +77 -77
  21. package/src/navigation-instruments/compass-flat/compass-flat.css +23 -23
  22. package/src/navigation-instruments/compass-flat/compass-flat.stories.ts +35 -35
  23. package/src/navigation-instruments/compass-flat/compass-flat.ts +221 -221
  24. package/src/navigation-instruments/thruster/advice.ts +109 -109
  25. package/src/navigation-instruments/watch/advice.ts +120 -120
  26. package/src/navigation-instruments/watch/label.ts +69 -69
  27. package/src/navigation-instruments/watch/watch.css +11 -11
  28. package/src/navigation-instruments/watch/watch.ts +199 -199
  29. package/src/navigation-instruments/watch-flat/tickmark-flat.ts +62 -62
  30. package/src/navigation-instruments/watch-flat/watch-flat.css +19 -19
  31. package/src/navigation-instruments/watch-flat/watch-flat.stories.ts +17 -17
  32. package/src/navigation-instruments/watch-flat/watch-flat.ts +148 -148
  33. package/src/svghelpers/rectangular.ts +42 -42
@@ -1,132 +1,132 @@
1
- import {LitElement, css, html} from 'lit';
2
- import {customElement, property} from 'lit/decorators.js';
3
- import '../watch/watch';
4
- import {Tickmark, TickmarkType} from '../watch/tickmark';
5
- import {arrow, ArrowStyle} from './arrow';
6
- import {
7
- AdviceState,
8
- AdviceType,
9
- AngleAdvice,
10
- AngleAdviceRaw,
11
- } from '../watch/advice';
12
- import {radialTickmarks} from './radial-tickmark';
13
-
14
- @customElement('obc-compass')
15
- export class ObcCompass extends LitElement {
16
- @property({type: Number}) heading = 0;
17
- @property({type: Number}) courseOverGround = 0;
18
- @property({type: Number}) padding = 48;
19
- @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];
20
- @property({type: Number}) containerWidth = 0;
21
-
22
- private resizeObserver: ResizeObserver = new ResizeObserver((entries) => {
23
- for (const entry of entries) {
24
- this.containerWidth = entry.contentRect.width;
25
- this.adjustPadding();
26
- }
27
- });
28
-
29
- override connectedCallback() {
30
- super.connectedCallback();
31
- this.resizeObserver.observe(this);
32
- }
33
-
34
- override disconnectedCallback() {
35
- super.disconnectedCallback();
36
- this.resizeObserver.unobserve(this);
37
- }
38
-
39
- private adjustPadding() {
40
- const deltaWidth = 512 - this.containerWidth;
41
- const steps = deltaWidth / 128;
42
- let deltaPadding = 0;
43
- if (deltaWidth > 0) {
44
- deltaPadding = steps * 48;
45
- } else {
46
- deltaPadding = steps * 6;
47
- }
48
-
49
- this.padding = 72 + deltaPadding;
50
- }
51
-
52
- private get angleAdviceRaw(): AngleAdviceRaw[] {
53
- return this.headingAdvices.map(({minAngle, maxAngle, hinted, type}) => {
54
- const state =
55
- this.heading >= minAngle && this.heading <= maxAngle
56
- ? AdviceState.triggered
57
- : hinted
58
- ? AdviceState.hinted
59
- : AdviceState.regular;
60
- return {minAngle, maxAngle, type, state};
61
- });
62
- }
63
-
64
- override render() {
65
- const tickmarks: Tickmark[] = [
66
- {angle: 0, type: TickmarkType.main},
67
- {angle: 90, type: TickmarkType.main},
68
- {angle: 180, type: TickmarkType.main},
69
- {angle: 270, type: TickmarkType.main},
70
- ];
71
-
72
- const rt = this.headingAdvices.map(({minAngle, maxAngle, type}) =>
73
- radialTickmarks(
74
- minAngle,
75
- maxAngle,
76
- type === AdviceType.caution ? TickmarkType.secondary : undefined
77
- )
78
- );
79
-
80
- const width = (176 + this.padding) * 2;
81
- const viewBox = `-${width / 2} -${width / 2} ${width} ${width}`;
82
-
83
- return html`
84
- <div class="container">
85
- <obc-watch
86
- .padding=${this.padding}
87
- .advices=${this.angleAdviceRaw}
88
- .tickmarks=${tickmarks}
89
- .labelFrameEnabled=${true}
90
- .crosshairEnabled=${true}
91
- >
92
- </obc-watch>
93
- <svg viewBox="${viewBox}">
94
- ${rt} ${arrow(ArrowStyle.HDG, this.heading)}
95
- ${arrow(ArrowStyle.COG, this.courseOverGround)}
96
- </svg>
97
- </div>
98
- `;
99
- }
100
-
101
- static override styles = css`
102
- * {
103
- box-sizing: border-box;
104
- }
105
-
106
- .container {
107
- position: relative;
108
- width: 100%;
109
- height: 100%;
110
- }
111
-
112
- .container > * {
113
- position: absolute;
114
- top: 0;
115
- left: 0;
116
- width: 100%;
117
- height: 100%;
118
- }
119
-
120
- :host {
121
- display: block;
122
- width: 100%;
123
- height: 100%;
124
- }
125
- `;
126
- }
127
-
128
- declare global {
129
- interface HTMLElementTagNameMap {
130
- 'obc-compass': ObcCompass;
131
- }
132
- }
1
+ import {LitElement, css, html} from 'lit';
2
+ import {customElement, property} from 'lit/decorators.js';
3
+ import '../watch/watch';
4
+ import {Tickmark, TickmarkType} from '../watch/tickmark';
5
+ import {arrow, ArrowStyle} from './arrow';
6
+ import {
7
+ AdviceState,
8
+ AdviceType,
9
+ AngleAdvice,
10
+ AngleAdviceRaw,
11
+ } from '../watch/advice';
12
+ import {radialTickmarks} from './radial-tickmark';
13
+
14
+ @customElement('obc-compass')
15
+ export class ObcCompass extends LitElement {
16
+ @property({type: Number}) heading = 0;
17
+ @property({type: Number}) courseOverGround = 0;
18
+ @property({type: Number}) padding = 48;
19
+ @property({type: Array, attribute: false}) headingAdvices: AngleAdvice[] = [];
20
+ @property({type: Number}) containerWidth = 0;
21
+
22
+ private resizeObserver: ResizeObserver = new ResizeObserver((entries) => {
23
+ for (const entry of entries) {
24
+ this.containerWidth = entry.contentRect.width;
25
+ this.adjustPadding();
26
+ }
27
+ });
28
+
29
+ override connectedCallback() {
30
+ super.connectedCallback();
31
+ this.resizeObserver.observe(this);
32
+ }
33
+
34
+ override disconnectedCallback() {
35
+ super.disconnectedCallback();
36
+ this.resizeObserver.unobserve(this);
37
+ }
38
+
39
+ private adjustPadding() {
40
+ const deltaWidth = 512 - this.containerWidth;
41
+ const steps = deltaWidth / 128;
42
+ let deltaPadding = 0;
43
+ if (deltaWidth > 0) {
44
+ deltaPadding = steps * 48;
45
+ } else {
46
+ deltaPadding = steps * 6;
47
+ }
48
+
49
+ this.padding = 72 + deltaPadding;
50
+ }
51
+
52
+ private get angleAdviceRaw(): AngleAdviceRaw[] {
53
+ return this.headingAdvices.map(({minAngle, maxAngle, hinted, type}) => {
54
+ const state =
55
+ this.heading >= minAngle && this.heading <= maxAngle
56
+ ? AdviceState.triggered
57
+ : hinted
58
+ ? AdviceState.hinted
59
+ : AdviceState.regular;
60
+ return {minAngle, maxAngle, type, state};
61
+ });
62
+ }
63
+
64
+ override render() {
65
+ const tickmarks: Tickmark[] = [
66
+ {angle: 0, type: TickmarkType.main},
67
+ {angle: 90, type: TickmarkType.main},
68
+ {angle: 180, type: TickmarkType.main},
69
+ {angle: 270, type: TickmarkType.main},
70
+ ];
71
+
72
+ const rt = this.headingAdvices.map(({minAngle, maxAngle, type}) =>
73
+ radialTickmarks(
74
+ minAngle,
75
+ maxAngle,
76
+ type === AdviceType.caution ? TickmarkType.secondary : undefined
77
+ )
78
+ );
79
+
80
+ const width = (176 + this.padding) * 2;
81
+ const viewBox = `-${width / 2} -${width / 2} ${width} ${width}`;
82
+
83
+ return html`
84
+ <div class="container">
85
+ <obc-watch
86
+ .padding=${this.padding}
87
+ .advices=${this.angleAdviceRaw}
88
+ .tickmarks=${tickmarks}
89
+ .labelFrameEnabled=${true}
90
+ .crosshairEnabled=${true}
91
+ >
92
+ </obc-watch>
93
+ <svg viewBox="${viewBox}">
94
+ ${rt} ${arrow(ArrowStyle.HDG, this.heading)}
95
+ ${arrow(ArrowStyle.COG, this.courseOverGround)}
96
+ </svg>
97
+ </div>
98
+ `;
99
+ }
100
+
101
+ static override styles = css`
102
+ * {
103
+ box-sizing: border-box;
104
+ }
105
+
106
+ .container {
107
+ position: relative;
108
+ width: 100%;
109
+ height: 100%;
110
+ }
111
+
112
+ .container > * {
113
+ position: absolute;
114
+ top: 0;
115
+ left: 0;
116
+ width: 100%;
117
+ height: 100%;
118
+ }
119
+
120
+ :host {
121
+ display: block;
122
+ width: 100%;
123
+ height: 100%;
124
+ }
125
+ `;
126
+ }
127
+
128
+ declare global {
129
+ interface HTMLElementTagNameMap {
130
+ 'obc-compass': ObcCompass;
131
+ }
132
+ }
@@ -1,77 +1,77 @@
1
- import {SVGTemplateResult, svg} from 'lit';
2
- import {TickmarkType, TickmarkStyle, tickmarkColor} from '../watch/tickmark';
3
-
4
- export function radialTickmarks(
5
- minAngle: number,
6
- maxAngle: number,
7
- type: TickmarkType | undefined
8
- ): SVGTemplateResult[] {
9
- if (type === TickmarkType.main || type === TickmarkType.tertiary) {
10
- throw new Error(
11
- 'Only secondary tickmarks or undefined tickmarks (dots) are supported'
12
- );
13
- }
14
-
15
- const origin = {x: 0, y: 0};
16
- const radius = 320 / 2;
17
- const strokeWidth = '1.2';
18
- const margin = 1.5;
19
- const colorName = tickmarkColor(TickmarkStyle.hinted);
20
- const tickWidth = type === TickmarkType.secondary ? 4 : 1;
21
- const tickmarks: SVGTemplateResult[] = [];
22
-
23
- const sinMin = Math.sin((minAngle * Math.PI) / 180);
24
- const cosMin = Math.cos((minAngle * Math.PI) / 180);
25
- const sinMax = Math.sin((maxAngle * Math.PI) / 180);
26
- const cosMax = Math.cos((maxAngle * Math.PI) / 180);
27
-
28
- const deltaIncrement = tickWidth * margin;
29
-
30
- for (let deltaR = 0; deltaR <= radius; deltaR += deltaIncrement) {
31
- const xMin = origin.x + sinMin * deltaR;
32
- const yMin = origin.y - cosMin * deltaR;
33
- const xMax = origin.x + sinMax * deltaR;
34
- const yMax = origin.y - cosMax * deltaR;
35
-
36
- if (type === undefined) {
37
- const size = 1;
38
- tickmarks.push(
39
- svg`<rect
40
- x=${xMin - size / 2}
41
- y=${yMin - size / 2}
42
- width=${size}
43
- height=${size}
44
- fill=${colorName}
45
- transform="rotate(${minAngle} ${xMin} ${yMin})"
46
- vector-effect="non-scaling-stroke"/>`
47
- );
48
- tickmarks.push(
49
- svg`<rect
50
- x=${xMax - size / 2}
51
- y=${yMax - size / 2}
52
- width=${size}
53
- height=${size}
54
- fill=${colorName}
55
- transform="rotate(${maxAngle} ${xMax} ${yMax})"
56
- vector-effect="non-scaling-stroke"/>`
57
- );
58
- } else {
59
- const currentRadius = Math.min(deltaR + tickWidth, radius);
60
- const x2Min = origin.x + sinMin * currentRadius;
61
- const y2Min = origin.y - cosMin * currentRadius;
62
- const x2Max = origin.x + sinMax * currentRadius;
63
- const y2Max = origin.y - cosMax * currentRadius;
64
-
65
- tickmarks.push(
66
- svg`<line x1=${xMin} y1=${yMin} x2=${x2Min} y2=${y2Min} stroke=${colorName} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>`
67
- );
68
- tickmarks.push(
69
- svg`<line x1=${xMax} y1=${yMax} x2=${x2Max} y2=${y2Max} stroke=${colorName} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>`
70
- );
71
-
72
- if (currentRadius >= radius) break;
73
- }
74
- }
75
-
76
- return tickmarks;
77
- }
1
+ import {SVGTemplateResult, svg} from 'lit';
2
+ import {TickmarkType, TickmarkStyle, tickmarkColor} from '../watch/tickmark';
3
+
4
+ export function radialTickmarks(
5
+ minAngle: number,
6
+ maxAngle: number,
7
+ type: TickmarkType | undefined
8
+ ): SVGTemplateResult[] {
9
+ if (type === TickmarkType.main || type === TickmarkType.tertiary) {
10
+ throw new Error(
11
+ 'Only secondary tickmarks or undefined tickmarks (dots) are supported'
12
+ );
13
+ }
14
+
15
+ const origin = {x: 0, y: 0};
16
+ const radius = 320 / 2;
17
+ const strokeWidth = '1.2';
18
+ const margin = 1.5;
19
+ const colorName = tickmarkColor(TickmarkStyle.hinted);
20
+ const tickWidth = type === TickmarkType.secondary ? 4 : 1;
21
+ const tickmarks: SVGTemplateResult[] = [];
22
+
23
+ const sinMin = Math.sin((minAngle * Math.PI) / 180);
24
+ const cosMin = Math.cos((minAngle * Math.PI) / 180);
25
+ const sinMax = Math.sin((maxAngle * Math.PI) / 180);
26
+ const cosMax = Math.cos((maxAngle * Math.PI) / 180);
27
+
28
+ const deltaIncrement = tickWidth * margin;
29
+
30
+ for (let deltaR = 0; deltaR <= radius; deltaR += deltaIncrement) {
31
+ const xMin = origin.x + sinMin * deltaR;
32
+ const yMin = origin.y - cosMin * deltaR;
33
+ const xMax = origin.x + sinMax * deltaR;
34
+ const yMax = origin.y - cosMax * deltaR;
35
+
36
+ if (type === undefined) {
37
+ const size = 1;
38
+ tickmarks.push(
39
+ svg`<rect
40
+ x=${xMin - size / 2}
41
+ y=${yMin - size / 2}
42
+ width=${size}
43
+ height=${size}
44
+ fill=${colorName}
45
+ transform="rotate(${minAngle} ${xMin} ${yMin})"
46
+ vector-effect="non-scaling-stroke"/>`
47
+ );
48
+ tickmarks.push(
49
+ svg`<rect
50
+ x=${xMax - size / 2}
51
+ y=${yMax - size / 2}
52
+ width=${size}
53
+ height=${size}
54
+ fill=${colorName}
55
+ transform="rotate(${maxAngle} ${xMax} ${yMax})"
56
+ vector-effect="non-scaling-stroke"/>`
57
+ );
58
+ } else {
59
+ const currentRadius = Math.min(deltaR + tickWidth, radius);
60
+ const x2Min = origin.x + sinMin * currentRadius;
61
+ const y2Min = origin.y - cosMin * currentRadius;
62
+ const x2Max = origin.x + sinMax * currentRadius;
63
+ const y2Max = origin.y - cosMax * currentRadius;
64
+
65
+ tickmarks.push(
66
+ svg`<line x1=${xMin} y1=${yMin} x2=${x2Min} y2=${y2Min} stroke=${colorName} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>`
67
+ );
68
+ tickmarks.push(
69
+ svg`<line x1=${xMax} y1=${yMax} x2=${x2Max} y2=${y2Max} stroke=${colorName} stroke-width=${strokeWidth} vector-effect="non-scaling-stroke"/>`
70
+ );
71
+
72
+ if (currentRadius >= radius) break;
73
+ }
74
+ }
75
+
76
+ return tickmarks;
77
+ }
@@ -1,23 +1,23 @@
1
- * {
2
- box-sizing: border-box;
3
- }
4
-
5
- .container {
6
- position: relative;
7
- width: 100%;
8
- height: 100%;
9
- }
10
-
11
- .container > * {
12
- position: absolute;
13
- top: 0;
14
- left: 0;
15
- width: 100%;
16
- height: 100%;
17
- }
18
-
19
- :host {
20
- display: block;
21
- width: 100%;
22
- height: 100%;
23
- }
1
+ * {
2
+ box-sizing: border-box;
3
+ }
4
+
5
+ .container {
6
+ position: relative;
7
+ width: 100%;
8
+ height: 100%;
9
+ }
10
+
11
+ .container > * {
12
+ position: absolute;
13
+ top: 0;
14
+ left: 0;
15
+ width: 100%;
16
+ height: 100%;
17
+ }
18
+
19
+ :host {
20
+ display: block;
21
+ width: 100%;
22
+ height: 100%;
23
+ }
@@ -1,35 +1,35 @@
1
- import type {Meta, StoryObj} from '@storybook/web-components';
2
- import {ObcCompassFlat} from './compass-flat';
3
- import './compass-flat';
4
- import {beta6Decorator, widthDecorator} from '../../storybook-util';
5
- import {LabelPosition} from './compass-flat';
6
-
7
- const meta: Meta<typeof ObcCompassFlat> = {
8
- title: 'Navigation Instruments/Compass flat',
9
- tags: ['autodocs'],
10
- component: 'obc-compass-flat',
11
- args: {
12
- width: 512,
13
- heading: 45,
14
- courseOverGround: 50,
15
- FOVIndicator: false,
16
- minFOV: 90,
17
- },
18
- argTypes: {
19
- width: {control: {type: 'range', min: 32, max: 1028, step: 1}},
20
- heading: {control: {type: 'range', min: 0, max: 360, step: 1}},
21
- courseOverGround: {control: {type: 'range', min: 0, max: 360, step: 1}},
22
- },
23
- decorators: [widthDecorator, beta6Decorator],
24
- } satisfies Meta<ObcCompassFlat>;
25
-
26
- export default meta;
27
- type Story = StoryObj<ObcCompassFlat>;
28
-
29
- export const Primary: Story = {};
30
-
31
- export const WithFOVIndicator: Story = {
32
- args: {
33
- FOVIndicator: true,
34
- },
35
- };
1
+ import type {Meta, StoryObj} from '@storybook/web-components';
2
+ import {ObcCompassFlat} from './compass-flat';
3
+ import './compass-flat';
4
+ import {beta6Decorator, widthDecorator} from '../../storybook-util';
5
+ import {LabelPosition} from './compass-flat';
6
+
7
+ const meta: Meta<typeof ObcCompassFlat> = {
8
+ title: 'Navigation Instruments/Compass flat',
9
+ tags: ['autodocs'],
10
+ component: 'obc-compass-flat',
11
+ args: {
12
+ width: 512,
13
+ heading: 45,
14
+ courseOverGround: 50,
15
+ FOVIndicator: false,
16
+ minFOV: 90,
17
+ },
18
+ argTypes: {
19
+ width: {control: {type: 'range', min: 32, max: 1028, step: 1}},
20
+ heading: {control: {type: 'range', min: 0, max: 360, step: 1}},
21
+ courseOverGround: {control: {type: 'range', min: 0, max: 360, step: 1}},
22
+ },
23
+ decorators: [widthDecorator, beta6Decorator],
24
+ } satisfies Meta<ObcCompassFlat>;
25
+
26
+ export default meta;
27
+ type Story = StoryObj<ObcCompassFlat>;
28
+
29
+ export const Primary: Story = {};
30
+
31
+ export const WithFOVIndicator: Story = {
32
+ args: {
33
+ FOVIndicator: true,
34
+ },
35
+ };