aboutsummaryrefslogtreecommitdiff
path: root/app.mjs
diff options
context:
space:
mode:
authorDeterminant <[email protected]>2024-08-29 23:03:20 -0700
committerDeterminant <[email protected]>2024-08-29 23:03:20 -0700
commit2cf6eaf48ab85f4c0b6dbcef80cec5f0e7421576 (patch)
treeb994556f0662b4a13e8ab1d504e642166f8b664a /app.mjs
parent78546930272e9ee02cf887cb37d3bbac6b6dd56d (diff)
clean up
Diffstat (limited to 'app.mjs')
-rwxr-xr-xapp.mjs566
1 files changed, 277 insertions, 289 deletions
diff --git a/app.mjs b/app.mjs
index 488951d..acb4bf5 100755
--- a/app.mjs
+++ b/app.mjs
@@ -1,15 +1,12 @@
#!/usr/bin/env node
-import { registerFont } from "canvas";
-
+//import { registerFont } from "canvas";
//registerFont("./ocr-a-ext.ttf", { family: "OCR A Extended" });
import { discover, HAPTIC } from "loupedeck";
import { readFile } from "fs/promises";
import { parse } from "yaml";
import { XPlane } from "./xplane.mjs";
-import { isArray } from "util";
-import { platform } from "process";
const labelFont = "OCR A Extended";
const labelSize = 22;
@@ -68,7 +65,7 @@ const getKeyConf = (i) => {
const getTextStyles = (conf) => {
// conf must be non-null
- let font;
+ let font = [];
let color_bg = [];
let color_fg = [];
@@ -80,12 +77,11 @@ const getTextStyles = (conf) => {
color_fg = Array.isArray(conf.color_fg)
? conf.color_fg
: [conf.color_fg];
- font = [];
for (let i = 0; i < size.length; i++) {
font.push(`${size[i] ? size[i] : labelSize}px '${labelFont}'`);
}
} else {
- font = [`${labelSize}px '${labelFont}'`];
+ font.push(`${labelSize}px '${labelFont}'`);
}
return {
font,
@@ -94,6 +90,101 @@ const getTextStyles = (conf) => {
};
};
+const getLabels = (conf) => {
+ let text;
+ if (isObject(conf)) {
+ text = Array.isArray(conf.label) ? conf.label : [conf.label];
+ } else {
+ text = [conf.toString()];
+ }
+ return text;
+};
+
+const formatValues = (conf, values, n = 1) => {
+ const f = (fmt) => {
+ if (fmt) {
+ return Function("$d", `"use strict"; return(\`${fmt}\`);`)(values);
+ }
+ if (isNaN(values[0])) {
+ return "X";
+ }
+ return values[0].toFixed(0).toString();
+ };
+
+ let last;
+ let text = [];
+ const formatter = Array.isArray(conf.formatter)
+ ? conf.formatter
+ : [conf.formatter];
+ for (let i = 0; i < n; i++) {
+ let fmt = formatter[i] || last;
+ text.push(f(fmt));
+ last = fmt;
+ }
+ return text;
+};
+
+const formatColors = (color_name, conf, values, n = 1) => {
+ const f = (fmt) => {
+ if (fmt) {
+ return Function("$d", `"use strict"; return(\`${fmt}\`);`)(values);
+ }
+ return "#fff";
+ };
+
+ let last;
+ let color = [];
+ const formatter = Array.isArray(conf[color_name])
+ ? conf[color_name]
+ : [conf[color_name]];
+ for (let i = 0; i < n; i++) {
+ let fmt = formatter[i] || last;
+ color.push(f(fmt));
+ last = fmt;
+ }
+ return color;
+};
+
+const renderMultiLineText = (c, x0, y0, w, h, text, styles, conf) => {
+ const { font, color_fg } = styles;
+ c.save();
+ let sep = conf.sep;
+ if (sep == null) {
+ c.font = font[0];
+ const mx = c.measureText("x");
+ sep = mx.actualBoundingBoxAscent - mx.actualBoundingBoxDescent;
+ }
+ let ms = [];
+ let totalHeight = 0;
+ for (let i = 0; i < text.length; i++) {
+ c.font = font[i];
+ const m = c.measureText(text[i]);
+ ms.push(m);
+ totalHeight += m.actualBoundingBoxAscent - m.actualBoundingBoxDescent;
+ }
+ totalHeight += (text.length - 1) * sep;
+ let yBase = y0 + (h - totalHeight) / 2;
+ for (let i = 0; i < text.length; i++) {
+ const x =
+ x0 +
+ Math.max(
+ 0,
+ w -
+ (ms[i].actualBoundingBoxRight -
+ ms[i].actualBoundingBoxLeft),
+ ) /
+ 2;
+ const textHeight =
+ ms[i].actualBoundingBoxAscent - ms[i].actualBoundingBoxDescent;
+ const y = yBase + textHeight;
+ c.font = font[i];
+ c.fillStyle = color_fg[i] || "#fff";
+ c.fillText(text[i], x, y);
+ yBase += textHeight + sep;
+ }
+ c.restore();
+};
+
const drawKey = async (id, conf, pressed) => {
if (conf && conf.display != null) {
// not an input, but a display gauge
@@ -118,7 +209,11 @@ const drawKey = async (id, conf, pressed) => {
if (conf != null) {
renderMultiLineText(
c,
- getLabelText(conf),
+ 0,
+ 0,
+ w,
+ h,
+ getLabels(conf),
getTextStyles(conf),
conf,
);
@@ -157,7 +252,7 @@ const drawSideKnobs = async (side, confs, highlight) => {
);
if (Array.isArray(confs) && confs.length > i && confs[i] != null) {
const { font, color_bg, color_fg } = getTextStyles(confs[i]);
- const text = getLabelText(confs[i]);
+ const text = getLabels(confs[i]);
if (color_bg[0]) {
c.fillStyle = color_bg[0];
c.fillRect(
@@ -167,129 +262,116 @@ const drawSideKnobs = async (side, confs, highlight) => {
h - y_padding * 2 - 2,
);
}
- c.font = font[0];
- const {
- width,
- actualBoundingBoxAscent,
- actualBoundingBoxDescent,
- } = c.measureText(text[0]);
- const x_axis = (h - width) / 2;
- const y_axis =
- w / 2 +
- (actualBoundingBoxAscent - actualBoundingBoxDescent) / 2;
- c.rotate((90 * Math.PI) / 180);
- c.fillStyle = hl ? "black" : "white";
- c.fillText(text[0], x_axis + y_offset, -(w - y_axis));
+ c.translate(w, y_offset);
+ c.rotate(Math.PI / 2);
+ renderMultiLineText(
+ c,
+ 0,
+ 0,
+ h,
+ w,
+ text,
+ { font, color_bg, color_fg },
+ confs[i],
+ );
c.resetTransform();
}
}
});
};
-const renderMultiLineText = (c, text, styles, conf) => {
+const renderTextGauge = (c, display, values) => {
+ const bg = "black";
const w = c.canvas.width;
const h = c.canvas.height;
- const { font, color_fg } = styles;
+ // draw background
+ c.fillStyle = bg;
+ c.fillRect(0, 0, w, h);
- c.save();
- c.font = font[0];
- let ms = [];
- let text_h = 0;
- const mx = c.measureText("x");
- const sep = conf.sep
- ? conf.sep
- : mx.actualBoundingBoxAscent - mx.actualBoundingBoxDescent;
- for (let i = 0; i < text.length; i++) {
- c.font = font[i];
- const m = c.measureText(text[i]);
- ms.push(m);
- text_h += m.actualBoundingBoxAscent - m.actualBoundingBoxDescent;
- }
- text_h += (text.length - 1) * sep;
- let y0 = (h - text_h) / 2;
- for (let i = 0; i < text.length; i++) {
- const x =
- Math.max(
- 0,
- w -
- (ms[i].actualBoundingBoxRight -
- ms[i].actualBoundingBoxLeft),
- ) / 2;
- const hh =
- ms[i].actualBoundingBoxAscent - ms[i].actualBoundingBoxDescent;
- const y = y0 + hh;
- c.font = font[i];
- if (color_fg[i]) {
- c.fillStyle = color_fg[i];
- }
- c.fillText(text[i], x, y);
- y0 += hh + sep;
- }
- c.restore();
+ const text = formatValues(display, values, display.formatter.length);
+ // TODO: cache this
+ const styles = getTextStyles({
+ size: display.size,
+ color_fg: formatColors(
+ "color_fg",
+ display,
+ values,
+ display.formatter.length,
+ ),
+ });
+ renderMultiLineText(c, 0, 0, w, h, text, styles, {});
};
-const getLabelText = (conf) => {
- let text;
- if (isObject(conf)) {
- text = Array.isArray(conf.label) ? conf.label : [conf.label];
- } else {
- text = [conf.toString()];
- }
- return text;
-};
+const renderMeterGauge = (c, display, values) => {
+ const bg = "black";
+ const fg = "white";
+ const w = c.canvas.width;
+ const h = c.canvas.height;
-const formatValues = (conf, values, n = 1) => {
- const f = (fmt) => {
- if (fmt) {
- return Function("$d", `"use strict"; return(\`${fmt}\`);`)(values);
- }
- if (isNaN(values[0])) {
- return "X";
- }
- return values[0].toFixed(0).toString();
- };
+ const { min, max, stops } = display || {};
- let last;
- let text = [];
- const formatter = Array.isArray(conf.formatter)
- ? conf.formatter
- : [conf.formatter];
- for (let i = 0; i < n; i++) {
- let fmt = formatter[i] || last;
- text.push(f(fmt));
- last = fmt;
+ if (min == null) {
+ return;
}
- return text;
-};
-const formatColors = (color_name, conf, values, n = 1) => {
- const f = (fmt, v) => {
- if (fmt) {
- return Function("$d", `"use strict"; return(\`${fmt}\`);`)(values);
- }
- return "#fff";
- };
+ let reading = (values[0] - min) / (max - min);
+ if (isNaN(reading)) {
+ reading = min;
+ }
- let last;
- let color = [];
- const formatter = Array.isArray(conf[color_name])
- ? conf[color_name]
- : [conf[color_name]];
- for (let i = 0; i < n; i++) {
- let fmt = formatter[i] || last;
- color.push(f(fmt));
- last = fmt;
+ // draw background
+ c.fillStyle = bg;
+ c.fillRect(0, 0, w, h);
+ c.strokeStyle = fg;
+ c.lineWidth = 1;
+
+ const x0 = w / 2;
+ const y0 = h / 2 + 5;
+ const outer = 40;
+ const width = 5;
+ const inner = outer - width;
+
+ // draw each arc segments
+ for (let i = 0; i < stops.length; i++) {
+ const theta0 =
+ Math.PI * (1 + (stops[i].value_begin - min) / (max - min)) + 0.05;
+ const theta1 = Math.PI * (1 + (stops[i].value_end - min) / (max - min));
+
+ c.beginPath();
+ c.lineWidth = width;
+ c.strokeStyle = stops[i].color;
+ c.arc(x0, y0, outer - width / 2, theta0, theta1);
+ c.stroke();
+
+ c.beginPath();
+ c.lineWidth = 2;
+ const cos = Math.cos(theta1);
+ const sin = Math.sin(theta1);
+ c.moveTo(x0 + cos * (inner - 2), y0 + sin * (inner - 2));
+ c.lineTo(x0 + cos * (outer + 2), y0 + sin * (outer + 2));
+ c.stroke();
}
- return color;
+
+ // draw the needle
+ c.strokeStyle = fg;
+ c.lineWidth = 2;
+ c.beginPath();
+ c.moveTo(x0, y0);
+ const theta = Math.PI * (1 + reading);
+ c.lineTo(x0 + Math.cos(theta) * inner, y0 + Math.sin(theta) * inner);
+ c.stroke();
+
+ // show the value text
+ const text = formatValues(display, values);
+ const size = display.font ? display.font : labelSize;
+ c.font = `${size * 0.9}px '${labelFont}'`;
+ c.fillStyle = fg;
+ const m = c.measureText(text);
+ c.fillText(text, (w - m.width) / 2, h / 2 + 25);
};
const renderAttitudeIndicator = (c, display, values) => {
- const pitch = values[0];
- const roll = values[1];
- const src = display.src[values[2]];
- const cdi = src ? values[src.def] : null;
- const received = src ? values[src.received] : null;
const bg = "black";
const fg = "white";
const w = c.canvas.width;
@@ -298,8 +380,12 @@ const renderAttitudeIndicator = (c, display, values) => {
// draw background
c.fillStyle = bg;
c.fillRect(0, 0, w, h);
- c.fillStyle = fg;
- c.strokeStyle = fg;
+
+ const pitch = values[0];
+ const roll = values[1];
+ const src = display.src[values[2]];
+ const cdi = src ? values[src.def] : null;
+ const received = src ? values[src.received] : null;
const x0 = w / 2;
const y0 = h / 2;
@@ -309,14 +395,17 @@ const renderAttitudeIndicator = (c, display, values) => {
const shortSep = longSep / 2;
c.translate(x0, y0);
+ c.save();
c.rotate((-roll * Math.PI) / 180);
c.translate(0, (pitch / 10) * longSep);
+ // draw horizon
c.fillStyle = "#0077b6";
c.fillRect(-w, -2 * h, 2 * w, 4 * h);
c.fillStyle = "#99582a";
c.fillRect(-w, 0, 2 * w, 4 * h);
+ // draw pitch marks
c.lineWidth = 1;
c.strokeStyle = fg;
c.beginPath();
@@ -339,40 +428,41 @@ const renderAttitudeIndicator = (c, display, values) => {
}
}
c.stroke();
- c.resetTransform();
+ c.restore();
+ // draw center mark
c.lineWidth = 2;
c.strokeStyle = "yellow";
c.beginPath();
- c.moveTo(x0 - 30, y0);
- c.lineTo(x0 - 10, y0);
- c.lineTo(x0 - 10, y0 + 8);
+ c.moveTo(-30, 0);
+ c.lineTo(-10, 0);
+ c.lineTo(-10, 8);
- c.moveTo(x0 + 30, y0);
- c.lineTo(x0 + 10, y0);
- c.lineTo(x0 + 10, y0 + 8);
+ c.moveTo(30, 0);
+ c.lineTo(10, 0);
+ c.lineTo(10, 8);
c.stroke();
- // draw vertical deflection
+ // draw vertical deflection dots
const pi2 = 2 * Math.PI;
const vdef_x = w - 10;
- const vdef_r = 3;
+ const vdefR = 3;
c.strokeStyle = "white";
c.lineWidth = 1;
c.beginPath();
for (let i = -2; i <= 2; i++) {
if (i != 0) {
- const vdef_y = y0 + 13 * i;
- c.moveTo(vdef_x + vdef_r, vdef_y);
- c.arc(vdef_x, vdef_y, vdef_r, 0, pi2);
+ const vdef_y = 13 * i;
+ c.moveTo(vdef_x + vdefR, vdef_y);
+ c.arc(vdef_x, vdef_y, vdefR, 0, pi2);
}
}
c.stroke();
if (received == 0) {
// draw CDI diamond
- const cdi_y = y0 + 13 * cdi;
+ const cdi_y = 13 * cdi;
const cdi_h = 7;
const cdi_w = 4;
c.fillStyle = "#2dfe54";
@@ -387,97 +477,6 @@ const renderAttitudeIndicator = (c, display, values) => {
}
};
-const renderTextGauge = (c, display, values) => {
- const value = values[0];
- const bg = "black";
- const fg = "white";
- const w = c.canvas.width;
- const h = c.canvas.height;
-
- // draw background
- c.fillStyle = bg;
- c.fillRect(0, 0, w, h);
- c.fillStyle = fg;
- c.strokeStyle = fg;
- c.lineWidth = 1;
-
- const text = formatValues(display, values, display.formatter.length);
- // TODO: cache this
- const styles = getTextStyles({
- size: display.size,
- color_fg: formatColors(
- "color_fg",
- display,
- values,
- display.formatter.length,
- ),
- });
- renderMultiLineText(c, text, styles, {});
-};
-
-const renderMeterGauge = (c, display, values) => {
- const bg = "black";
- const fg = "white";
- const w = c.canvas.width;
- const h = c.canvas.height;
-
- const { min, max, stops } = display || {};
-
- if (min == null) {
- return;
- }
-
- let reading = (values[0] - min) / (max - min);
- if (isNaN(reading)) {
- reading = min;
- }
-
- const text = formatValues(display, values);
-
- // draw background
- c.fillStyle = bg;
- c.fillRect(0, 0, w, h);
- c.strokeStyle = fg;
- c.lineWidth = 1;
- const x0 = w / 2;
- const y0 = h / 2 + 5;
- const outer = 40;
- const width = 5;
- const inner = outer - width;
- for (let i = 0; i < stops.length; i++) {
- const theta0 =
- Math.PI * (1 + (stops[i].value_begin - min) / (max - min)) + 0.05;
- const theta1 = Math.PI * (1 + (stops[i].value_end - min) / (max - min));
-
- c.beginPath();
- c.lineWidth = width;
- c.strokeStyle = stops[i].color;
- c.arc(x0, y0, outer - width / 2, theta0, theta1);
- c.stroke();
-
- c.beginPath();
- c.lineWidth = 2;
- const cos = Math.cos(theta1);
- const sin = Math.sin(theta1);
- c.moveTo(x0 + cos * (inner - 2), y0 + sin * (inner - 2));
- c.lineTo(x0 + cos * (outer + 2), y0 + sin * (outer + 2));
- c.stroke();
- }
- c.strokeStyle = fg;
- c.lineWidth = 2;
- c.beginPath();
- c.moveTo(x0, y0);
- const theta = Math.PI * (1 + reading);
- c.lineTo(x0 + Math.cos(theta) * inner, y0 + Math.sin(theta) * inner);
- c.stroke();
-
- const size = display.font ? display.font : labelSize;
- c.font = `${size * 0.9}px '${labelFont}'`;
- c.fillStyle = fg;
- const m = c.measureText(text);
- c.fillText(text, (w - m.width) / 2, h / 2 + 25);
-};
-
const mechanicalStyleNumber = (value, lowDigitStep = 1) => {
const split = (x) => {
const int = Math.trunc(x);
@@ -522,7 +521,7 @@ const renderMechanicalDisplay = (
value,
padding = 20,
right = true,
- bigger_window_width = 2,
+ wideWinWidth = 2,
lowDigitStep = 1,
size = labelSize,
) => {
@@ -534,32 +533,24 @@ const renderMechanicalDisplay = (
const m = c.measureText("x");
const y0 =
h / 2 + (m.actualBoundingBoxAscent - m.actualBoundingBoxDescent) / 2;
- let digit_height =
- (m.actualBoundingBoxAscent - m.actualBoundingBoxDescent) * 2;
- let digit_width =
- (m.actualBoundingBoxRight - m.actualBoundingBoxLeft) * 1.2;
+ let digitH = (m.actualBoundingBoxAscent - m.actualBoundingBoxDescent) * 2;
+ let digitW = (m.actualBoundingBoxRight - m.actualBoundingBoxLeft) * 1.2;
const sign = right ? -1 : 1;
let x = (right ? w : 0) + sign * padding;
c.strokeStyle = bg;
- const narrow_window_y = y0 - digit_height * 0.95;
- const narrow_window_h = digit_height * 1.25;
- const bigger_window_x =
- x + sign * (bigger_window_width + (right ? -1 : 0)) * digit_width;
- const bigger_window_y = y0 - digit_height * 1.5;
- const bigger_window_w = bigger_window_width * digit_width;
- const bigger_window_h = digit_height * 2.25;
+ const narrowWinY = y0 - digitH * 0.95;
+ const narrowWinH = digitH * 1.25;
+ const wideWinX = x + sign * (wideWinWidth + (right ? -1 : 0)) * digitW;
+ const wideWinY = y0 - digitH * 1.5;
+ const wideWinW = wideWinWidth * digitW;
+ const wideWinH = digitH * 2.25;
c.fillStyle = bg;
- c.fillRect(0, narrow_window_y, w, narrow_window_h);
- c.fillRect(
- bigger_window_x,
- bigger_window_y,
- bigger_window_w,
- bigger_window_h,
- );
+ c.fillRect(0, narrowWinY, w, narrowWinH);
+ c.fillRect(wideWinX, wideWinY, wideWinW, wideWinH);
- c.rect(0, narrow_window_y, w, narrow_window_h);
- c.rect(bigger_window_x, bigger_window_y, bigger_window_w, bigger_window_h);
+ c.rect(0, narrowWinY, w, narrowWinH);
+ c.rect(wideWinX, wideWinY, wideWinW, wideWinH);
c.stroke();
c.clip();
c.strokeStyle = fg;
@@ -567,8 +558,8 @@ const renderMechanicalDisplay = (
if (isNaN(value)) {
c.beginPath();
- const y0 = narrow_window_y;
- const y1 = narrow_window_y + narrow_window_h;
+ const y0 = narrowWinY;
+ const y1 = narrowWinY + narrowWinH;
c.moveTo(0, y0);
c.lineTo(w, y1);
c.moveTo(0, y1);
@@ -585,7 +576,7 @@ const renderMechanicalDisplay = (
const formatLowDigits = (x) => x.toFixed(0).padStart(lowDigits, "0");
for (let i = 0; i < digits.length; i++) {
const p = right ? i : digits.length - i - 1;
- const y = y0 + scroll[p] * digit_height;
+ const y = y0 + scroll[p] * digitH;
let d, m1, m2, p1;
if (p == 0) {
d = digits[p] * lowDigitStep;
@@ -604,7 +595,7 @@ const renderMechanicalDisplay = (
m2 = formatLowDigits(m2);
p1 = formatLowDigits(p1);
p2 = formatLowDigits(p2);
- c.fillText(p2, x, y - digit_height * 2);
+ c.fillText(p2, x, y - digitH * 2);
} else {
d = digits[p];
m1 = d == 0 ? 9 : d - 1;
@@ -612,33 +603,27 @@ const renderMechanicalDisplay = (
p1 = d == 9 ? 0 : d + 1;
}
c.fillText(d, x, y);
- c.fillText(m1, x, y + digit_height);
- c.fillText(m2, x, y + digit_height * 2);
- c.fillText(p1, x, y - digit_height);
- x += sign * digit_width;
+ c.fillText(m1, x, y + digitH);
+ c.fillText(m2, x, y + digitH * 2);
+ c.fillText(p1, x, y - digitH);
+ x += sign * digitW;
}
c.restore();
};
const renderIAS = (c, display, values) => {
- const value = values[0];
const bg = "#555";
- const fg = "white";
const w = c.canvas.width;
const h = c.canvas.height;
// draw background
c.fillStyle = bg;
c.fillRect(0, 0, w, h);
- c.fillStyle = fg;
- c.strokeStyle = fg;
- c.lineWidth = 1;
renderMechanicalDisplay(c, w, h, values[0], 20, true, 1);
};
const renderAltimeter = (c, display, values) => {
- const value = values[0];
const bg = "#555";
const fg = "white";
const w = c.canvas.width;
@@ -647,23 +632,26 @@ const renderAltimeter = (c, display, values) => {
// draw background
c.fillStyle = bg;
c.fillRect(0, 0, w, h);
+
renderMechanicalDisplay(c, w, h, values[0], 5, false, 2, 20, 18);
+
+ // draw floating vsi window
const vsi = values[1];
- const vsi_bg_x = w / 2 + 4;
- c.fillRect(vsi_bg_x, 0, w - vsi_bg_x, h);
+ const vsiBgX = w / 2 + 4;
+ c.fillRect(vsiBgX, 0, w - vsiBgX, h);
c.fillStyle = "#000";
- const vsi_h = 20;
- const vsi_x = vsi_bg_x + 2;
- const vsi_y =
+ const vsiH = 20;
+ const vsiX = vsiBgX + 2;
+ const vsiY =
(1 -
(Math.min(Math.max(isNumber(vsi) ? vsi : 0, -2000), 2000) + 2000) /
4000) *
- (h - vsi_h);
- c.fillRect(vsi_x, vsi_y, w - vsi_x, vsi_h);
+ (h - vsiH);
+ c.fillRect(vsiX, vsiY, w - vsiX, vsiH);
c.fillStyle = fg;
if (isNumber(vsi)) {
c.font = `12px '${labelFont}'`;
- c.fillText(Math.trunc(vsi / 10) * 10, vsi_x + 2, vsi_y + vsi_h * 0.8);
+ c.fillText(Math.trunc(vsi / 10) * 10, vsiX + 2, vsiY + vsiH * 0.8);
}
const selected = values[2];
if (isNumber(selected)) {
@@ -682,24 +670,23 @@ const renderHSI = (c, display, values) => {
// draw background
c.fillStyle = bg;
c.fillRect(0, 0, w, h);
- c.fillStyle = fg;
- c.strokeStyle = fg;
- c.lineWidth = 1;
const x0 = w / 2;
const y0 = h / 2;
const r = w / 2 - 5;
const f1 = 0.8;
const f2 = 0.9;
- const cdi_r = 0.4 * r;
- const vdef_r = 3;
+ const cdiR = 0.4 * r;
+ const vdefR = 3;
const deg2Rad = (x) => (x / 180) * Math.PI;
+
const hdg = deg2Rad(values[0]);
- const hdg_bug = deg2Rad(values[1]);
+ const hdgB = deg2Rad(values[1]);
const src = display.navs[values[2]];
const crs = src ? deg2Rad(values[src.crs]) : null;
let def = src ? Math.min(Math.max(values[src.def], -3), 3) : null;
const received = src ? values[src.received] : null;
+
if (isNaN(def)) {
def = 0;
}
@@ -713,6 +700,8 @@ const renderHSI = (c, display, values) => {
c.translate(x0, y0);
c.rotate(-hdg);
+ c.strokeStyle = fg;
+ c.lineWidth = 1;
c.beginPath();
for (let i = 0; i < 36; i++) {
const { dx, dy } = polarXY(deg2Rad(i * 10), r);
@@ -721,25 +710,26 @@ const renderHSI = (c, display, values) => {
c.lineTo(dx * f, dy * f);
}
+ c.fillStyle = fg;
c.font = `16px '${labelFont}'`;
c.fillText("N", -5, -0.5 * r);
- if (isNumber(hdg_bug)) {
- const bug_w = 4;
- const bug_y1 = -(r - 3);
- const bug_y0 = -(r - 8);
+ if (isNumber(hdgB)) {
+ const bugW = 4;
+ const bugY1 = -(r - 3);
+ const bugY0 = -(r - 8);
c.stroke();
- c.rotate(hdg_bug);
+ c.rotate(hdgB);
c.fillStyle = "cyan";
c.beginPath();
- c.moveTo(0, bug_y1);
- c.lineTo(-bug_w, -(r + 1));
- c.lineTo(-bug_w, bug_y0);
- c.lineTo(bug_w, bug_y0);
- c.lineTo(bug_w, -(r + 1));
- c.lineTo(0, bug_y1);
+ c.moveTo(0, bugY1);
+ c.lineTo(-bugW, -(r + 1));
+ c.lineTo(-bugW, bugY0);
+ c.lineTo(bugW, bugY0);
+ c.lineTo(bugW, -(r + 1));
+ c.lineTo(0, bugY1);
c.fill();
- c.rotate(-hdg_bug);
+ c.rotate(-hdgB);
}
if (crs != null) {
@@ -748,8 +738,8 @@ const renderHSI = (c, display, values) => {
for (let i = -2; i <= 2; i++) {
if (i != 0) {
const x = 13 * i;
- c.moveTo(x + vdef_r, 0);
- c.arc(x, 0, vdef_r, 0, pi2);
+ c.moveTo(x + vdefR, 0);
+ c.arc(x, 0, vdefR, 0, pi2);
}
}
c.stroke();
@@ -759,13 +749,13 @@ const renderHSI = (c, display, values) => {
c.strokeStyle = src.color ? src.color : "magenta";
if (received != 0) {
- const cdi_x = 13 * def;
- c.moveTo(cdi_x, -(cdi_r - 1));
- c.lineTo(cdi_x, cdi_r - 1);
+ const cdiX = 13 * def;
+ c.moveTo(cdiX, -(cdiR - 1));
+ c.lineTo(cdiX, cdiR - 1);
}
c.moveTo(0, -r);
- c.lineTo(0, -(cdi_r + 1));
+ c.lineTo(0, -(cdiR + 1));
c.moveTo(0, -r);
// crs arrowhead
@@ -774,7 +764,7 @@ const renderHSI = (c, display, values) => {
c.lineTo(0, -r);
c.moveTo(0, r);
- c.lineTo(0, cdi_r + 1);
+ c.lineTo(0, cdiR + 1);
}
c.stroke();
};
@@ -788,16 +778,13 @@ const renderBarGauge = (c, display, values) => {
// draw background
c.fillStyle = bg;
c.fillRect(0, 0, w, h);
- c.fillStyle = fg;
- c.strokeStyle = fg;
const slotWidth = 10;
const slotHeight = 60;
const barWidth = slotWidth * 0.6;
- const barD = (slotWidth - barWidth) / 2;
const text = formatValues(display, values, 4);
- const label = getLabelText(display);
+ const label = getLabels(display);
// TODO: cache this
const { font, color_fg } = getTextStyles({
size: display.size,
@@ -808,6 +795,7 @@ const renderBarGauge = (c, display, values) => {
let y = -(w - (slotWidth + 10) * text.length) / 2;
let x = (h - slotHeight) / 2;
+ c.strokeStyle = fg;
for (let i = 0; i < text.length; i++) {
c.lineWidth = 1;
c.strokeRect(x, y - barWidth, slotHeight, barWidth);