@oicl/openbridge-webcomponents 0.0.15-dev-20240916083108 → 0.0.15-dev-20240916185711

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. package/__snapshots__/navigation-instruments-azimuth-thruster--in-command-at-setpoint-disable-auto-setpoint.png +0 -0
  2. package/__snapshots__/navigation-instruments-azimuth-thruster--in-command-at-setpoint.png +0 -0
  3. package/__snapshots__/navigation-instruments-azimuth-thruster--in-command.png +0 -0
  4. package/__snapshots__/navigation-instruments-azimuth-thruster--pod.png +0 -0
  5. package/__snapshots__/navigation-instruments-azimuth-thruster--single-direction-with-propeller.png +0 -0
  6. package/__snapshots__/navigation-instruments-azimuth-thruster--single-direction.png +0 -0
  7. package/__snapshots__/navigation-instruments-azimuth-thruster-labeled--large.png +0 -0
  8. package/__snapshots__/navigation-instruments-main-engine--active.png +0 -0
  9. package/__snapshots__/navigation-instruments-main-engine--in-command.png +0 -0
  10. package/__snapshots__/navigation-instruments-main-engine--off.png +0 -0
  11. package/__snapshots__/navigation-instruments-thruster--tunnel.png +0 -0
  12. package/custom-elements.json +570 -7
  13. package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.d.ts.map +1 -1
  14. package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.js +2 -1
  15. package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.js.map +1 -1
  16. package/dist/navigation-instruments/main-engine/main-engine.css.js +22 -0
  17. package/dist/navigation-instruments/main-engine/main-engine.css.js.map +1 -0
  18. package/dist/navigation-instruments/main-engine/main-engine.d.ts +29 -0
  19. package/dist/navigation-instruments/main-engine/main-engine.d.ts.map +1 -0
  20. package/dist/navigation-instruments/main-engine/main-engine.js +196 -0
  21. package/dist/navigation-instruments/main-engine/main-engine.js.map +1 -0
  22. package/dist/navigation-instruments/thruster/thruster.d.ts +54 -1
  23. package/dist/navigation-instruments/thruster/thruster.d.ts.map +1 -1
  24. package/dist/navigation-instruments/thruster/thruster.js +163 -99
  25. package/dist/navigation-instruments/thruster/thruster.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/navigation-instruments/azimuth-thruster/azimuth-thruster.ts +1 -0
  28. package/src/navigation-instruments/main-engine/main-engine.css +17 -0
  29. package/src/navigation-instruments/main-engine/main-engine.stories.ts +54 -0
  30. package/src/navigation-instruments/main-engine/main-engine.ts +160 -0
  31. package/src/navigation-instruments/thruster/thruster.stories.ts +1 -0
  32. package/src/navigation-instruments/thruster/thruster.ts +205 -113
  33. package/src/palettes/variables.css +1343 -1343
@@ -1,4 +1,4 @@
1
- import { css, LitElement, html, svg } from "lit";
1
+ import { css, LitElement, html, svg, nothing } from "lit";
2
2
  import { property, customElement } from "lit/decorators.js";
3
3
  import { InstrumentState } from "../types.js";
4
4
  import { renderAdvice } from "./advice.js";
@@ -49,7 +49,8 @@ let ObcThruster = class extends LitElement {
49
49
  singleDirection: this.singleDirection,
50
50
  singleDirectionHalfSize: this.singleDirectionHalfSize,
51
51
  topPropeller: this.topPropeller,
52
- bottomPropeller: this.bottomPropeller
52
+ bottomPropeller: this.bottomPropeller,
53
+ narrow: !this.tunnel
53
54
  })}
54
55
  </div>`;
55
56
  }
@@ -113,7 +114,7 @@ __decorateClass([
113
114
  ObcThruster = __decorateClass([
114
115
  customElement("obc-thruster")
115
116
  ], ObcThruster);
116
- function thrusterTop(height, value, colors, hideTicks) {
117
+ function thrusterTop(height, value, colors, options) {
117
118
  const container = svg`
118
119
  <path transform="translate(0 -2)" d="M -44 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 72 a 8 8 0 0 1 8 8 V 0 Z" fill=${colors.container} stroke="var(--instrument-frame-tertiary-color)" vector-effect="non-scaling-stroke"/>
