@oicl/openbridge-webcomponents 0.0.15-dev-20240923191659 → 0.0.15-dev-20240923193604
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 +9 -9
- 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,199 +1,199 @@
|
|
1
|
-
import {
|
2
|
-
LitElement,
|
3
|
-
SVGTemplateResult,
|
4
|
-
html,
|
5
|
-
nothing,
|
6
|
-
svg,
|
7
|
-
unsafeCSS,
|
8
|
-
} from 'lit';
|
9
|
-
import {customElement, property} from 'lit/decorators.js';
|
10
|
-
import {circle} from '../../svghelpers';
|
11
|
-
import {roundedArch} from '../../svghelpers/roundedArch';
|
12
|
-
import {InstrumentState} from '../types';
|
13
|
-
import compentStyle from './watch.css?inline';
|
14
|
-
import {ResizeController} from '@lit-labs/observers/resize-controller.js';
|
15
|
-
import {AngleAdviceRaw, renderAdvice} from './advice';
|
16
|
-
import {Tickmark, TickmarkStyle, tickmark} from './tickmark';
|
17
|
-
import {renderLabels} from './label';
|
18
|
-
|
19
|
-
@customElement('obc-watch')
|
20
|
-
export class ObcWatch extends LitElement {
|
21
|
-
@property({type: String}) state: InstrumentState = InstrumentState.inCommand;
|
22
|
-
@property({type: Number}) angleSetpoint: number | undefined;
|
23
|
-
@property({type: Boolean}) atAngleSetpoint: boolean = false;
|
24
|
-
@property({type: Number}) padding = 24;
|
25
|
-
@property({type: Number}) cutAngleStart: number | null = null;
|
26
|
-
@property({type: Number}) cutAngleEnd: number | null = null;
|
27
|
-
@property({type: Boolean}) roundOutsideCut = false;
|
28
|
-
@property({type: Boolean}) roundInsideCut = false;
|
29
|
-
@property({type: Array, attribute: false}) tickmarks: Tickmark[] = [];
|
30
|
-
@property({type: Array, attribute: false}) advices: AngleAdviceRaw[] = [];
|
31
|
-
@property({type: Boolean}) crosshairEnabled: boolean = false;
|
32
|
-
@property({type: Boolean}) labelFrameEnabled: boolean = false;
|
33
|
-
|
34
|
-
// @ts-expect-error TS6133: The controller unsures that the render
|
35
|
-
// function is called on resize of the element
|
36
|
-
private _resizeController = new ResizeController(this, {});
|
37
|
-
|
38
|
-
private watchCircle(): SVGTemplateResult {
|
39
|
-
if (this.cutAngleStart === null || this.cutAngleEnd === null) {
|
40
|
-
return svg`
|
41
|
-
<defs>
|
42
|
-
<mask id="mask1" x="0" y="0" width="100%" height="100%">
|
43
|
-
<rect x="-200" y="-200" width="400" height="400" fill="white" />
|
44
|
-
<circle cx="0" cy="0" r="160" fill="black" />
|
45
|
-
</mask>
|
46
|
-
</defs>
|
47
|
-
${
|
48
|
-
this.state === InstrumentState.off
|
49
|
-
? null
|
50
|
-
: svg`
|
51
|
-
<circle
|
52
|
-
cx="0"
|
53
|
-
cy="0"
|
54
|
-
r="184"
|
55
|
-
fill="var(--instrument-frame-primary-color)"
|
56
|
-
mask="url(#mask1)"
|
57
|
-
/>`
|
58
|
-
}
|
59
|
-
${circle('innerRing', {
|
60
|
-
radius: 320 / 2,
|
61
|
-
strokeWidth: 1,
|
62
|
-
strokeColor: 'var(--instrument-frame-tertiary-color)',
|
63
|
-
strokePosition: 'center',
|
64
|
-
fillColor: 'none',
|
65
|
-
})}
|
66
|
-
${
|
67
|
-
this.state === InstrumentState.off
|
68
|
-
? null
|
69
|
-
: circle('outerRing', {
|
70
|
-
radius: 368 / 2,
|
71
|
-
strokeWidth: 1,
|
72
|
-
strokeColor: 'var(--instrument-frame-tertiary-color)',
|
73
|
-
strokePosition: 'center',
|
74
|
-
fillColor: 'none',
|
75
|
-
})
|
76
|
-
}
|
77
|
-
`;
|
78
|
-
} else {
|
79
|
-
const R = 184;
|
80
|
-
const r = 160;
|
81
|
-
const svgPath = roundedArch({
|
82
|
-
startAngle: this.cutAngleStart,
|
83
|
-
endAngle: this.cutAngleEnd,
|
84
|
-
R,
|
85
|
-
r,
|
86
|
-
roundOutsideCut: this.roundOutsideCut,
|
87
|
-
roundInsideCut: this.roundInsideCut,
|
88
|
-
});
|
89
|
-
return svg`
|
90
|
-
<path d=${svgPath} fill="var(--instrument-frame-primary-color)"
|
91
|
-
stroke="var(--instrument-frame-tertiary-color)"
|
92
|
-
vector-effect="non-scaling-stroke"/>
|
93
|
-
`;
|
94
|
-
}
|
95
|
-
}
|
96
|
-
|
97
|
-
private renderCrosshair(radius: number): SVGTemplateResult {
|
98
|
-
return svg`
|
99
|
-
<line
|
100
|
-
x1="-${radius}"
|
101
|
-
y1="0"
|
102
|
-
x2="${radius}"
|
103
|
-
y2="0"
|
104
|
-
stroke="var(--instrument-frame-tertiary-color)"
|
105
|
-
stroke-width="1"
|
106
|
-
vector-effect="non-scaling-stroke"
|
107
|
-
/>
|
108
|
-
<line
|
109
|
-
x1="0"
|
110
|
-
y1="-${radius}"
|
111
|
-
x2="0"
|
112
|
-
y2="${radius}"
|
113
|
-
stroke="var(--instrument-frame-tertiary-color)"
|
114
|
-
stroke-width="1"
|
115
|
-
vector-effect="non-scaling-stroke"
|
116
|
-
/>
|
117
|
-
`;
|
118
|
-
}
|
119
|
-
|
120
|
-
override render() {
|
121
|
-
const width = (176 + this.padding) * 2;
|
122
|
-
const viewBox = `-${width / 2} -${width / 2} ${width} ${width}`;
|
123
|
-
const angleSetpoint = this.renderSetpoint();
|
124
|
-
const scale = this.clientWidth / width;
|
125
|
-
const tickmarks = this.tickmarks.map((t) =>
|
126
|
-
tickmark(t.angle, t.type, TickmarkStyle.hinted, scale, t.text)
|
127
|
-
);
|
128
|
-
const advices = this.advices
|
129
|
-
? this.advices.map((a) => renderAdvice(a))
|
130
|
-
: nothing;
|
131
|
-
const labels = this.labelFrameEnabled ? renderLabels(scale) : nothing;
|
132
|
-
|
133
|
-
return html`
|
134
|
-
<svg
|
135
|
-
width="100%"
|
136
|
-
height="100%"
|
137
|
-
viewBox=${viewBox}
|
138
|
-
style="--scale: ${scale}"
|
139
|
-
>
|
140
|
-
${this.watchCircle()} ${tickmarks} ${advices} ${angleSetpoint} ${labels}
|
141
|
-
${this.crosshairEnabled ? this.renderCrosshair(320 / 2) : nothing}
|
142
|
-
</svg>
|
143
|
-
`;
|
144
|
-
}
|
145
|
-
|
146
|
-
private renderSetpoint(): SVGTemplateResult | typeof nothing {
|
147
|
-
let setPointColor = 'var(--instrument-enhanced-primary-color)';
|
148
|
-
if (this.atAngleSetpoint) {
|
149
|
-
setPointColor = 'var(--instrument-enhanced-secondary-color)';
|
150
|
-
}
|
151
|
-
if (this.state === InstrumentState.active) {
|
152
|
-
setPointColor = 'var(--instrument-regular-primary-color)';
|
153
|
-
if (this.atAngleSetpoint) {
|
154
|
-
setPointColor = 'var(--instrument-regular-secondary-color)';
|
155
|
-
}
|
156
|
-
} else if (this.state === InstrumentState.loading) {
|
157
|
-
setPointColor = 'var(--instrument-frame-tertiary-color)';
|
158
|
-
} else if (this.state === InstrumentState.off) {
|
159
|
-
setPointColor = 'var(--instrument-frame-tertiary-color)';
|
160
|
-
}
|
161
|
-
|
162
|
-
if (this.angleSetpoint === undefined) {
|
163
|
-
return nothing;
|
164
|
-
} else {
|
165
|
-
let path;
|
166
|
-
if (this.state === InstrumentState.inCommand) {
|
167
|
-
path =
|
168
|
-
'M23.5119 8C24.6981 6.35191 23.5696 4 21.5926 4L2.39959 4C0.422598 4 -0.705911 6.35191 0.480283 8L11.9961 24L23.5119 8Z';
|
169
|
-
} else {
|
170
|
-
path =
|
171
|
-
'M18.5836 8L5.4086 8L11.9961 17.1526L18.5836 8ZM23.5119 8C24.6981 6.35191 23.5696 4 21.5926 4L2.39959 4C0.422598 4 -0.705911 6.35191 0.480283 8L11.9961 24L23.5119 8Z';
|
172
|
-
}
|
173
|
-
return svg`
|
174
|
-
<defs>
|
175
|
-
<g id="setpoint">
|
176
|
-
<path fill-rule="evenodd" clip-rule="evenodd" transform="translate(-24 12) rotate(-90)" d=${path} vector-effect="non-scaling-stroke"/>
|
177
|
-
</g>
|
178
|
-
<mask id="setpointMask">
|
179
|
-
<rect x="-20" y="-20" width="50" height="50" fill="white" />
|
180
|
-
<use href="#setpoint" fill="black" />
|
181
|
-
</mask>
|
182
|
-
</defs>
|
183
|
-
<g transform="rotate(${this.angleSetpoint + 90}) translate(-168 0) ">
|
184
|
-
<use href="#setpoint" fill=${setPointColor} stroke-width="0" />
|
185
|
-
|
186
|
-
<use href="#setpoint" vector-effect="non-scaling-stroke" fill="none" stroke="var(--border-silhouette-color)" stroke-width="2" stroke-linejoin="round" mask="url(#setpointMask)" />
|
187
|
-
</g>
|
188
|
-
`;
|
189
|
-
}
|
190
|
-
}
|
191
|
-
|
192
|
-
static override styles = unsafeCSS(compentStyle);
|
193
|
-
}
|
194
|
-
|
195
|
-
declare global {
|
196
|
-
interface HTMLElementTagNameMap {
|
197
|
-
'obc-watch': ObcWatch;
|
198
|
-
}
|
199
|
-
}
|
1
|
+
import {
|
2
|
+
LitElement,
|
3
|
+
SVGTemplateResult,
|
4
|
+
html,
|
5
|
+
nothing,
|
6
|
+
svg,
|
7
|
+
unsafeCSS,
|
8
|
+
} from 'lit';
|
9
|
+
import {customElement, property} from 'lit/decorators.js';
|
10
|
+
import {circle} from '../../svghelpers';
|
11
|
+
import {roundedArch} from '../../svghelpers/roundedArch';
|
12
|
+
import {InstrumentState} from '../types';
|
13
|
+
import compentStyle from './watch.css?inline';
|
14
|
+
import {ResizeController} from '@lit-labs/observers/resize-controller.js';
|
15
|
+
import {AngleAdviceRaw, renderAdvice} from './advice';
|
16
|
+
import {Tickmark, TickmarkStyle, tickmark} from './tickmark';
|
17
|
+
import {renderLabels} from './label';
|
18
|
+
|
19
|
+
@customElement('obc-watch')
|
20
|
+
export class ObcWatch extends LitElement {
|
21
|
+
@property({type: String}) state: InstrumentState = InstrumentState.inCommand;
|
22
|
+
@property({type: Number}) angleSetpoint: number | undefined;
|
23
|
+
@property({type: Boolean}) atAngleSetpoint: boolean = false;
|
24
|
+
@property({type: Number}) padding = 24;
|
25
|
+
@property({type: Number}) cutAngleStart: number | null = null;
|
26
|
+
@property({type: Number}) cutAngleEnd: number | null = null;
|
27
|
+
@property({type: Boolean}) roundOutsideCut = false;
|
28
|
+
@property({type: Boolean}) roundInsideCut = false;
|
29
|
+
@property({type: Array, attribute: false}) tickmarks: Tickmark[] = [];
|
30
|
+
@property({type: Array, attribute: false}) advices: AngleAdviceRaw[] = [];
|
31
|
+
@property({type: Boolean}) crosshairEnabled: boolean = false;
|
32
|
+
@property({type: Boolean}) labelFrameEnabled: boolean = false;
|
33
|
+
|
34
|
+
// @ts-expect-error TS6133: The controller unsures that the render
|
35
|
+
// function is called on resize of the element
|
36
|
+
private _resizeController = new ResizeController(this, {});
|
37
|
+
|
38
|
+
private watchCircle(): SVGTemplateResult {
|
39
|
+
if (this.cutAngleStart === null || this.cutAngleEnd === null) {
|
40
|
+
return svg`
|
41
|
+
<defs>
|
42
|
+
<mask id="mask1" x="0" y="0" width="100%" height="100%">
|
43
|
+
<rect x="-200" y="-200" width="400" height="400" fill="white" />
|
44
|
+
<circle cx="0" cy="0" r="160" fill="black" />
|
45
|
+
</mask>
|
46
|
+
</defs>
|
47
|
+
${
|
48
|
+
this.state === InstrumentState.off
|
49
|
+
? null
|
50
|
+
: svg`
|
51
|
+
<circle
|
52
|
+
cx="0"
|
53
|
+
cy="0"
|
54
|
+
r="184"
|
55
|
+
fill="var(--instrument-frame-primary-color)"
|
56
|
+
mask="url(#mask1)"
|
57
|
+
/>`
|
58
|
+
}
|
59
|
+
${circle('innerRing', {
|
60
|
+
radius: 320 / 2,
|
61
|
+
strokeWidth: 1,
|
62
|
+
strokeColor: 'var(--instrument-frame-tertiary-color)',
|
63
|
+
strokePosition: 'center',
|
64
|
+
fillColor: 'none',
|
65
|
+
})}
|
66
|
+
${
|
67
|
+
this.state === InstrumentState.off
|
68
|
+
? null
|
69
|
+
: circle('outerRing', {
|
70
|
+
radius: 368 / 2,
|
71
|
+
strokeWidth: 1,
|
72
|
+
strokeColor: 'var(--instrument-frame-tertiary-color)',
|
73
|
+
strokePosition: 'center',
|
74
|
+
fillColor: 'none',
|
75
|
+
})
|
76
|
+
}
|
77
|
+
`;
|
78
|
+
} else {
|
79
|
+
const R = 184;
|
80
|
+
const r = 160;
|
81
|
+
const svgPath = roundedArch({
|
82
|
+
startAngle: this.cutAngleStart,
|
83
|
+
endAngle: this.cutAngleEnd,
|
84
|
+
R,
|
85
|
+
r,
|
86
|
+
roundOutsideCut: this.roundOutsideCut,
|
87
|
+
roundInsideCut: this.roundInsideCut,
|
88
|
+
});
|
89
|
+
return svg`
|
90
|
+
<path d=${svgPath} fill="var(--instrument-frame-primary-color)"
|
91
|
+
stroke="var(--instrument-frame-tertiary-color)"
|
92
|
+
vector-effect="non-scaling-stroke"/>
|
93
|
+
`;
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
private renderCrosshair(radius: number): SVGTemplateResult {
|
98
|
+
return svg`
|
99
|
+
<line
|
100
|
+
x1="-${radius}"
|
101
|
+
y1="0"
|
102
|
+
x2="${radius}"
|
103
|
+
y2="0"
|
104
|
+
stroke="var(--instrument-frame-tertiary-color)"
|
105
|
+
stroke-width="1"
|
106
|
+
vector-effect="non-scaling-stroke"
|
107
|
+
/>
|
108
|
+
<line
|
109
|
+
x1="0"
|
110
|
+
y1="-${radius}"
|
111
|
+
x2="0"
|
112
|
+
y2="${radius}"
|
113
|
+
stroke="var(--instrument-frame-tertiary-color)"
|
114
|
+
stroke-width="1"
|
115
|
+
vector-effect="non-scaling-stroke"
|
116
|
+
/>
|
117
|
+
`;
|
118
|
+
}
|
119
|
+
|
120
|
+
override render() {
|
121
|
+
const width = (176 + this.padding) * 2;
|
122
|
+
const viewBox = `-${width / 2} -${width / 2} ${width} ${width}`;
|
123
|
+
const angleSetpoint = this.renderSetpoint();
|
124
|
+
const scale = this.clientWidth / width;
|
125
|
+
const tickmarks = this.tickmarks.map((t) =>
|
126
|
+
tickmark(t.angle, t.type, TickmarkStyle.hinted, scale, t.text)
|
127
|
+
);
|
128
|
+
const advices = this.advices
|
129
|
+
? this.advices.map((a) => renderAdvice(a))
|
130
|
+
: nothing;
|
131
|
+
const labels = this.labelFrameEnabled ? renderLabels(scale) : nothing;
|
132
|
+
|
133
|
+
return html`
|
134
|
+
<svg
|
135
|
+
width="100%"
|
136
|
+
height="100%"
|
137
|
+
viewBox=${viewBox}
|
138
|
+
style="--scale: ${scale}"
|
139
|
+
>
|
140
|
+
${this.watchCircle()} ${tickmarks} ${advices} ${angleSetpoint} ${labels}
|
141
|
+
${this.crosshairEnabled ? this.renderCrosshair(320 / 2) : nothing}
|
142
|
+
</svg>
|
143
|
+
`;
|
144
|
+
}
|
145
|
+
|
146
|
+
private renderSetpoint(): SVGTemplateResult | typeof nothing {
|
147
|
+
let setPointColor = 'var(--instrument-enhanced-primary-color)';
|
148
|
+
if (this.atAngleSetpoint) {
|
149
|
+
setPointColor = 'var(--instrument-enhanced-secondary-color)';
|
150
|
+
}
|
151
|
+
if (this.state === InstrumentState.active) {
|
152
|
+
setPointColor = 'var(--instrument-regular-primary-color)';
|
153
|
+
if (this.atAngleSetpoint) {
|
154
|
+
setPointColor = 'var(--instrument-regular-secondary-color)';
|
155
|
+
}
|
156
|
+
} else if (this.state === InstrumentState.loading) {
|
157
|
+
setPointColor = 'var(--instrument-frame-tertiary-color)';
|
158
|
+
} else if (this.state === InstrumentState.off) {
|
159
|
+
setPointColor = 'var(--instrument-frame-tertiary-color)';
|
160
|
+
}
|
161
|
+
|
162
|
+
if (this.angleSetpoint === undefined) {
|
163
|
+
return nothing;
|
164
|
+
} else {
|
165
|
+
let path;
|
166
|
+
if (this.state === InstrumentState.inCommand) {
|
167
|
+
path =
|
168
|
+
'M23.5119 8C24.6981 6.35191 23.5696 4 21.5926 4L2.39959 4C0.422598 4 -0.705911 6.35191 0.480283 8L11.9961 24L23.5119 8Z';
|
169
|
+
} else {
|
170
|
+
path =
|
171
|
+
'M18.5836 8L5.4086 8L11.9961 17.1526L18.5836 8ZM23.5119 8C24.6981 6.35191 23.5696 4 21.5926 4L2.39959 4C0.422598 4 -0.705911 6.35191 0.480283 8L11.9961 24L23.5119 8Z';
|
172
|
+
}
|
173
|
+
return svg`
|
174
|
+
<defs>
|
175
|
+
<g id="setpoint">
|
176
|
+
<path fill-rule="evenodd" clip-rule="evenodd" transform="translate(-24 12) rotate(-90)" d=${path} vector-effect="non-scaling-stroke"/>
|
177
|
+
</g>
|
178
|
+
<mask id="setpointMask">
|
179
|
+
<rect x="-20" y="-20" width="50" height="50" fill="white" />
|
180
|
+
<use href="#setpoint" fill="black" />
|
181
|
+
</mask>
|
182
|
+
</defs>
|
183
|
+
<g transform="rotate(${this.angleSetpoint + 90}) translate(-168 0) ">
|
184
|
+
<use href="#setpoint" fill=${setPointColor} stroke-width="0" />
|
185
|
+
|
186
|
+
<use href="#setpoint" vector-effect="non-scaling-stroke" fill="none" stroke="var(--border-silhouette-color)" stroke-width="2" stroke-linejoin="round" mask="url(#setpointMask)" />
|
187
|
+
</g>
|
188
|
+
`;
|
189
|
+
}
|
190
|
+
}
|
191
|
+
|
192
|
+
static override styles = unsafeCSS(compentStyle);
|
193
|
+
}
|
194
|
+
|
195
|
+
declare global {
|
196
|
+
interface HTMLElementTagNameMap {
|
197
|
+
'obc-watch': ObcWatch;
|
198
|
+
}
|
199
|
+
}
|
@@ -1,62 +1,62 @@
|
|
1
|
-
import {SVGTemplateResult, svg} from 'lit';
|
2
|
-
|
3
|
-
export interface Tickmark {
|
4
|
-
angle: number;
|
5
|
-
type: TickmarkType;
|
6
|
-
text?: string;
|
7
|
-
}
|
8
|
-
|
9
|
-
export enum TickmarkType {
|
10
|
-
main = 'main',
|
11
|
-
primary = 'primary',
|
12
|
-
secondary = 'secondary',
|
13
|
-
tertiary = 'tertiary',
|
14
|
-
}
|
15
|
-
|
16
|
-
export enum TickmarkStyle {
|
17
|
-
hinted = 'hinted',
|
18
|
-
regular = 'regular',
|
19
|
-
enhanced = 'enhanced',
|
20
|
-
}
|
21
|
-
|
22
|
-
export function tickmarkColor(style: TickmarkStyle): string {
|
23
|
-
if (style === TickmarkStyle.hinted) {
|
24
|
-
return 'var(--instrument-frame-tertiary-color)';
|
25
|
-
} else if (style === TickmarkStyle.regular) {
|
26
|
-
return 'var(--instrument-tick-mark-secondary-color)';
|
27
|
-
} else {
|
28
|
-
return 'var(--instrument-tick-mark-primary-color)';
|
29
|
-
}
|
30
|
-
}
|
31
|
-
|
32
|
-
export function tickmark(
|
33
|
-
angle: number,
|
34
|
-
tickmarkSize: TickmarkType,
|
35
|
-
style: TickmarkStyle,
|
36
|
-
text?: string
|
37
|
-
): SVGTemplateResult | SVGTemplateResult[] {
|
38
|
-
const textHeight = -32;
|
39
|
-
let lineStartY: number = -35;
|
40
|
-
let lineEndY: number = -34;
|
41
|
-
|
42
|
-
if (tickmarkSize === TickmarkType.secondary) {
|
43
|
-
lineStartY = -24;
|
44
|
-
lineEndY = lineStartY + 8;
|
45
|
-
} else if (tickmarkSize === TickmarkType.main) {
|
46
|
-
lineEndY = lineStartY + 20;
|
47
|
-
} else if (tickmarkSize === TickmarkType.tertiary) {
|
48
|
-
throw new Error('Tertiary tickmarks are not supported');
|
49
|
-
}
|
50
|
-
|
51
|
-
const colorName = tickmarkColor(style);
|
52
|
-
const tick = svg`<line x1=${angle} y1=${lineStartY} x2=${angle} y2=${lineEndY} stroke=${colorName} stroke-width="1" vector-effect="non-scaling-stroke"/>`;
|
53
|
-
if (text) {
|
54
|
-
const textY = lineEndY + textHeight;
|
55
|
-
return [
|
56
|
-
tick,
|
57
|
-
svg`<text x=${angle} y=${textY} class="label" text-anchor="middle">${text}</text>`,
|
58
|
-
];
|
59
|
-
}
|
60
|
-
|
61
|
-
return tick;
|
62
|
-
}
|
1
|
+
import {SVGTemplateResult, svg} from 'lit';
|
2
|
+
|
3
|
+
export interface Tickmark {
|
4
|
+
angle: number;
|
5
|
+
type: TickmarkType;
|
6
|
+
text?: string;
|
7
|
+
}
|
8
|
+
|
9
|
+
export enum TickmarkType {
|
10
|
+
main = 'main',
|
11
|
+
primary = 'primary',
|
12
|
+
secondary = 'secondary',
|
13
|
+
tertiary = 'tertiary',
|
14
|
+
}
|
15
|
+
|
16
|
+
export enum TickmarkStyle {
|
17
|
+
hinted = 'hinted',
|
18
|
+
regular = 'regular',
|
19
|
+
enhanced = 'enhanced',
|
20
|
+
}
|
21
|
+
|
22
|
+
export function tickmarkColor(style: TickmarkStyle): string {
|
23
|
+
if (style === TickmarkStyle.hinted) {
|
24
|
+
return 'var(--instrument-frame-tertiary-color)';
|
25
|
+
} else if (style === TickmarkStyle.regular) {
|
26
|
+
return 'var(--instrument-tick-mark-secondary-color)';
|
27
|
+
} else {
|
28
|
+
return 'var(--instrument-tick-mark-primary-color)';
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
export function tickmark(
|
33
|
+
angle: number,
|
34
|
+
tickmarkSize: TickmarkType,
|
35
|
+
style: TickmarkStyle,
|
36
|
+
text?: string
|
37
|
+
): SVGTemplateResult | SVGTemplateResult[] {
|
38
|
+
const textHeight = -32;
|
39
|
+
let lineStartY: number = -35;
|
40
|
+
let lineEndY: number = -34;
|
41
|
+
|
42
|
+
if (tickmarkSize === TickmarkType.secondary) {
|
43
|
+
lineStartY = -24;
|
44
|
+
lineEndY = lineStartY + 8;
|
45
|
+
} else if (tickmarkSize === TickmarkType.main) {
|
46
|
+
lineEndY = lineStartY + 20;
|
47
|
+
} else if (tickmarkSize === TickmarkType.tertiary) {
|
48
|
+
throw new Error('Tertiary tickmarks are not supported');
|
49
|
+
}
|
50
|
+
|
51
|
+
const colorName = tickmarkColor(style);
|
52
|
+
const tick = svg`<line x1=${angle} y1=${lineStartY} x2=${angle} y2=${lineEndY} stroke=${colorName} stroke-width="1" vector-effect="non-scaling-stroke"/>`;
|
53
|
+
if (text) {
|
54
|
+
const textY = lineEndY + textHeight;
|
55
|
+
return [
|
56
|
+
tick,
|
57
|
+
svg`<text x=${angle} y=${textY} class="label" text-anchor="middle">${text}</text>`,
|
58
|
+
];
|
59
|
+
}
|
60
|
+
|
61
|
+
return tick;
|
62
|
+
}
|
@@ -1,19 +1,19 @@
|
|
1
|
-
* {
|
2
|
-
box-sizing: border-box;
|
3
|
-
}
|
4
|
-
|
5
|
-
.label {
|
6
|
-
@mixin font-body;
|
7
|
-
font-size: calc(16px / var(--scale));
|
8
|
-
fill: var(--element-neutral-color);
|
9
|
-
alignment-baseline: middle;
|
10
|
-
text-anchor: middle;
|
11
|
-
}
|
12
|
-
|
13
|
-
.label.left {
|
14
|
-
text-anchor: start;
|
15
|
-
}
|
16
|
-
|
17
|
-
.label.right {
|
18
|
-
text-anchor: end;
|
19
|
-
}
|
1
|
+
* {
|
2
|
+
box-sizing: border-box;
|
3
|
+
}
|
4
|
+
|
5
|
+
.label {
|
6
|
+
@mixin font-body;
|
7
|
+
font-size: calc(16px / var(--scale));
|
8
|
+
fill: var(--element-neutral-color);
|
9
|
+
alignment-baseline: middle;
|
10
|
+
text-anchor: middle;
|
11
|
+
}
|
12
|
+
|
13
|
+
.label.left {
|
14
|
+
text-anchor: start;
|
15
|
+
}
|
16
|
+
|
17
|
+
.label.right {
|
18
|
+
text-anchor: end;
|
19
|
+
}
|
@@ -1,17 +1,17 @@
|
|
1
|
-
import type {Meta, StoryObj} from '@storybook/web-components';
|
2
|
-
import {ObcWatchFlat} from './watch-flat';
|
3
|
-
import './watch-flat';
|
4
|
-
|
5
|
-
const meta: Meta<typeof ObcWatchFlat> = {
|
6
|
-
title: 'Building blocks/Watch flat',
|
7
|
-
tags: ['autodocs'],
|
8
|
-
component: 'obc-watch-flat',
|
9
|
-
args: {},
|
10
|
-
} satisfies Meta<ObcWatchFlat>;
|
11
|
-
|
12
|
-
export default meta;
|
13
|
-
type Story = StoryObj<ObcWatchFlat>;
|
14
|
-
|
15
|
-
export const Primary: Story = {
|
16
|
-
args: {},
|
17
|
-
};
|
1
|
+
import type {Meta, StoryObj} from '@storybook/web-components';
|
2
|
+
import {ObcWatchFlat} from './watch-flat';
|
3
|
+
import './watch-flat';
|
4
|
+
|
5
|
+
const meta: Meta<typeof ObcWatchFlat> = {
|
6
|
+
title: 'Building blocks/Watch flat',
|
7
|
+
tags: ['autodocs'],
|
8
|
+
component: 'obc-watch-flat',
|
9
|
+
args: {},
|
10
|
+
} satisfies Meta<ObcWatchFlat>;
|
11
|
+
|
12
|
+
export default meta;
|
13
|
+
type Story = StoryObj<ObcWatchFlat>;
|
14
|
+
|
15
|
+
export const Primary: Story = {
|
16
|
+
args: {},
|
17
|
+
};
|