rtwx/nexrad-browser/www/index.js

174 lines
4.9 KiB
JavaScript
Raw Normal View History

2023-11-03 20:33:22 +00:00
import * as wasm from "./wasm/nexrad_browser.js";
await wasm.default();
wasm.__nxrd_browser_init();
console.log("[JS] setup event listeners");
2023-11-04 04:08:31 +00:00
console.log("[JS] initializing the renderer");
const DEFAULT_PREFERENCES = {
RR: 5,
RREN: true,
2023-11-04 05:23:23 +00:00
FCS: 20
2023-11-04 04:08:31 +00:00
};
let preferences = DEFAULT_PREFERENCES;
2023-11-04 05:23:23 +00:00
function get_font_size() { return `${preferences.FCS}px monospace`; }
2023-11-04 04:08:31 +00:00
const canvas = document.getElementById("canvas");
2023-11-04 05:23:23 +00:00
function setupCanvas(canvas) {
// Get the device pixel ratio, falling back to 1.
var dpr = window.devicePixelRatio || 1;
// Get the size of the canvas in CSS pixels.
var rect = canvas.getBoundingClientRect();
// Give the canvas pixel dimensions of their CSS
// size * the device pixel ratio.
canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;
var ctx = canvas.getContext('2d');
// Scale all drawing operations by the dpr, so you
// don't have to worry about the difference.
ctx.scale(dpr, dpr);
return ctx;
}
function rescaleCanvas(canvas, ctx) {
var dpr = window.devicePixelRatio || 1;
// Get the size of the canvas in CSS pixels.
var rect = canvas.getBoundingClientRect();
// Give the canvas pixel dimensions of their CSS
// size * the device pixel ratio.
canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;
// Scale all drawing operations by the dpr, so you
// don't have to worry about the difference.
ctx.scale(dpr, dpr);
}
const ctx = setupCanvas(canvas);
2023-11-04 04:08:31 +00:00
const FIFTY_MILES = 0.0916;
let current_lat = 38.8977;
let current_long = -77.036560;
function calcRenderbox() {
return [current_long - FIFTY_MILES, current_lat - FIFTY_MILES, current_long + FIFTY_MILES, current_lat + FIFTY_MILES];
}
function latlongXY(lat, long) {
let bbox = calcRenderbox();
let pixelWidth = canvas.width;
let pixelHeight = canvas.height;
let bboxWidth = bbox[2] - bbox[0];
let bboxHeight = bbox[3] - bbox[1];
let widthPct = ( long - bbox[0] ) / bboxWidth;
let heightPct = ( lat - bbox[1] ) / bboxHeight;
let x = Math.floor( pixelWidth * widthPct );
let y = Math.floor( pixelHeight * ( 1 - heightPct ) );
return { x, y };
}
let x0 = 0;
let y0 = 0;
let xfull = canvas.width;
let yfull = canvas.height;
function recalcBorderCoordinates() {
let xy = latlongXY(current_lat, current_long);
x0 = xy.x - canvas.width;
y0 = xy.y - canvas.height;
2023-11-04 05:23:23 +00:00
xfull = x0 + canvas.width;
yfull = y0 + canvas.width;
}
const red = "#ef0000";
const green = "#4af626";
const white = "#dedede";
let blinkyColor = "#dedede";
setInterval(() => {
if (blinkyColor === red) {
blinkyColor = white;
} else {
blinkyColor = red;
}
}, 350);
function zulu() {
let date = new Date();
return `${date.getUTCHours().toString().padStart(2, '0')}:${date.getUTCMinutes().toString().padStart(2, '0')}:${date.getUTCSeconds().toString().padStart(2, '0')}Z`;
}
let command_buf = "";
let buf_response_mode = false;
function exec() {
console.log("exec1!");
}
document.onkeyup = (e) => {
if (e.key.toUpperCase() === "ESCAPE") {
command_buf = "";
} else if (e.key.toUpperCase() === "ENTER") {
command_buf = "";
exec();
} else if (e.key.toUpperCase() === "BACKSPACE") {
command_buf = command_buf.slice(0, command_buf.length-1);
exec();
} else {
if (e.key.length !== 1) { return; }
if (buf_response_mode) {
buf_response_mode = false;
command_buf = "";
}
command_buf += e.key.toUpperCase();
}
2023-11-04 04:08:31 +00:00
}
setInterval(() => {
2023-11-04 05:23:23 +00:00
//document.getElementById("input-detection").focus();
rescaleCanvas(canvas, ctx);
2023-11-04 04:08:31 +00:00
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.resetTransform();
recalcBorderCoordinates();
let xy = latlongXY(current_lat, current_long);
ctx.translate(xy.x, xy.y);
// background (black, always)
ctx.fillStyle = "black";
2023-11-04 05:23:23 +00:00
ctx.fillRect(x0, y0, xfull * 2, yfull * 2);
ctx.font = get_font_size();
ctx.fillStyle = green;
ctx.fillText(`NEXRAD KLSX ${zulu()}`, x0 + 50, y0 + 50);
ctx.fillStyle = blinkyColor;
ctx.fillText("RADR INOP NO DATA LOADED", x0 + 50, y0 + 50 + preferences.FCS);
ctx.fillStyle = green;
ctx.textAlign = "right";
ctx.fillText("RADAR SITE", xfull - 75, y0 + 50);
ctx.fillText("KLSX VCP35 Clear Air Mode", xfull - 75, y0 + 50 + preferences.FCS);
ctx.fillText("MODE", xfull - 75, y0 + canvas.height / 3);
ctx.fillText(" REF VEL SW ", xfull - 75, y0 + canvas.height / 3 + preferences.FCS);
ctx.fillText(" ZDR PHI RHO ", xfull - 75, y0 + canvas.height / 3 + preferences.FCS * 2);
ctx.fillText(" CFP ", xfull - 75, y0 + canvas.height / 3 + preferences.FCS * 3);
ctx.fillStyle = white;
ctx.fillText(" >RADR INOP<", xfull - 75, y0 + canvas.height / 3 + preferences.FCS * 3);
ctx.fillStyle = green;
ctx.textAlign = "left";
ctx.fillText(command_buf, x0 + 50, y0 + canvas.height / 2);
}, 10);