119
120
  `;
@@ -121,7 +122,7 @@ function thrusterTop(height, value, colors, hideTicks) {
121
122
  const tickmarks = [];
122
123
  const nTicks = 2;
123
124
  const delta = height / nTicks;
124
- if (!hideTicks) {
125
+ if (!options.hideTicks) {
125
126
  for (let i = 1; i < nTicks; i++) {
126
127
  tickmarks.push(
127
128
  svg`<line x1="-24" x2="-44" y1=${-i * delta - 2} y2=${-i * delta - 2} stroke="var(--instrument-frame-tertiary-color)" stroke-width="1" vector-effect="non-scaling-stroke"/>`
@@ -134,49 +135,70 @@ function thrusterTop(height, value, colors, hideTicks) {
134
135
  const barHeight = height * value / 100;
135
136
  const barY = -2 - barHeight;
136
137
  const bar = svg`<rect width="40" height=${barHeight} x="-20" y=${barY} fill=${colors.box} stroke=${colors.box} vector-effect="non-scaling-stroke"/>`;
137
- return [container, track, tickmarks, bar];
138
+ if (options.hideContainer) {
139
+ return [track, tickmarks, bar];
140
+ } else {
141
+ return [container, track, tickmarks, bar];
142
+ }
138
143
  }
139
- function thrusterTopSingleSided(height, value, colors, hideTicks, advice, flipAdicePattern = false) {
140
- const container = svg`
144
+ function thrusterTopSingleSided(height, value, colors, options, advice) {
145
+ const container = options.narrow ? svg`
141
146
  <path transform="translate(0 -2)" d="M -32 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 48 a 8 8 0 0 1 8 8 V 0 Z" fill=${colors.container} stroke="var(--instrument-frame-tertiary-color)" vector-effect="non-scaling-stroke"/>
147
+ ` : svg`
148
+ <path transform="translate(0 -2)" d="M -40 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 56 a 8 8 0 0 1 8 8 V 0 Z" fill=${colors.container} stroke="var(--instrument-frame-tertiary-color)" vector-effect="non-scaling-stroke"/>
142
149
  `;
143
- const track = svg`
150
+ const track = options.narrow ? svg`
144
151
  <path transform="translate(0 -2)" d="M -32 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 32 V 0 Z" fill="var(--instrument-frame-secondary-color)" stroke="var(--instrument-frame-tertiary-color)" vector-effect="non-scaling-stroke"/>
152
+ ` : svg`
153
+ <path transform="translate(0 -2)" d="M -40 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 40 V 0 Z" fill="var(--instrument-frame-secondary-color)" stroke="var(--instrument-frame-tertiary-color)" vector-effect="non-scaling-stroke"/>
145
154
  `;
146
- const tickmarks = hideTicks ? [] : [singleSidedTickmark(height, 50, TickmarkStyle.hinted)];
155
+ const tickmarks = options.hideTicks ? [] : [singleSidedTickmark(height, 50, TickmarkStyle.hinted)];
147
156
  const barHeight = height * value / 100;
157
+ const barWidth = options.narrow ? 40 : 48;
158
+ const barX = options.narrow ? -32 : -40;
148
159
  const barY = -2 - barHeight;
149
- const maskId = flipAdicePattern ? "thrusterBarMask1" : "thrusterBarMask2";
150
- const bar = svg`
160
+ const maskId = options.flipAdicePattern ? "thrusterBarMask1" : "thrusterBarMask2";
161
+ const mask = options.hideContainer ? nothing : svg`
151
162
  <defs>
152
163
  <mask id=${maskId}>
153
- <path transform="translate(0 -2)" d="M -32 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 48 a 8 8 0 0 1 8 8 V 0 Z" fill="white" stroke="white" vector-effect="non-scaling-stroke"/>
154
- </defs>
155
- <rect mask="url(#${maskId})" width="40" height=${barHeight} x="-32" y=${barY} fill=${colors.box} stroke=${colors.box} vector-effect="non-scaling-stroke"/>`;
164
+ <path transform="translate(0 -2)" d="M ${barX} 0 v -${height - 8} a 8 8 0 0 1 8 -8 h ${barWidth} V 0 Z" fill="white" stroke="white" vector-effect="non-scaling-stroke"/>
165
+ </defs>`;
166
+ const maskAttr = options.hideContainer ? "" : `mask="url(#${maskId})"`;
167
+ const bar = svg`
168
+ ${mask}
169
+ <rect ${maskAttr} width=${barWidth} height=${barHeight} x=${barX} y=${barY} fill=${colors.box} stroke=${colors.box} vector-effect="non-scaling-stroke"/>`;
156
170
  const advicesSvg = advice.map(
157
- (a) => renderAdvice(height, a, flipAdicePattern)
171
+ (a) => renderAdvice(height, a, options.flipAdicePattern)
158
172
  );
159
- return [container, track, tickmarks, bar, advicesSvg];
173
+ const all = [tickmarks, bar, advicesSvg];
174
+ if (!options.hideContainer) {
175
+ all.splice(0, 0, [container, track]);
176
+ }
177
+ if (!options.narrow) {
178
+ return svg`<g transform="translate(4 0)">${all}</g>`;
179
+ } else {
180
+ return all;
181
+ }
160
182
  }
161
- function thrusterBottom(height, value, colors, hideTicks) {
183
+ function thrusterBottom(height, value, colors, options) {
162
184
  const container = svg`
163
185
  <g transform="rotate(180)">
164
- ${thrusterTop(height, value, colors, hideTicks)}
186
+ ${thrusterTop(height, value, colors, options)}
165
187
  </g>
166
188
  `;
167
189
  return container;
168
190
  }
169
- function thrusterBottomSingleSided(height, value, colors, hideTicks, advices) {
191
+ function thrusterBottomSingleSided(height, value, colors, options, advice) {
170
192
  const container = svg`
171
193
  <g transform="rotate(180) scale(-1,1)">
172
- ${thrusterTopSingleSided(height, value, colors, hideTicks, advices, true)}
194
+ ${thrusterTopSingleSided(height, value, colors, { hideTicks: options.hideTicks, flipAdicePattern: options.flipAdicePattern, hideContainer: options.hideContainer, narrow: options.narrow }, advice)}
173
195
  </g>
174
196
  `;
175
197
  return container;
176
198
  }
177
199
  function setpointSvg(height, value, setpointAtZero, colors, options) {
178
200
  const y = -(setpointAtZero ? 0 : Math.sign(value) * (height * Math.abs(value) / 100 + 2));
179
- const extra = options.singleSided ? -12 : 0;
201
+ const extra = (options.singleSided ? -12 : 0) + (options.narrow ? 0 : 4);
180
202
  let path;
181
203
  if (options.inCommand) {
182
204
  path = "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";
@@ -203,78 +225,38 @@ function setpointSvg(height, value, setpointAtZero, colors, options) {
203
225
  </g>
204
226
  `;
205
227
  }
