174 lines
4.9 KiB
JavaScript
174 lines
4.9 KiB
JavaScript
import * as wasm from "./wasm/nexrad_browser.js";
|
|
await wasm.default();
|
|
wasm.__nxrd_browser_init();
|
|
|
|
console.log("[JS] setup event listeners");
|
|
|
|
console.log("[JS] initializing the renderer");
|
|
|
|
const DEFAULT_PREFERENCES = {
|
|
RR: 5,
|
|
RREN: true,
|
|
FCS: 20
|
|
};
|
|
let preferences = DEFAULT_PREFERENCES;
|
|
|
|
function get_font_size() { return `${preferences.FCS}px monospace`; }
|
|
|
|
const canvas = document.getElementById("canvas");
|
|
|
|
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);
|
|
|
|
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;
|
|
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();
|
|
}
|
|
}
|
|
|
|
setInterval(() => {
|
|
//document.getElementById("input-detection").focus();
|
|
rescaleCanvas(canvas, ctx);
|
|
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";
|
|
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);
|
|
|