@oicl/openbridge-webcomponents 0.0.15-dev-20240923191659 → 0.0.15-dev-20240923194534
Sign up to get free protection for your applications and to get access to all the features.
- package/.storybook/main.ts +58 -58
- package/.storybook/preview.ts +55 -55
- package/custom-elements.json +2745 -2745
- package/dist/navigation-instruments/compass/arrow.js.map +1 -1
- package/dist/navigation-instruments/compass/compass.js.map +1 -1
- package/dist/navigation-instruments/compass/radial-tickmark.js.map +1 -1
- package/dist/navigation-instruments/compass-flat/compass-flat.js.map +1 -1
- package/dist/navigation-instruments/thruster/advice.js.map +1 -1
- package/dist/navigation-instruments/watch/advice.js.map +1 -1
- package/dist/navigation-instruments/watch/label.js.map +1 -1
- package/dist/navigation-instruments/watch/watch.js.map +1 -1
- package/dist/navigation-instruments/watch-flat/tickmark-flat.js.map +1 -1
- package/dist/navigation-instruments/watch-flat/watch-flat.js.map +1 -1
- package/dist/svghelpers/rectangular.js.map +1 -1
- package/package.json +83 -83
- package/src/navigation-instruments/compass/arrow.ts +61 -61
- package/src/navigation-instruments/compass/compass.stories.ts +37 -37
- package/src/navigation-instruments/compass/compass.ts +132 -132
- package/src/navigation-instruments/compass/radial-tickmark.ts +77 -77
- package/src/navigation-instruments/compass-flat/compass-flat.css +23 -23
- package/src/navigation-instruments/compass-flat/compass-flat.stories.ts +35 -35
- package/src/navigation-instruments/compass-flat/compass-flat.ts +221 -221
- package/src/navigation-instruments/thruster/advice.ts +109 -109
- package/src/navigation-instruments/watch/advice.ts +120 -120
- package/src/navigation-instruments/watch/label.ts +69 -69
- package/src/navigation-instruments/watch/watch.css +11 -11
- package/src/navigation-instruments/watch/watch.ts +199 -199
- package/src/navigation-instruments/watch-flat/tickmark-flat.ts +62 -62
- package/src/navigation-instruments/watch-flat/watch-flat.css +19 -19
- package/src/navigation-instruments/watch-flat/watch-flat.stories.ts +17 -17
- package/src/navigation-instruments/watch-flat/watch-flat.ts +148 -148
- package/src/svghelpers/rectangular.ts +42 -42
- package/oicl-openbridge-webcomponents-0.0.15-dev-20240923191659.tgz +0 -0
@@ -1,61 +1,61 @@
|
|
1
|
-
import {SVGTemplateResult, svg} from 'lit';
|
2
|
-
|
3
|
-
export enum ArrowStyle {
|
4
|
-
HDG = 'HDG',
|
5
|
-
COG = 'COG',
|
6
|
-
}
|
7
|
-
|
8
|
-
export function arrow(
|
9
|
-
style: ArrowStyle,
|
10
|
-
angle: number
|
11
|
-
): SVGTemplateResult | SVGTemplateResult[] {
|
12
|
-
const colorName = 'var(--instrument-enhanced-secondary-color)';
|
13
|
-
|
14
|
-
if (style === ArrowStyle.HDG) {
|
15
|
-
return svg`
|
16
|
-
<g transform="translate(-32, -${256}) rotate(${angle}, 32, 256)">
|
17
|
-
<rect x="28" y="118" width="8" height="139" rx="4" fill="${colorName}" />
|
18
|
-
<rect x="30.0039" y="256" width="4" height="156" rx="2" fill="${colorName}" />
|
19
|
-
<circle cx="32" cy="256" r="8" fill="${colorName}" />
|
20
|
-
<mask
|
21
|
-
id="mask0_262_65165"
|
22
|
-
style="mask-type:luminance"
|
23
|
-
maskUnits="userSpaceOnUse"
|
24
|
-
x="8"
|
25
|
-
y="94"
|
26
|
-
width="48"
|
27
|
-
height="50"
|
28
|
-
>
|
29
|
-
<path
|
30
|
-
d="M13.2833 140.564L32 96L50.7167 140.564C51.4569 142.326 49.54 144.023 47.8805 143.075L32 136L16.1195 143.075C14.46 144.023 12.5432 142.326 13.2833 140.564Z"
|
31
|
-
fill="white"
|
32
|
-
stroke="black"
|
33
|
-
/>
|
34
|
-
</mask>
|
35
|
-
<g mask="url(#mask0_262_65165)">
|
36
|
-
<path
|
37
|
-
d="M13.2833 140.564L32 96L50.7167 140.564C51.4569 142.326 49.54 144.023 47.8805 143.075L32 136L16.1195 143.075C14.46 144.023 12.5432 142.326 13.2833 140.564Z"
|
38
|
-
fill="${colorName}"
|
39
|
-
/>
|
40
|
-
</g>
|
41
|
-
</g>
|
42
|
-
`;
|
43
|
-
} else if (style === ArrowStyle.COG) {
|
44
|
-
return svg`
|
45
|
-
<g transform="translate(-32, -${256}) rotate(${angle}, 32, 256)">
|
46
|
-
<path
|
47
|
-
fill-rule="evenodd"
|
48
|
-
clip-rule="evenodd"
|
49
|
-
d="M13.2833 140.564C12.5431 142.326 14.46 144.023 16.1195 143.075L32 136L47.8805 143.075C49.54 144.023 51.4568 142.326 50.7167 140.564L32 96L13.2833 140.564ZM32 106.33L19.2545 136.676L32 131.393L44.7455 136.676L32 106.33ZM49.865 139.602L49.8625 139.6L49.865 139.602Z"
|
50
|
-
fill="${colorName}"
|
51
|
-
/>
|
52
|
-
<rect x="30" y="133" width="4" height="124" rx="2" fill="${colorName}" />
|
53
|
-
<circle cx="32" cy="256" r="4" fill="${colorName}" />
|
54
|
-
</g>
|
55
|
-
`;
|
56
|
-
} else {
|
57
|
-
return [];
|
58
|
-
}
|
59
|
-
|
60
|
-
// return [...shaft, circle, arrowTip];
|
61
|
-
}
|
1
|
+
import {SVGTemplateResult, svg} from 'lit';
|
2
|
+
|
3
|
+
export enum ArrowStyle {
|
4
|
+
HDG = 'HDG',
|
5
|
+
COG = 'COG',
|
6
|
+
}
|
7
|
+
|
8
|
+
export function arrow(
|
9
|
+
style: ArrowStyle,
|
10
|
+
angle: number
|
11
|
+
): SVGTemplateResult | SVGTemplateResult[] {
|
12
|
+
const colorName = 'var(--instrument-enhanced-secondary-color)';
|
13
|
+
|
14
|
+
if (style === ArrowStyle.HDG) {
|
15
|
+
return svg`
|
16
|
+
<g transform="translate(-32, -${256}) rotate(${angle}, 32, 256)">
|
17
|
+
<rect x="28" y="118" width="8" height="139" rx="4" fill="${colorName}" />
|
18
|
+
<rect x="30.0039" y="256" width="4" height="156" rx="2" fill="${colorName}" />
|
19
|
+
<circle cx="32" cy="256" r="8" fill="${colorName}" />
|
20
|
+
<mask
|
21
|
+
id="mask0_262_65165"
|
22
|
+
style="mask-type:luminance"
|
23
|
+
maskUnits="userSpaceOnUse"
|
24
|
+
x="8"
|
25
|
+
y="94"
|
26
|
+
width="48"
|
27
|
+
height="50"
|
28
|
+
>
|
29
|
+
<path
|
30
|
+
d="M13.2833 140.564L32 96L50.7167 140.564C51.4569 142.326 49.54 144.023 47.8805 143.075L32 136L16.1195 143.075C14.46 144.023 12.5432 142.326 13.2833 140.564Z"
|
31
|
+
fill="white"
|
32
|
+
stroke="black"
|
33
|
+
/>
|
34
|
+
</mask>
|
35
|
+
<g mask="url(#mask0_262_65165)">
|
36
|
+
<path
|
37
|
+
d="M13.2833 140.564L32 96L50.7167 140.564C51.4569 142.326 49.54 144.023 47.8805 143.075L32 136L16.1195 143.075C14.46 144.023 12.5432 142.326 13.2833 140.564Z"
|
38
|
+
fill="${colorName}"
|
39
|
+
/>
|
40
|
+
</g>
|
41
|
+
</g>
|
42
|
+
`;
|
43
|
+
} else if (style === ArrowStyle.COG) {
|
44
|
+
return svg`
|
45
|
+
<g transform="translate(-32, -${256}) rotate(${angle}, 32, 256)">
|
46
|
+
<path
|
47
|
+
fill-rule="evenodd"
|
48
|
+
clip-rule="evenodd"
|
49
|
+
d="M13.2833 140.564C12.5431 142.326 14.46 144.023 16.1195 143.075L32 136L47.8805 143.075C49.54 144.023 51.4568 142.326 50.7167 140.564L32 96L13.2833 140.564ZM32 106.33L19.2545 136.676L32 131.393L44.7455 136.676L32 106.33ZM49.865 139.602L49.8625 139.6L49.865 139.602Z"
|
50
|
+
fill="${colorName}"
|
51
|
+
/>
|
52
|
+
<rect x="30" y="133" width="4" height="124" rx="2" fill="${colorName}" />
|
53
|
+
<circle cx="32" cy="256" r="4" fill="${colorName}" />
|
54
|
+
</g>
|
55
|
+
`;
|
56
|
+
} else {
|
57
|
+
return [];
|
58
|
+
}
|
59
|
+
|
60
|
+
// return [...shaft, circle, arrowTip];
|
61
|
+
}
|
@@ -1,37 +1,37 @@
|
|
1
|
-
import type {Meta, StoryObj} from '@storybook/web-components';
|
2
|
-
import {ObcCompass} from './compass';
|
3
|
-
import './compass';
|
4
|
-
import {beta6Decorator, widthDecorator} from '../../storybook-util';
|
5
|
-
import {AdviceType} from '../watch/advice';
|
6
|
-
|
7
|
-
const meta: Meta<typeof ObcCompass> = {
|
8
|
-
title: 'Navigation Instruments/Compass',
|
9
|
-
tags: ['autodocs'],
|
10
|
-
component: 'obc-compass',
|
11
|
-
args: {
|
12
|
-
width: 512,
|
13
|
-
heading: 311,
|
14
|
-
courseOverGround: 338,
|
15
|
-
headingAdvices: [
|
16
|
-
{
|
17
|
-
minAngle: 20,
|
18
|
-
maxAngle: 50,
|
19
|
-
type: AdviceType.advice,
|
20
|
-
hinted: false,
|
21
|
-
},
|
22
|
-
],
|
23
|
-
},
|
24
|
-
argTypes: {
|
25
|
-
width: {control: {type: 'range', min: 32, max: 1028, step: 1}},
|
26
|
-
heading: {control: {type: 'range', min: 0, max: 360, step: 1}},
|
27
|
-
courseOverGround: {control: {type: 'range', min: 0, max: 360, step: 1}},
|
28
|
-
},
|
29
|
-
decorators: [widthDecorator, beta6Decorator],
|
30
|
-
} satisfies Meta<ObcCompass>;
|
31
|
-
|
32
|
-
export default meta;
|
33
|
-
type Story = StoryObj<ObcCompass>;
|
34
|
-
|
35
|
-
export const Primary: Story = {
|
36
|
-
args: {},
|
37
|
-
};
|
1
|
+
import type {Meta, StoryObj} from '@storybook/web-components';
|
2
|
+
import {ObcCompass} from './compass';
|
3
|
+
import './compass';
|
4
|
+
import {beta6Decorator, widthDecorator} from '../../storybook-util';
|
5
|
+
import {AdviceType} from '../watch/advice';
|
6
|
+
|
7
|
+
const meta: Meta<typeof ObcCompass> = {
|
8
|
+
title: 'Navigation Instruments/Compass',
|
9
|
+
tags: ['autodocs'],
|
10
|
+
component: 'obc-compass',
|
11
|
+
args: {
|
12
|
+
width: 512,
|
13
|
+
heading: 311,
|
14
|
+
courseOverGround: 338,
|
15
|
+
headingAdvices: [
|
16
|
+
{
|
17
|
+
minAngle: 20,
|
18
|
+
maxAngle: 50,
|
19
|
+
type: AdviceType.advice,
|
20
|
+
hinted: false,
|
21
|
+
},
|
22
|
+
],
|
23
|
+
},
|
24
|
+
argTypes: {
|
25
|
+
width: {control: {type: 'range', min: 32, max: 1028, step: 1}},
|
26
|
+
heading: {control: {type: 'range', min: 0, max: 360, step: 1}},
|
27
|
+
courseOverGround: {control: {type: 'range', min: 0, max: 360, step: 1}},
|
28
|
+
},
|
29
|
+
decorators: [widthDecorator, beta6Decorator],
|
30
|
+
} satisfies Meta<ObcCompass>;
|
31
|
+
|
32
|
+
export default meta;
|
33
|
+
type Story = StoryObj<ObcCompass>;
|
34
|
+
|
35
|
+
export const Primary: Story = {
|
36
|
+
args: {},
|
37
|
+
};
|
@@ -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
|
+
}
|