206
- function thruster(thrust, setpoint, state, options) {
207
- if (!options.singleSided && options.advices.length > 0) {
208
- throw new Error("Double sided thruster does not support advice");
228
+ function atSetpoint(thrust, setpoint, options) {
229
+ if (options.touching) {
230
+ return false;
209
231
  }
210
232
  if (options.autoAtSetpoint && setpoint !== void 0) {
211
- options.atSetpoint = Math.abs(thrust - setpoint) < options.autoSetpointDeadband;
212
- }
213
- if (options.touching) {
214
- options.atSetpoint = false;
233
+ return Math.abs(thrust - setpoint) < options.autoSetpointDeadband;
215
234
  }
216
- let boxColor = "var(--instrument-enhanced-secondary-color)";
217
- let setPointColor = "var(--instrument-enhanced-primary-color)";
218
- let arrowColor = "var(--instrument-regular-secondary-color)";
219
- let containerBackgroundColor = "var(--instrument-frame-primary-color)";
220
- let zeroLineColor = "var(--instrument-enhanced-secondary-color)";
221
- let hideTicks = false;
222
- if (options.atSetpoint) {
223
- setPointColor = boxColor;
235
+ return options.atSetpoint;
236
+ }
237
+ function thruster(thrust, setpoint, state, options) {
238
+ if (options.tunnel) {
239
+ thrust = -thrust;
240
+ setpoint = setpoint === void 0 ? void 0 : -setpoint;
224
241
  }
225
- if (state === InstrumentState.active) {
226
- boxColor = "var(--instrument-regular-secondary-color)";
227
- zeroLineColor = "var(--instrument-regular-secondary-color)";
228
- setPointColor = "var(--instrument-regular-primary-color)";
229
- arrowColor = "var(--instrument-regular-secondary-color)";
230
- if (options.atSetpoint) {
231
- setPointColor = boxColor;
232
- }
233
- } else if (state === InstrumentState.loading) {
234
- boxColor = "transparent";
235
- setPointColor = "var(--instrument-frame-tertiary-color)";
236
- zeroLineColor = "var(--instrument-frame-tertiary-color)";
237
- arrowColor = "var(--instrument-regular-secondary-color)";
238
- thrust = 0;
239
- hideTicks = true;
240
- if (setpoint !== void 0) {
241
- setpoint = 0;
242
- }
243
- } else if (state === InstrumentState.off) {
244
- boxColor = "transparent";
245
- setPointColor = "var(--instrument-frame-tertiary-color)";
246
- arrowColor = "var(--instrument-frame-tertiary-color)";
247
- zeroLineColor = "var(--instrument-frame-tertiary-color)";
248
- thrust = 0;
249
- hideTicks = true;
250
- containerBackgroundColor = "transparent";
251
- if (setpoint !== void 0) {
252
- setpoint = 0;
253
- }
242
+ if (!options.singleSided && options.advices.length > 0) {
243
+ throw new Error("Double sided thruster does not support advice");
254
244
  }
255
- const centerLine = options.singleSided ? svg`<rect x="-32" y="-2" width="64" height="4" stroke-width="1" fill=${zeroLineColor} stroke=${zeroLineColor} vector-effect="non-scaling-stroke"/>` : svg`
256
- <rect x="-44" y="-2" width="88" height="4" stroke-width="1" fill=${zeroLineColor} stroke=${zeroLineColor} vector-effect="non-scaling-stroke"/>
245
+ options.atSetpoint = atSetpoint(thrust, setpoint, options);
246
+ const tc = thrusterColors(options, state);
247
+ let centerLine = svg`
248
+ <rect x="-44" y="-2" width="88" height="4" stroke-width="1" fill=${tc.zeroLineColor} stroke=${tc.zeroLineColor} vector-effect="non-scaling-stroke"/>
257
249
  `;
250
+ if (options.singleSided) {
251
+ const width = options.narrow ? 64 : 72;
252
+ const x = options.narrow ? -32 : -36;
253
+ centerLine = svg`<rect x=${x} y="-2" width=${width} height="4" stroke-width="1" fill=${tc.zeroLineColor} stroke=${tc.zeroLineColor} vector-effect="non-scaling-stroke"/>`;
254
+ }
258
255
  const setpointAtZero = Math.abs(setpoint || 0) < options.setpointAtZeroDeadband;
259
- const advices = options.advices.map((a) => {
260
- const triggered = thrust >= a.min && thrust <= a.max;
261
- let state2;
262
- if (triggered) {
263
- state2 = AdviceState.triggered;
264
- } else if (a.hinted) {
265
- state2 = AdviceState.hinted;
266
- } else {
267
- state2 = AdviceState.regular;
268
- }
269
- return {
270
- min: a.min,
271
- max: a.max,
272
- type: a.type,
273
- state: state2
274
- };
275
- });
276
- const topAdvices = advices.filter((a) => a.min >= 0);
277
- const bottomAdvices = advices.filter((a) => a.max <= 0).map((a) => ({ ...a, min: -a.max, max: -a.min }));
256
+ const { topAdvices, bottomAdvices } = convertThrustAdvices(
257
+ options.advices,
258
+ thrust
259
+ );
278
260
  const thrusterSvg = [];
279
261
  const baseheight = options.topPropeller === PropellerType.none ? 134 : 106;
280
262
  const height = options.singleDirection ? baseheight * 2 : baseheight;
@@ -283,8 +265,13 @@ function thruster(thrust, setpoint, state, options) {
283
265
  thrusterTopSingleSided(
284
266
  height,
285
267
  Math.max(thrust, 0),
286
- { box: boxColor, container: containerBackgroundColor },
287
- hideTicks,
268
+ { box: tc.boxColor, container: tc.containerBackgroundColor },
269
+ {
270
+ hideTicks: tc.hideTicks,
271
+ flipAdicePattern: false,
272
+ hideContainer: false,
273
+ narrow: options.narrow
274
+ },
288
275
  topAdvices
289
276
  )
290
277
  );
@@ -293,8 +280,13 @@ function thruster(thrust, setpoint, state, options) {
293
280
  thrusterBottomSingleSided(
294
281
  height,
295
282
  Math.max(-thrust, 0),
296
- { box: boxColor, container: containerBackgroundColor },
297
- hideTicks,
283
+ { box: tc.boxColor, container: tc.containerBackgroundColor },
284
+ {
285
+ hideTicks: tc.hideTicks,
286
+ flipAdicePattern: true,
287
+ hideContainer: false,
288
+ narrow: options.narrow
289
+ },
298
290
  bottomAdvices
299
291
  )
300
292
  );
@@ -305,8 +297,8 @@ function thruster(thrust, setpoint, state, options) {
305
297
  thrusterTop(
306
298
  height,
307
299
  Math.max(thrust, 0),
308
- { box: boxColor, container: containerBackgroundColor },
309
- hideTicks
300
+ { box: tc.boxColor, container: tc.containerBackgroundColor },
301
+ { hideTicks: tc.hideTicks, hideContainer: false }
310
302
  )
311
303
  );
312
304
  if (!options.singleDirection) {
@@ -314,8 +306,8 @@ function thruster(thrust, setpoint, state, options) {
314
306
  thrusterBottom(
315
307
  height,
316
308
  Math.max(-thrust, 0),
317
- { box: boxColor, container: containerBackgroundColor },
318
- hideTicks
309
+ { box: tc.boxColor, container: tc.containerBackgroundColor },
310
+ { hideTicks: tc.hideTicks, hideContainer: false }
319
311
  )
320
312
  );
321
313
  }
@@ -328,12 +320,13 @@ function thruster(thrust, setpoint, state, options) {
328
320
  setpoint,
329
321
  setpointAtZero,
330
322
  {
331
- fill: setPointColor,
323
+ fill: tc.setPointColor,
332
324
  stroke: "var(--border-silhouette-color)"
333
325
  },
334
326
  {
335
327
  inCommand: state === InstrumentState.inCommand,
336
- singleSided: options.singleSided
328
+ singleSided: options.singleSided,
329
+ narrow: options.narrow
337
330
  }
338
331
  )
339
332
  );
@@ -341,7 +334,7 @@ function thruster(thrust, setpoint, state, options) {
341
334
  if (options.tunnel) {
342
335
  return svg`
343
336
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="-160 -64 320 128" x="-160" y="-64">
344
- <g transform="rotate(90)">
337
+ <g transform="rotate(-90)">
345
338
  ${thrusterSvg}
346
339
  </g>
347
340
  </svg>`;
@@ -352,7 +345,7 @@ function thruster(thrust, setpoint, state, options) {
352
345
  viewBox = "-80 -300 160 320";
353
346
  y = -320;
354
347
  }
355
- const top = topPropeller(height, arrowColor, options.topPropeller);
348
+ const top = topPropeller(height, tc.arrowColor, options.topPropeller);
356
349
  const bottom = bottomPropeller(
357
350
  options.singleDirectionHalfSize ? 0.5 : height,
358
351
  options.bottomPropeller
@@ -366,8 +359,79 @@ function thruster(thrust, setpoint, state, options) {
366
359
  `;
367
360
  }
368
361
  }
362
+ function convertThrustAdvices(advices, thrust) {
363
+ const rawAdvices = advices.map((a) => {
364
+ const triggered = thrust >= a.min && thrust <= a.max;
365
+ let state;
366
+ if (triggered) {
367
+ state = AdviceState.triggered;
368
+ } else if (a.hinted) {
369
+ state = AdviceState.hinted;
370
+ } else {
371
+ state = AdviceState.regular;
372
+ }
373
+ return {
374
+ min: a.min,
375
+ max: a.max,
376
+ type: a.type,
377
+ state,
378
+ hinted: a.hinted
379
+ };
380
+ });
381
+ const topAdvices = rawAdvices.filter((a) => a.min >= 0);
382
+ const bottomAdvices = rawAdvices.filter((a) => a.max <= 0).map((a) => ({ ...a, min: -a.max, max: -a.min }));
383
+ return { topAdvices, bottomAdvices };
384
+ }
385
+ function thrusterColors(options, state) {
386
+ let boxColor = "var(--instrument-enhanced-secondary-color)";
387
+ let setPointColor = "var(--instrument-enhanced-primary-color)";
388
+ let arrowColor = "var(--instrument-regular-secondary-color)";
389
+ let containerBackgroundColor = "var(--instrument-frame-primary-color)";
390
+ let zeroLineColor = "var(--instrument-enhanced-secondary-color)";
391
+ let hideTicks = false;
392
+ if (options.atSetpoint) {
393
+ setPointColor = boxColor;
394
+ }
395
+ if (state === InstrumentState.active) {
396
+ boxColor = "var(--instrument-regular-secondary-color)";
397
+ zeroLineColor = "var(--instrument-regular-secondary-color)";
398
+ setPointColor = "var(--instrument-regular-primary-color)";
399
+ arrowColor = "var(--instrument-regular-secondary-color)";
400
+ if (options.atSetpoint) {
401
+ setPointColor = boxColor;
402
+ }
403
+ } else if (state === InstrumentState.loading) {
404
+ boxColor = "transparent";
405
+ setPointColor = "var(--instrument-frame-tertiary-color)";
406
+ zeroLineColor = "var(--instrument-frame-tertiary-color)";
407
+ arrowColor = "var(--instrument-regular-secondary-color)";
408
+ hideTicks = true;
409
+ } else if (state === InstrumentState.off) {
410
+ boxColor = "transparent";
411
+ setPointColor = "var(--instrument-frame-tertiary-color)";
412
+ arrowColor = "var(--instrument-frame-tertiary-color)";
413
+ zeroLineColor = "var(--instrument-frame-tertiary-color)";
414
+ hideTicks = true;
415
+ containerBackgroundColor = "transparent";
416
+ }
417
+ return {
418
+ zeroLineColor,
419
+ boxColor,
420
+ containerBackgroundColor,
421
+ hideTicks,
422
+ setPointColor,
423
+ arrowColor
424
+ };
425
+ }
369
426
  export {
370
427
  ObcThruster,
371
- thruster
428
+ atSetpoint,
429
+ convertThrustAdvices,
430
+ setpointSvg,
431
+ thruster,
432
+ thrusterBottom,
433
+ thrusterColors,
434
+ thrusterTop,
435
+ thrusterTopSingleSided
372
436
  };
373
437
  //# sourceMappingURL=thruster.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"thruster.js","sources":["../../../src/navigation-instruments/thruster/thruster.ts"],"sourcesContent":["import {LitElement, svg, html, css} from 'lit';\nimport {customElement, property} from 'lit/decorators.js';\nimport {InstrumentState} from '../types';\nimport {LinearAdvice, LinearAdviceRaw, renderAdvice} from './advice';\nimport {AdviceState} from '../watch/advice';\nimport {TickmarkStyle} from '../watch/tickmark';\nimport {singleSidedTickmark} from './tickmark';\nimport {PropellerType, bottomPropeller, topPropeller} from './propeller';\n\n/**\n * @element obc-thruster\n *\n * @prop {number} thrust - The thrust of the thruster in percent (-100 - +100)\n * @prop {boolean} touching - Highlight the thruster when the lever is being touched\n */\n@customElement('obc-thruster')\nexport class ObcThruster extends LitElement {\n @property({type: Number}) thrust: number = 0;\n @property({type: Number}) setpoint: number | undefined;\n @property({type: Boolean}) touching: boolean = false;\n @property({type: Boolean}) atSetpoint: boolean = false;\n @property({type: Boolean}) disableAutoAtSetpoint: boolean = false;\n @property({type: Number}) autoAtSetpointDeadband: number = 1;\n @property({type: Number}) setpointAtZeroDeadband: number = 0.5;\n @property({type: String}) state: InstrumentState = InstrumentState.inCommand;\n @property({type: Boolean}) tunnel: boolean = false;\n @property({type: Boolean}) singleSided: boolean = false;\n @property({type: Boolean}) singleDirection: boolean = false;\n @property({type: Boolean}) singleDirectionHalfSize: boolean = false;\n @property({type: Array}) advices: LinearAdvice[] = [];\n @property({type: String}) topPropeller: PropellerType = PropellerType.none;\n @property({type: String}) bottomPropeller: PropellerType = PropellerType.none;\n\n override render() {\n return html`<div class=\"container\">\n ${thruster(this.thrust, this.setpoint, this.state, {\n atSetpoint: this.atSetpoint,\n tunnel: this.tunnel,\n setpointAtZeroDeadband: this.setpointAtZeroDeadband,\n autoAtSetpoint: !this.disableAutoAtSetpoint,\n autoSetpointDeadband: this.autoAtSetpointDeadband,\n touching: this.touching,\n singleSided: this.singleSided,\n advices: this.advices,\n singleDirection: this.singleDirection,\n singleDirectionHalfSize: this.singleDirectionHalfSize,\n topPropeller: this.topPropeller,\n bottomPropeller: this.bottomPropeller,\n })}\n </div>`;\n }\n\n static override styles = css`\n .container {\n height: 100%;\n width: 100%;\n }\n\n .container > svg {\n height: 100%;\n width: 100%;\n }\n `;\n}\n\nfunction thrusterTop(\n height: number,\n value: number,\n colors: {box: string; container: string},\n hideTicks: boolean\n) {\n const container = svg`\n <path transform=\"translate(0 -2)\" d=\"M -44 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 72 a 8 8 0 0 1 8 8 V 0 Z\" fill=${colors.container} stroke=\"var(--instrument-frame-tertiary-color)\" vector-effect=\"non-scaling-stroke\"/>\n `;\n const track = svg`<rect width=\"40\" height=${height} x=\"-20\" y=${-2 - height} fill=\"var(--instrument-frame-secondary-color)\" stroke=\"var(--instrument-frame-tertiary-color)\" vector-effect=\"non-scaling-stroke\"/>`;\n\n const tickmarks = [];\n\n const nTicks = 2;\n const delta = height / nTicks;\n if (!hideTicks) {\n for (let i = 1; i < nTicks; i++) {\n tickmarks.push(\n svg`<line x1=\"-24\" x2=\"-44\" y1=${-i * delta - 2} y2=${\n -i * delta - 2\n } stroke=\"var(--instrument-frame-tertiary-color)\" stroke-width=\"1\" vector-effect=\"non-scaling-stroke\"/>`\n );\n tickmarks.push(\n svg`<line x1=\"24\" x2=\"44\" y1=${-i * delta - 2} y2=${\n -i * delta - 2\n } stroke=\"var(--instrument-frame-tertiary-color)\" stroke-width=\"1\" vector-effect=\"non-scaling-stroke\"/>`\n );\n }\n }\n\n const barHeight = (height * value) / 100;\n const barY = -2 - barHeight;\n const bar = svg`<rect width=\"40\" height=${barHeight} x=\"-20\" y=${barY} fill=${colors.box} stroke=${colors.box} vector-effect=\"non-scaling-stroke\"/>`;\n\n return [container, track, tickmarks, bar];\n}\n\nfunction thrusterTopSingleSided(\n height: number,\n value: number,\n colors: {box: string; container: string},\n hideTicks: boolean,\n advice: LinearAdviceRaw[],\n flipAdicePattern: boolean = false\n) {\n const container = svg`\n <path transform=\"translate(0 -2)\" d=\"M -32 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 48 a 8 8 0 0 1 8 8 V 0 Z\" fill=${colors.container} stroke=\"var(--instrument-frame-tertiary-color)\" vector-effect=\"non-scaling-stroke\"/>\n `;\n const track = svg`\n <path transform=\"translate(0 -2)\" d=\"M -32 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 32 V 0 Z\" fill=\"var(--instrument-frame-secondary-color)\" stroke=\"var(--instrument-frame-tertiary-color)\" vector-effect=\"non-scaling-stroke\"/>\n `;\n\n const tickmarks = hideTicks\n ? []\n : [singleSidedTickmark(height, 50, TickmarkStyle.hinted)];\n\n const barHeight = (height * value) / 100;\n const barY = -2 - barHeight;\n const maskId = flipAdicePattern ? 'thrusterBarMask1' : 'thrusterBarMask2';\n const bar = svg`\n <defs>\n <mask id=${maskId}>\n <path transform=\"translate(0 -2)\" d=\"M -32 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 48 a 8 8 0 0 1 8 8 V 0 Z\" fill=\"white\" stroke=\"white\" vector-effect=\"non-scaling-stroke\"/>\n </defs>\n <rect mask=\"url(#${maskId})\" width=\"40\" height=${barHeight} x=\"-32\" y=${barY} fill=${colors.box} stroke=${colors.box} vector-effect=\"non-scaling-stroke\"/>`;\n const advicesSvg = advice.map((a) =>\n renderAdvice(height, a, flipAdicePattern)\n );\n\n return [container, track, tickmarks, bar, advicesSvg];\n}\n\nfunction thrusterBottom(\n height: number,\n value: number,\n colors: {box: string; container: string},\n hideTicks: boolean\n) {\n const container = svg`\n <g transform=\"rotate(180)\">\n ${thrusterTop(height, value, colors, hideTicks)}\n </g>\n `;\n return container;\n}\n\nfunction thrusterBottomSingleSided(\n height: number,\n value: number,\n colors: {box: string; container: string},\n hideTicks: boolean,\n advices: LinearAdviceRaw[]\n) {\n const container = svg`\n <g transform=\"rotate(180) scale(-1,1)\">\n ${thrusterTopSingleSided(height, value, colors, hideTicks, advices, true)}\n </g>\n `;\n return container;\n}\n\nfunction setpointSvg(\n height: number,\n value: number,\n setpointAtZero: boolean,\n colors: {fill: string; stroke: string},\n options: {\n inCommand: boolean;\n singleSided: boolean;\n }\n) {\n const y = -(setpointAtZero\n ? 0\n : Math.sign(value) * ((height * Math.abs(value)) / 100 + 2));\n const extra = options.singleSided ? -12 : 0;\n let path;\n if (options.inCommand) {\n path =\n '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';\n } else {\n path =\n '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';\n }\n return svg`\n <defs>\n <g id=\"thrusterSetpoint\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" transform=\"translate(24 -12) rotate(90)\" d=${path} vector-effect=\"non-scaling-stroke\"/>\n </g>\n <mask id=\"thrusterSetpointMask\">\n <rect x=\"-20\" y=\"-20\" width=\"50\" height=\"50\" fill=\"white\" />\n <use href=\"#thrusterSetpoint\" fill=\"black\" />\n </mask>\n </defs>\n <g transform=\"translate(0 ${y})\">\n <use href=\"#thrusterSetpoint\" fill=${colors.fill} stroke=\"none\" transform=\"translate(${28 + extra} 0)\"/>\n <use href=\"#thrusterSetpoint\" mask=\"url(#thrusterSetpointMask)\" transform=\"translate(${28 + extra} 0)\" fill=\"none\" stroke=${colors.stroke} stroke-width=\"2\" stroke-linejoin=\"round\" vector-effect=\"non-scaling-stroke\"/>\n ${\n options.singleSided\n ? null\n : svg`\n <use href=\"#thrusterSetpoint\" transform=\"rotate(180) translate(28 0)\" fill=${colors.fill} stroke=\"none\"/>\n <use href=\"#thrusterSetpoint\" transform=\"rotate(180) translate(28 0)\" mask=\"url(#thrusterSetpointMask)\" fill=\"none\" stroke=${colors.stroke} stroke-width=\"2\" stroke-linejoin=\"round\" vector-effect=\"non-scaling-stroke\"/>\n `\n }\n </g>\n `;\n}\n\nexport function thruster(\n thrust: number,\n setpoint: number | undefined,\n state: InstrumentState,\n options: {\n atSetpoint: boolean;\n tunnel: boolean;\n singleSided: boolean;\n singleDirection: boolean;\n singleDirectionHalfSize: boolean;\n setpointAtZeroDeadband: number;\n autoAtSetpoint: boolean;\n autoSetpointDeadband: number;\n touching: boolean;\n advices: LinearAdvice[];\n topPropeller: PropellerType;\n bottomPropeller: PropellerType;\n }\n) {\n if (!options.singleSided && options.advices.length > 0) {\n throw new Error('Double sided thruster does not support advice');\n }\n\n if (options.autoAtSetpoint && setpoint !== undefined) {\n options.atSetpoint =\n Math.abs(thrust - setpoint) < options.autoSetpointDeadband;\n }\n\n if (options.touching) {\n options.atSetpoint = false;\n }\n\n let boxColor = 'var(--instrument-enhanced-secondary-color)';\n let setPointColor = 'var(--instrument-enhanced-primary-color)';\n let arrowColor = 'var(--instrument-regular-secondary-color)';\n let containerBackgroundColor = 'var(--instrument-frame-primary-color)';\n let zeroLineColor = 'var(--instrument-enhanced-secondary-color)';\n let hideTicks = false;\n if (options.atSetpoint) {\n setPointColor = boxColor;\n }\n if (state === InstrumentState.active) {\n boxColor = 'var(--instrument-regular-secondary-color)';\n zeroLineColor = 'var(--instrument-regular-secondary-color)';\n setPointColor = 'var(--instrument-regular-primary-color)';\n arrowColor = 'var(--instrument-regular-secondary-color)';\n if (options.atSetpoint) {\n setPointColor = boxColor;\n }\n } else if (state === InstrumentState.loading) {\n boxColor = 'transparent';\n setPointColor = 'var(--instrument-frame-tertiary-color)';\n zeroLineColor = 'var(--instrument-frame-tertiary-color)';\n arrowColor = 'var(--instrument-regular-secondary-color)';\n thrust = 0;\n hideTicks = true;\n if (setpoint !== undefined) {\n setpoint = 0;\n }\n } else if (state === InstrumentState.off) {\n boxColor = 'transparent';\n setPointColor = 'var(--instrument-frame-tertiary-color)';\n arrowColor = 'var(--instrument-frame-tertiary-color)';\n zeroLineColor = 'var(--instrument-frame-tertiary-color)';\n thrust = 0;\n hideTicks = true;\n containerBackgroundColor = 'transparent';\n if (setpoint !== undefined) {\n setpoint = 0;\n }\n }\n\n const centerLine = options.singleSided\n ? svg`<rect x=\"-32\" y=\"-2\" width=\"64\" height=\"4\" stroke-width=\"1\" fill=${zeroLineColor} stroke=${zeroLineColor} vector-effect=\"non-scaling-stroke\"/>`\n : svg`\n <rect x=\"-44\" y=\"-2\" width=\"88\" height=\"4\" stroke-width=\"1\" fill=${zeroLineColor} stroke=${zeroLineColor} vector-effect=\"non-scaling-stroke\"/>\n `;\n\n const setpointAtZero =\n Math.abs(setpoint || 0) < options.setpointAtZeroDeadband;\n\n const advices: LinearAdviceRaw[] = options.advices.map((a) => {\n const triggered = thrust >= a.min && thrust <= a.max;\n let state: AdviceState;\n if (triggered) {\n state = AdviceState.triggered;\n } else if (a.hinted) {\n state = AdviceState.hinted;\n } else {\n state = AdviceState.regular;\n }\n return {\n min: a.min,\n max: a.max,\n type: a.type,\n state,\n };\n });\n\n const topAdvices = advices.filter((a) => a.min >= 0);\n const bottomAdvices = advices\n .filter((a) => a.max <= 0)\n .map((a) => ({...a, min: -a.max, max: -a.min}));\n\n const thrusterSvg = [];\n const baseheight = options.topPropeller === PropellerType.none ? 134 : 106;\n const height = options.singleDirection ? baseheight * 2 : baseheight;\n if (options.singleSided) {\n thrusterSvg.push(\n thrusterTopSingleSided(\n height,\n Math.max(thrust, 0),\n {box: boxColor, container: containerBackgroundColor},\n hideTicks,\n topAdvices\n )\n );\n if (!(options.singleDirection || options.singleDirectionHalfSize)) {\n thrusterSvg.push(\n thrusterBottomSingleSided(\n height,\n Math.max(-thrust, 0),\n {box: boxColor, container: containerBackgroundColor},\n hideTicks,\n bottomAdvices\n )\n );\n }\n thrusterSvg.push(centerLine);\n } else {\n thrusterSvg.push(\n thrusterTop(\n height,\n Math.max(thrust, 0),\n {box: boxColor, container: containerBackgroundColor},\n hideTicks\n )\n );\n if (!options.singleDirection) {\n thrusterSvg.push(\n thrusterBottom(\n height,\n Math.max(-thrust, 0),\n {box: boxColor, container: containerBackgroundColor},\n hideTicks\n )\n );\n }\n thrusterSvg.push(centerLine);\n }\n if (setpoint !== undefined) {\n thrusterSvg.push(\n setpointSvg(\n height,\n setpoint,\n setpointAtZero,\n {\n fill: setPointColor,\n stroke: 'var(--border-silhouette-color)',\n },\n {\n inCommand: state === InstrumentState.inCommand,\n singleSided: options.singleSided,\n }\n )\n );\n }\n\n if (options.tunnel) {\n return svg`\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"-160 -64 320 128\" x=\"-160\" y=\"-64\">\n <g transform=\"rotate(90)\">\n ${thrusterSvg}\n </g>\n </svg>`;\n } else {\n let viewBox = '-80 -160 160 320';\n let y = -160;\n if (options.singleDirection) {\n viewBox = '-80 -300 160 320';\n y = -320;\n }\n const top = topPropeller(height, arrowColor, options.topPropeller);\n const bottom = bottomPropeller(\n options.singleDirectionHalfSize ? 0.5 : height,\n options.bottomPropeller\n );\n return svg`\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=${viewBox} x=\"-80\" y=${y} width=\"160\" height=\"320\">\n ${top}\n ${bottom}\n ${thrusterSvg}\n </svg>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-thruster': ObcThruster;\n }\n}\n"],"names":["state"],"mappings":"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"}
1
+ {"version":3,"file":"thruster.js","sources":["../../../src/navigation-instruments/thruster/thruster.ts"],"sourcesContent":["import {LitElement, svg, html, css, nothing} from 'lit';\nimport {customElement, property} from 'lit/decorators.js';\nimport {InstrumentState} from '../types';\nimport {LinearAdvice, LinearAdviceRaw, renderAdvice} from './advice';\nimport {AdviceState} from '../watch/advice';\nimport {TickmarkStyle} from '../watch/tickmark';\nimport {singleSidedTickmark} from './tickmark';\nimport {PropellerType, bottomPropeller, topPropeller} from './propeller';\n\n/**\n * @element obc-thruster\n *\n * @prop {number} thrust - The thrust of the thruster in percent (-100 - +100)\n * @prop {boolean} touching - Highlight the thruster when the lever is being touched\n */\n@customElement('obc-thruster')\nexport class ObcThruster extends LitElement {\n @property({type: Number}) thrust: number = 0;\n @property({type: Number}) setpoint: number | undefined;\n @property({type: Boolean}) touching: boolean = false;\n @property({type: Boolean}) atSetpoint: boolean = false;\n @property({type: Boolean}) disableAutoAtSetpoint: boolean = false;\n @property({type: Number}) autoAtSetpointDeadband: number = 1;\n @property({type: Number}) setpointAtZeroDeadband: number = 0.5;\n @property({type: String}) state: InstrumentState = InstrumentState.inCommand;\n @property({type: Boolean}) tunnel: boolean = false;\n @property({type: Boolean}) singleSided: boolean = false;\n @property({type: Boolean}) singleDirection: boolean = false;\n @property({type: Boolean}) singleDirectionHalfSize: boolean = false;\n @property({type: Array}) advices: LinearAdvice[] = [];\n @property({type: String}) topPropeller: PropellerType = PropellerType.none;\n @property({type: String}) bottomPropeller: PropellerType = PropellerType.none;\n\n override render() {\n return html`<div class=\"container\">\n ${thruster(this.thrust, this.setpoint, this.state, {\n atSetpoint: this.atSetpoint,\n tunnel: this.tunnel,\n setpointAtZeroDeadband: this.setpointAtZeroDeadband,\n autoAtSetpoint: !this.disableAutoAtSetpoint,\n autoSetpointDeadband: this.autoAtSetpointDeadband,\n touching: this.touching,\n singleSided: this.singleSided,\n advices: this.advices,\n singleDirection: this.singleDirection,\n singleDirectionHalfSize: this.singleDirectionHalfSize,\n topPropeller: this.topPropeller,\n bottomPropeller: this.bottomPropeller,\n narrow: !this.tunnel,\n })}\n </div>`;\n }\n\n static override styles = css`\n .container {\n height: 100%;\n width: 100%;\n }\n\n .container > svg {\n height: 100%;\n width: 100%;\n }\n `;\n}\n\nexport function thrusterTop(\n height: number,\n value: number,\n colors: {box: string; container: string},\n options: {hideTicks: boolean; hideContainer: boolean}\n) {\n const container = svg`\n <path transform=\"translate(0 -2)\" d=\"M -44 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 72 a 8 8 0 0 1 8 8 V 0 Z\" fill=${colors.container} stroke=\"var(--instrument-frame-tertiary-color)\" vector-effect=\"non-scaling-stroke\"/>\n `;\n const track = svg`<rect width=\"40\" height=${height} x=\"-20\" y=${-2 - height} fill=\"var(--instrument-frame-secondary-color)\" stroke=\"var(--instrument-frame-tertiary-color)\" vector-effect=\"non-scaling-stroke\"/>`;\n\n const tickmarks = [];\n\n const nTicks = 2;\n const delta = height / nTicks;\n if (!options.hideTicks) {\n for (let i = 1; i < nTicks; i++) {\n tickmarks.push(\n svg`<line x1=\"-24\" x2=\"-44\" y1=${-i * delta - 2} y2=${\n -i * delta - 2\n } stroke=\"var(--instrument-frame-tertiary-color)\" stroke-width=\"1\" vector-effect=\"non-scaling-stroke\"/>`\n );\n tickmarks.push(\n svg`<line x1=\"24\" x2=\"44\" y1=${-i * delta - 2} y2=${\n -i * delta - 2\n } stroke=\"var(--instrument-frame-tertiary-color)\" stroke-width=\"1\" vector-effect=\"non-scaling-stroke\"/>`\n );\n }\n }\n\n const barHeight = (height * value) / 100;\n const barY = -2 - barHeight;\n const bar = svg`<rect width=\"40\" height=${barHeight} x=\"-20\" y=${barY} fill=${colors.box} stroke=${colors.box} vector-effect=\"non-scaling-stroke\"/>`;\n if (options.hideContainer) {\n return [track, tickmarks, bar];\n } else {\n return [container, track, tickmarks, bar];\n }\n}\n\nexport function thrusterTopSingleSided(\n height: number,\n value: number,\n colors: {box: string; container: string},\n options: {\n hideTicks: boolean;\n flipAdicePattern: boolean;\n hideContainer: boolean;\n narrow: boolean;\n },\n advice: LinearAdviceRaw[]\n) {\n const container = options.narrow\n ? svg`\n <path transform=\"translate(0 -2)\" d=\"M -32 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 48 a 8 8 0 0 1 8 8 V 0 Z\" fill=${colors.container} stroke=\"var(--instrument-frame-tertiary-color)\" vector-effect=\"non-scaling-stroke\"/>\n `\n : svg`\n <path transform=\"translate(0 -2)\" d=\"M -40 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 56 a 8 8 0 0 1 8 8 V 0 Z\" fill=${colors.container} stroke=\"var(--instrument-frame-tertiary-color)\" vector-effect=\"non-scaling-stroke\"/>\n `;\n const track = options.narrow\n ? svg`\n <path transform=\"translate(0 -2)\" d=\"M -32 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 32 V 0 Z\" fill=\"var(--instrument-frame-secondary-color)\" stroke=\"var(--instrument-frame-tertiary-color)\" vector-effect=\"non-scaling-stroke\"/>\n `\n : svg`\n <path transform=\"translate(0 -2)\" d=\"M -40 0 v -${height - 8} a 8 8 0 0 1 8 -8 h 40 V 0 Z\" fill=\"var(--instrument-frame-secondary-color)\" stroke=\"var(--instrument-frame-tertiary-color)\" vector-effect=\"non-scaling-stroke\"/>\n `;\n\n const tickmarks = options.hideTicks\n ? []\n : [singleSidedTickmark(height, 50, TickmarkStyle.hinted)];\n\n const barHeight = (height * value) / 100;\n const barWidth = options.narrow ? 40 : 48;\n const barX = options.narrow ? -32 : -40;\n const barY = -2 - barHeight;\n const maskId = options.flipAdicePattern\n ? 'thrusterBarMask1'\n : 'thrusterBarMask2';\n // The mask is used to clip the bar to the container shape\n const mask = options.hideContainer\n ? nothing\n : svg`\n <defs>\n <mask id=${maskId}>\n <path transform=\"translate(0 -2)\" d=\"M ${barX} 0 v -${height - 8} a 8 8 0 0 1 8 -8 h ${barWidth} V 0 Z\" fill=\"white\" stroke=\"white\" vector-effect=\"non-scaling-stroke\"/>\n </defs>`;\n const maskAttr = options.hideContainer ? '' : `mask=\"url(#${maskId})\"`;\n const bar = svg`\n ${mask}\n <rect ${maskAttr} width=${barWidth} height=${barHeight} x=${barX} y=${barY} fill=${colors.box} stroke=${colors.box} vector-effect=\"non-scaling-stroke\"/>`;\n const advicesSvg = advice.map((a) =>\n renderAdvice(height, a, options.flipAdicePattern)\n );\n const all = [tickmarks, bar, advicesSvg];\n if (!options.hideContainer) {\n all.splice(0, 0, [container, track]);\n }\n if (!options.narrow) {\n return svg`<g transform=\"translate(4 0)\">${all}</g>`;\n } else {\n return all;\n }\n}\n\nexport function thrusterBottom(\n height: number,\n value: number,\n colors: {box: string; container: string},\n options: {hideTicks: boolean; hideContainer: boolean}\n) {\n const container = svg`\n <g transform=\"rotate(180)\">\n ${thrusterTop(height, value, colors, options)}\n </g>\n `;\n return container;\n}\n\nfunction thrusterBottomSingleSided(\n height: number,\n value: number,\n colors: {box: string; container: string},\n options: {\n hideTicks: boolean;\n flipAdicePattern: boolean;\n hideContainer: boolean;\n narrow: boolean;\n },\n advice: LinearAdviceRaw[]\n) {\n const container = svg`\n <g transform=\"rotate(180) scale(-1,1)\">\n ${thrusterTopSingleSided(height, value, colors, {hideTicks: options.hideTicks, flipAdicePattern: options.flipAdicePattern, hideContainer: options.hideContainer, narrow: options.narrow}, advice)}\n </g>\n `;\n return container;\n}\n\nexport function setpointSvg(\n height: number,\n value: number,\n setpointAtZero: boolean,\n colors: {fill: string; stroke: string},\n options: {\n inCommand: boolean;\n singleSided: boolean;\n narrow: boolean;\n }\n) {\n const y = -(setpointAtZero\n ? 0\n : Math.sign(value) * ((height * Math.abs(value)) / 100 + 2));\n const extra = (options.singleSided ? -12 : 0) + (options.narrow ? 0 : 4);\n let path;\n if (options.inCommand) {\n path =\n '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';\n } else {\n path =\n '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';\n }\n return svg`\n <defs>\n <g id=\"thrusterSetpoint\">\n <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" transform=\"translate(24 -12) rotate(90)\" d=${path} vector-effect=\"non-scaling-stroke\"/>\n </g>\n <mask id=\"thrusterSetpointMask\">\n <rect x=\"-20\" y=\"-20\" width=\"50\" height=\"50\" fill=\"white\" />\n <use href=\"#thrusterSetpoint\" fill=\"black\" />\n </mask>\n </defs>\n <g transform=\"translate(0 ${y})\">\n <use href=\"#thrusterSetpoint\" fill=${colors.fill} stroke=\"none\" transform=\"translate(${28 + extra} 0)\"/>\n <use href=\"#thrusterSetpoint\" mask=\"url(#thrusterSetpointMask)\" transform=\"translate(${28 + extra} 0)\" fill=\"none\" stroke=${colors.stroke} stroke-width=\"2\" stroke-linejoin=\"round\" vector-effect=\"non-scaling-stroke\"/>\n ${\n options.singleSided\n ? null\n : svg`\n <use href=\"#thrusterSetpoint\" transform=\"rotate(180) translate(28 0)\" fill=${colors.fill} stroke=\"none\"/>\n <use href=\"#thrusterSetpoint\" transform=\"rotate(180) translate(28 0)\" mask=\"url(#thrusterSetpointMask)\" fill=\"none\" stroke=${colors.stroke} stroke-width=\"2\" stroke-linejoin=\"round\" vector-effect=\"non-scaling-stroke\"/>\n `\n }\n </g>\n `;\n}\n\nexport function atSetpoint(\n thrust: number,\n setpoint: number | undefined,\n options: {\n autoAtSetpoint: boolean;\n autoSetpointDeadband: number;\n touching: boolean;\n atSetpoint: boolean;\n }\n): boolean {\n if (options.touching) {\n return false;\n }\n\n if (options.autoAtSetpoint && setpoint !== undefined) {\n return Math.abs(thrust - setpoint) < options.autoSetpointDeadband;\n }\n\n return options.atSetpoint;\n}\n\nexport function thruster(\n thrust: number,\n setpoint: number | undefined,\n state: InstrumentState,\n options: {\n atSetpoint: boolean;\n tunnel: boolean;\n singleSided: boolean;\n singleDirection: boolean;\n singleDirectionHalfSize: boolean;\n setpointAtZeroDeadband: number;\n autoAtSetpoint: boolean;\n autoSetpointDeadband: number;\n touching: boolean;\n advices: LinearAdvice[];\n topPropeller: PropellerType;\n bottomPropeller: PropellerType;\n narrow: boolean;\n }\n) {\n if (options.tunnel) {\n thrust = -thrust;\n setpoint = setpoint === undefined ? undefined : -setpoint;\n }\n\n if (!options.singleSided && options.advices.length > 0) {\n throw new Error('Double sided thruster does not support advice');\n }\n\n options.atSetpoint = atSetpoint(thrust, setpoint, options);\n\n const tc = thrusterColors(options, state);\n\n let centerLine = svg`\n <rect x=\"-44\" y=\"-2\" width=\"88\" height=\"4\" stroke-width=\"1\" fill=${tc.zeroLineColor} stroke=${tc.zeroLineColor} vector-effect=\"non-scaling-stroke\"/>\n `;\n if (options.singleSided) {\n const width = options.narrow ? 64 : 72;\n const x = options.narrow ? -32 : -36;\n centerLine = svg`<rect x=${x} y=\"-2\" width=${width} height=\"4\" stroke-width=\"1\" fill=${tc.zeroLineColor} stroke=${tc.zeroLineColor} vector-effect=\"non-scaling-stroke\"/>`;\n }\n\n const setpointAtZero =\n Math.abs(setpoint || 0) < options.setpointAtZeroDeadband;\n\n const {topAdvices, bottomAdvices} = convertThrustAdvices(\n options.advices,\n thrust\n );\n\n const thrusterSvg = [];\n const baseheight = options.topPropeller === PropellerType.none ? 134 : 106;\n const height = options.singleDirection ? baseheight * 2 : baseheight;\n if (options.singleSided) {\n thrusterSvg.push(\n thrusterTopSingleSided(\n height,\n Math.max(thrust, 0),\n {box: tc.boxColor, container: tc.containerBackgroundColor},\n {\n hideTicks: tc.hideTicks,\n flipAdicePattern: false,\n hideContainer: false,\n narrow: options.narrow,\n },\n topAdvices\n )\n );\n if (!(options.singleDirection || options.singleDirectionHalfSize)) {\n thrusterSvg.push(\n thrusterBottomSingleSided(\n height,\n Math.max(-thrust, 0),\n {box: tc.boxColor, container: tc.containerBackgroundColor},\n {\n hideTicks: tc.hideTicks,\n flipAdicePattern: true,\n hideContainer: false,\n narrow: options.narrow,\n },\n bottomAdvices\n )\n );\n }\n thrusterSvg.push(centerLine);\n } else {\n thrusterSvg.push(\n thrusterTop(\n height,\n Math.max(thrust, 0),\n {box: tc.boxColor, container: tc.containerBackgroundColor},\n {hideTicks: tc.hideTicks, hideContainer: false}\n )\n );\n if (!options.singleDirection) {\n thrusterSvg.push(\n thrusterBottom(\n height,\n Math.max(-thrust, 0),\n {box: tc.boxColor, container: tc.containerBackgroundColor},\n {hideTicks: tc.hideTicks, hideContainer: false}\n )\n );\n }\n thrusterSvg.push(centerLine);\n }\n if (setpoint !== undefined) {\n thrusterSvg.push(\n setpointSvg(\n height,\n setpoint,\n setpointAtZero,\n {\n fill: tc.setPointColor,\n stroke: 'var(--border-silhouette-color)',\n },\n {\n inCommand: state === InstrumentState.inCommand,\n singleSided: options.singleSided,\n narrow: options.narrow,\n }\n )\n );\n }\n\n if (options.tunnel) {\n return svg`\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"-160 -64 320 128\" x=\"-160\" y=\"-64\">\n <g transform=\"rotate(-90)\">\n ${thrusterSvg}\n </g>\n </svg>`;\n } else {\n let viewBox = '-80 -160 160 320';\n let y = -160;\n if (options.singleDirection) {\n viewBox = '-80 -300 160 320';\n y = -320;\n }\n const top = topPropeller(height, tc.arrowColor, options.topPropeller);\n const bottom = bottomPropeller(\n options.singleDirectionHalfSize ? 0.5 : height,\n options.bottomPropeller\n );\n return svg`\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=${viewBox} x=\"-80\" y=${y} width=\"160\" height=\"320\">\n ${top}\n ${bottom}\n ${thrusterSvg}\n </svg>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-thruster': ObcThruster;\n }\n}\n\nexport function convertThrustAdvices(\n advices: LinearAdvice[],\n thrust: number\n): {topAdvices: LinearAdviceRaw[]; bottomAdvices: LinearAdviceRaw[]} {\n const rawAdvices: LinearAdviceRaw[] = advices.map((a) => {\n const triggered = thrust >= a.min && thrust <= a.max;\n let state: AdviceState;\n if (triggered) {\n state = AdviceState.triggered;\n } else if (a.hinted) {\n state = AdviceState.hinted;\n } else {\n state = AdviceState.regular;\n }\n return {\n min: a.min,\n max: a.max,\n type: a.type,\n state,\n hinted: a.hinted,\n };\n });\n\n const topAdvices = rawAdvices.filter((a) => a.min >= 0);\n const bottomAdvices = rawAdvices\n .filter((a) => a.max <= 0)\n .map((a) => ({...a, min: -a.max, max: -a.min}));\n return {topAdvices, bottomAdvices};\n}\n\nexport function thrusterColors(\n options: {atSetpoint: boolean; touching: boolean},\n state: InstrumentState\n) {\n let boxColor = 'var(--instrument-enhanced-secondary-color)';\n let setPointColor = 'var(--instrument-enhanced-primary-color)';\n let arrowColor = 'var(--instrument-regular-secondary-color)';\n let containerBackgroundColor = 'var(--instrument-frame-primary-color)';\n let zeroLineColor = 'var(--instrument-enhanced-secondary-color)';\n let hideTicks = false;\n if (options.atSetpoint) {\n setPointColor = boxColor;\n }\n if (state === InstrumentState.active) {\n boxColor = 'var(--instrument-regular-secondary-color)';\n zeroLineColor = 'var(--instrument-regular-secondary-color)';\n setPointColor = 'var(--instrument-regular-primary-color)';\n arrowColor = 'var(--instrument-regular-secondary-color)';\n if (options.atSetpoint) {\n setPointColor = boxColor;\n }\n } else if (state === InstrumentState.loading) {\n boxColor = 'transparent';\n setPointColor = 'var(--instrument-frame-tertiary-color)';\n zeroLineColor = 'var(--instrument-frame-tertiary-color)';\n arrowColor = 'var(--instrument-regular-secondary-color)';\n hideTicks = true;\n } else if (state === InstrumentState.off) {\n boxColor = 'transparent';\n setPointColor = 'var(--instrument-frame-tertiary-color)';\n arrowColor = 'var(--instrument-frame-tertiary-color)';\n zeroLineColor = 'var(--instrument-frame-tertiary-color)';\n hideTicks = true;\n containerBackgroundColor = 'transparent';\n }\n return {\n zeroLineColor,\n boxColor,\n containerBackgroundColor,\n hideTicks,\n setPointColor,\n arrowColor,\n };\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oicl/openbridge-webcomponents",
3
- "version": "0.0.15-dev-20240916083108",
3
+ "version": "0.0.15-dev-20240916185711",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -130,6 +130,7 @@ export class ObcAzimuthThruster extends LitElement {
130
130
  advices: this.thrustAdvices,
131
131
  topPropeller: this.topPropeller,
132
132
  bottomPropeller: this.bottomPropeller,
133
+ narrow: true,
133
134
  })}
134
135
  </svg>
135
136
  </g>
@@ -0,0 +1,17 @@
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
+ }
@@ -0,0 +1,54 @@
1
+ import type {Meta, StoryObj} from '@storybook/web-components';
2
+ import {ObcMainEngine} from './main-engine';
3
+ import './main-engine';
4
+ import {beta6Decorator, widthDecorator} from '../../storybook-util';
5
+ import {InstrumentState} from '../types';
6
+
7
+ const meta: Meta<typeof ObcMainEngine> = {
8
+ title: 'Navigation instruments/Main Engine',
9
+ tags: ['autodocs'],
10
+ component: 'obc-main-engine',
11
+ args: {
12
+ width: 352,
13
+ thrust: 50,
14
+ thrustSetpoint: 30,
15
+ speed: 50,
16
+ speedSetpoint: 30,
17
+ },
18
+ argTypes: {
19
+ width: {control: {type: 'range', min: 32, max: 1028, step: 1}},
20
+ thrust: {control: {type: 'range', min: -100, max: 100, step: 1}},
21
+ thrustSetpoint: {control: {type: 'range', min: -100, max: 100, step: 1}},
22
+ speed: {control: {type: 'range', min: 0, max: 100, step: 1}},
23
+ speedSetpoint: {control: {type: 'range', min: 0, max: 100, step: 1}},
24
+ state: {
25
+ options: Object.values(InstrumentState),
26
+ },
27
+ },
28
+ decorators: [widthDecorator, beta6Decorator],
29
+ } satisfies Meta<ObcMainEngine>;
30
+
31
+ export default meta;
32
+ type Story = StoryObj<ObcMainEngine>;
33
+
34
+ export const InCommand: Story = {
35
+ args: {
36
+ state: InstrumentState.inCommand,
37
+ },
38
+ };
39
+
40
+ export const Active: Story = {
41
+ args: {
42
+ state: InstrumentState.active,
43
+ },
44
+ };
45
+
46
+ export const Off: Story = {
47
+ args: {
48
+ state: InstrumentState.off,
49
+ speed: 0,
50
+ thrust: 0,
51
+ speedSetpoint: 0,
52
+ thrustSetpoint: 0,
53
+ },
54
+ };