UNPKG

advancedwind

Version:

A plugin that calculates true wind and ground wind optionally correcting for vessel motion, upwash, leeway and mast height.

145 lines (122 loc) 4 kB
const API_BASE_URL = "/plugins/advancedwind"; let previous = 0; let lastTime = new Date(); function getHeading(data) { let heading = 0; data.deltas.forEach(delta => { if (delta.id == "heading") { heading = delta.value * 180 / Math.PI; } }); return heading; } function getLargest(data) { let largest = 1; data.polars.forEach(polar => { largest = Math.max(largest, Math.abs(polar.x)); largest = Math.max(largest, Math.abs(polar.y)); }); return largest; } function drawBoat(canvas, heading) { const hull = document.createElementNS("http://www.w3.org/2000/svg", "path"); hull.setAttribute("d", "M -45 8 Q 15 20 30 0 Q 15 -20 -45 -8 z"); hull.setAttribute("fill", "none"); hull.setAttribute("stroke", "black"); hull.setAttribute("stroke-width", "1"); //hull.setAttribute("transform", `scale(${1 - Math.abs(Math.sin(att.pitch))}, ${1 - Math.abs(Math.sin(att.roll))})`); hull.setAttribute("id", "hull"); // const mast = document.createElementNS("http://www.w3.org/2000/svg", "line"); // mast.setAttribute("x1", 0); // mast.setAttribute("y1", 0); // mast.setAttribute("x2", offset.x); // mast.setAttribute("y2", offset.y); // mast.setAttribute("id", "mast"); const boat = document.createElementNS("http://www.w3.org/2000/svg", "g"); boat.setAttribute("transform", `rotate(${heading - 90})`); boat.appendChild(hull); // boat.appendChild(mast); canvas.appendChild(boat); } function drawVectors(canvas, data, heading, scale) { data.polars.forEach(polar => { const vector = document.createElementNS("http://www.w3.org/2000/svg", "line"); vector.setAttribute("x1", 0 ); vector.setAttribute("y1", 0 ); vector.setAttribute("x2", polar.x * scale ); vector.setAttribute("y2", polar.y * scale ); vector.setAttribute("id", polar.id); let dash; let s = scale * 5 / 1.94384 - 1; if (s > 50) { s = s / 5; dash = `1 1 ${s - 1} 1 ${s} 1 ${s} 1 ${s} 1 ${s - 1} 1 `; } else { dash = `1 1 ${s - 1} 1 ${s} 1 `; } vector.setAttribute("stroke-dasharray", dash); vector.setAttribute("stroke-dashoffset", `1`); if (polar.displayAttributes.plane == "Ground") vector.setAttribute("transform", `rotate(${-90})`); else vector.setAttribute("transform", `rotate(${heading - 90})`); canvas.appendChild(vector); }); } function handleError(error) { console.log('Error:', error.message); } async function getFromServer(endpoint) { try { const response = await fetch(`${API_BASE_URL}/${endpoint}`, { method: 'GET', headers: { 'Content-Type': 'application/json' } }); if (!response.ok) { if (response.status === 503) { handleError(new Error("Plugin is not running")); } else { handleError(new Error(`Error fetching data: ${response.status} ${response.statusText}`)); } return null; // Prevent parsing JSON on error } const data = await response.json(); return data; } catch (error) { handleError(error); return null; } } async function fetchVectorData() { const data = await getFromServer('getVectors'); if (data) { const canvas = document.getElementById("canvas"); canvas.innerHTML = ""; const heading = getHeading(data); const largest = getLargest(data); let time, deltaT; if (previous == 0) { previous = largest; lastTime = new Date(); } else { time = new Date(); deltaT = (time - lastTime)/1000; if (largest != previous) { if (largest > previous) { previous *= (1.005 ); } else { previous *= (0.9995 ); } } } const scale = 95 / previous; drawBoat(canvas, heading); drawVectors(canvas, data, heading, scale); } } setInterval(fetchVectorData, 1000);