hamradio.ki5bhv.com/hamdash.html

626 lines
19 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Refresh" content="300" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css?family=Victor Mono|Audiowide|Bebas Neue"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@100..900&display=swap"
rel="stylesheet"
/>
<title>VA3HDL Ham Radio Dashboard</title>
<!--
Hamdash
license: MIT
https://www.va3hdl.com/projects/hamdash
.d8888. d888888b db db db d88888b .d8888.
88' YP `~~88~~' `8b d8' 88 88' 88' YP
`8bo. 88 `8bd8' 88 88ooooo `8bo.
`Y8b. 88 88 88 88~~~~~ `Y8b.
db 8D 88 88 88booo. 88. db 8D
`8888Y' YP YP Y88888P Y88888P `8888Y'
-->
<style>
body {
background: black;
font-size: 100%;
}
.iframe-container {
background-color: black;
left: 0px;
border: 0px none;
height: 100%;
position: fixed;
width: 100%;
overflow: hidden;
bottom: 0px;
z-index: -2;
}
.img-zoom {
background-color: black;
left: 0px;
border: 0px none;
height: 100%;
position: fixed;
width: 100%;
overflow: hidden;
bottom: 0px;
z-index: -2;
}
/* Style for the fullscreen container (menu options) */
.full-screen {
height: 100%;
border: 0px none;
width: 100%;
margin-bottom: 0px;
margin-left: 0px;
-ms-zoom: 1;
-moz-transform: scale(1);
-moz-transform-origin: 0 0;
-o-transform: scale(1);
-o-transform-origin: 0 0;
-webkit-transform: scale(1);
-webkit-transform-origin: 0 0;
}
.default-frame {
margin-top: 0px;
margin-bottom: 0px;
margin-left: 0px;
left: 0px;
border: 0px none;
height: 100%;
position: fixed;
width: 100%;
overflow: hidden;
bottom: 0px;
}
.top-bar {
display: grid;
grid-template-columns: 2fr 1fr 2fr;
background-color: #333;
color: #fff;
padding: 1vh;
border: 0px none;
overflow: hidden;
position: relative;
width: auto;
}
.child {
position: relative;
display: grid;
border: 1px solid hsl(210deg 8% 50%);
border-radius: 5px;
background: hsl(210deg 15% 20%);
color: white;
padding: 0.5vh;
font-family: "Victor Mono", sans-serif;
font-size: 1.4vw;
}
/* Style for the dashboard container */
.dashboard {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 0px;
border: 0px none;
margin-bottom: 0px;
overflow: hidden;
position: relative;
width: 100%;
}
/* Style for the image container */
.image-container {
position: relative;
float: inline-start;
margin-right: 0px;
border: 0px;
width: 24.9vw;
height: 31vh;
overflow: hidden;
display: flex;
justify-content: center; /* Horizontal centering */
align-items: center; /* Vertical centering */
}
/* Style for the image */
.image-container img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* Style for the image titles */
.image-title {
position: absolute;
top: 6%;
left: 50%;
transform: translate(-50%, -50%);
color: white; /* font color */
background-color: black;
font-size: 1vw;
border-left: 0.25vw solid black;
border-right: 0.25vw solid black;
font-family: "Roboto Condensed", sans-serif;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
padding-top: 1px;
}
/* Style for the full screen image */
.image-large {
display: block;
position: relative;
margin-left: auto;
margin-right: auto;
max-width: 100%;
max-height: 100%;
width: auto;
height: 100%;
}
/* Style for the left menu options */
.menu {
display: grid;
grid-gap: 3px;
position: absolute;
width: auto;
height: auto;
margin-top: 70px;
left: 0px;
z-index: 2;
overflow: hidden;
}
/* Style for the right menu options */
.menuR {
display: grid;
grid-gap: 3px;
position: absolute;
width: auto;
height: auto;
margin-top: 70px;
right: 0px;
z-index: 2;
overflow: hidden;
}
#mySidenav a {
position: relative;
float: inline-start;
left: -120px;
transition: 0.3s;
padding-left: 15px;
padding-right: 15px;
padding-top: 12px;
padding-bottom: 8px;
width: 100px;
text-decoration: none;
font-family: "Bebas Neue", sans-serif;
font-size: 1.2vw;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
text-align: right;
color: white;
border-radius: 0 5px 5px 0;
box-shadow: 4px 4px 12px rgba(0, 0, 0, 0.5);
}
#mySidenav a:hover {
left: 0;
}
#mySidenavR a {
position: relative;
float: inline-start;
right: -120px;
transition: 0.3s;
padding-left: 15px;
padding-right: 15px;
padding-top: 12px;
padding-bottom: 8px;
width: 100px;
text-decoration: none;
font-family: "Bebas Neue", sans-serif;
font-size: 1.2vw;
font-optical-sizing: auto;
font-weight: 300;
font-style: normal;
text-align: left;
color: white;
border-radius: 5px 0px 0px 5px;
box-shadow: 4px 4px 12px rgba(0, 0, 0, 0.5);
}
#mySidenavR a:hover {
right: 0;
}
</style>
</head>
<!--
.d8888. .o88b. d8888b. d888888b d8888b. d888888b .d8888.
88' YP d8P Y8 88 `8D `88' 88 `8D `~~88~~' 88' YP
`8bo. 8P 88oobY' 88 88oodD' 88 `8bo.
`Y8b. 8b 88`8b 88 88~~~ 88 `Y8b.
db 8D Y8b d8 88 `88. .88. 88 88 db 8D
`8888Y' `Y88P' 88 YD Y888888P 88 YP `8888Y'
-->
<script src="wheelzoom.js"></script>
<script>
// CUT START
const topBarCenterText = `VA3HDL - FN04ga`;
// Menu items
// Structure is as follows HTML Color code, Option, target URL, scaling 1=Original Size, side (optional, nothing is Left, "R" is Right)
// The values are [color code, menu text, target link, scale factor, side],
// add new lines following the structure for extra menu options. The comma at the end is important!
const aURL = [
["add10d", "BACK", "#", "1"],
["add10d", "BACK", "#", "1", "R"],
["ff9100", "Refresh", "#", "1"],
["0dd1a7", "Help", "#", "1"],
["2196F3", "CLUBLOG", "https://clublog.org/livestream/VA3HDL", "1.7"],
[
"2196F3",
"CONTEST",
"https://www.contestcalendar.com/fivewkcal.html",
"1",
],
["2196F3", "DX CLUSTER", "https://dxcluster.ha8tks.hu/map/", "1"],
[
"2196F3",
"LIGHTNING",
"https://map.blitzortung.org/#3.87/36.5/-89.41",
"1",
"R",
],
["2196F3", "PISTAR", "http://pi-star.local/", "1.2"],
[
"2196F3",
"RADAR",
"https://weather.gc.ca/?layers=alert,radar&center=43.39961001,-78.53212031&zoom=6&alertTableFilterProv=ON",
"1",
"R"
],
["2196F3", "TIME.IS", "https://time.is/", "1", "R"],
[
"2196F3",
"WEATHER",
"https://openweathermap.org/weathermap?basemap=map&cities=true&layer=temperature&lat=44.0157&lon=-79.4591&zoom=5",
"1",
"R",
],
[
"2196F3",
"WINDS",
"https://earth.nullschool.net/#current/wind/surface/level/orthographic=-78.79,44.09,3000",
"1",
"R",
],
];
// Dashboard items
// Structure is Title, Image Source URL
// [Title, Image Source URL],
// the comma at the end is important!
// You can't add more items because there are only 12 placeholders on the dashboard
// but you can replace the titles and the images with anything you want.
const aIMG = [
["RADAR", "https://radar.weather.gov/ridge/standard/CONUS_loop.gif"],
[
"LOCAL RADAR",
"https://radar.weather.gov/ridge/standard/KNQA_loop.gif",
],
[
"NOAA D-RAP",
"https://services.swpc.noaa.gov/images/animations/d-rap/global/d-rap/latest.png",
],
[
"ISS & RS-44 POSITION",
"https://www.heavens-above.com/orbitdisplay.aspx?icon=iss&width=600&height=300&mode=M&satid=25544",
"https://www.heavens-above.com/orbitdisplay.aspx?icon=default&width=600&height=300&mode=M&satid=44909",
],
[
"SATELLITE CAN",
"https://cdn.star.nesdis.noaa.gov/GOES16/GLM/SECTOR/can/EXTENT3/GOES16-CAN-EXTENT3-1125x560.gif",
],
[
"SATELLITE CGL",
"https://cdn.star.nesdis.noaa.gov/GOES16/GLM/SECTOR/cgl/EXTENT3/GOES16-CGL-EXTENT3-600x600.gif",
],
[
"LIGHTNING",
"https://images.lightningmaps.org/blitzortung/america/index.php?animation=usa",
],
[
"LIGHTNING LOCAL",
"https://www.blitzortung.org/en/Images/image_b_ny.png",
],
["GREY LINE", "https://www.timeanddate.com/scripts/sunmap.php?iso=now"],
[
"SW BROADCAST",
"https://www.short-wave.info/php/transmitter-site-map.php?mobile=false&lat=52.67|-21.96|-15.53|-9.42|-17.76|-17.53|46.34|50.73|42.81|39.75|50.89|29.60|6.23|39.40|-15.53|43.51|46.34|-21.96|34.38|44.15|39.36|46.34|39.91|39.91|46.34|27.46|24.88|27.46|36.28|39.36|42.04|36.28|36.21|12.69|18.22|24.17|42.04|29.60|-15.73|-7.90|36.21|12.69|36.21|29.15|30.65|-21.96|33.50|-38.83|36.28|36.21|27.46&lon=9.75|27.60|28.00|160.05|168.36|146.05|-67.83|4.39|23.19|116.81|-113.85|55.79|-10.70|32.86|28.00|-79.63|-67.83|27.64|108.61|86.90|75.72|-67.83|-76.58|-76.58|-67.83|-80.93|102.50|-80.93|-86.10|75.72|12.32|-86.10|-86.89|-8.02|-63.02|54.25|12.32|55.79|46.45|-14.38|-86.89|-8.02|-86.89|47.77|-87.09|27.64|-86.47|176.42|-86.10|-86.89|-80.93&freq=3975|4930|4965|5020|5040|5055|5130|5780|5900|5985|6030|6040|6050|6050|6065|6070|6160|6195|7285|7295|7415|7490|9265|9265|9330|9395|9440|9455|9475|9600|9705|9930|9980|11640|11775|11810|11870|11880|11965|12095|12160|13630|13845|15540|15555|15580|15610|15720|15810|15825|17790&az=ND|20|ND|ND|ND|ND|245|ND|126|257|ND|313|ND|310|315|ND|245|350|317|270|308|245|242|242|245|355|283|285|50|308|206|180|90|111|320|90|210|211|295|27|85|111|90|310|5|350|85|35|40|46|160",
],
["10M PROPAGATION", "https://www.tvcomm.co.uk/g7izu/Autosave/NA_ES_AutoSave.JPG"],
["HF PROPAGATION",
"https://www.hamqsl.com/solar101vhf.php",
"https://www.hamqsl.com/solar100sc.php",
"https://www.hamqsl.com/solarpich.php"],
];
// CUT END
var largeShow = 0;
var aIdx = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
// This function shows the embedded websites
function MenuOpt(num) {
// Stop refreshes
window.stop();
clearTimeout(getSlideId);
//
document.getElementById("FullScreen").style.display = "block";
document.getElementById("iFrameContainer").style.zIndex = 1;
document.getElementById("FullScreen").src = aURL[num][2];
document.getElementById("FullScreen").style.transform =
"scale(" + aURL[num][3] + ")";
if (num == 0) {
// Start refreshes
window.location.reload(true);
getSlideId = setInterval(() => slide(), 5000);
//
wheelzoom(document.querySelectorAll("img"));
} else if (num == 1) {
// Start refreshes
window.location.reload(true);
getSlideId = setInterval(() => slide(), 5000);
//
} else if (num == 2) {
alert(`Double click on an image to expand to full screen.
Double click again to close full screen view.
Right click on an image to display the next one.
The content refreshes automatically every 5 minutes.
`);
}
}
// This function shows the larger images when double click to enlarge
function larger(event) {
var targetElement = event.target || event.srcElement;
if (largeShow == 1) {
// Start refreshes
window.location.reload(true);
getSlideId = setInterval(() => slide(), 5000);
//
largeShow = 0;
document.getElementById("imgZoom").style.display = "none";
document.getElementById("imgZoom").style.zIndex = -2;
} else {
// Stop refreshes
window.stop();
clearTimeout(getSlideId);
//
largeShow = 1;
document.getElementById("imgZoom").style.display = "block";
document.getElementById("imgZoom").style.zIndex = 3;
document.getElementById("ImageLarge").src =
targetElement.style.backgroundImage
.replace(/^url\(["']?/, "")
.replace(/["']?\)$/, "");
}
}
// Manually rotate images
function rotate(event) {
event.preventDefault();
var targetElement = event.target || event.srcElement;
i = +targetElement.id.match(/\d+/)[0];
if (aIMG[i].length > 2) {
++aIdx[i];
if (aIdx[i] > aIMG[i].length - 1) {
aIdx[i] = 1;
}
document.getElementById(targetElement.id).src = aIMG[i][aIdx[i]];
}
}
// Automatically rotate images
function slide() {
// get the locations with multiple images
aIMG.forEach(function (innerArray, i) {
if (aIMG[i].length > 2) {
++aIdx[i];
if (aIdx[i] > aIMG[i].length - 1) {
aIdx[i] = 1;
}
// console.log("Image" + i, " ", aIMG[i][aIdx[i]]);
img = document.getElementById("Image" + i);
img.src = aIMG[i][aIdx[i]];
// img.style.opacity = 0;
// img.style.transform = "translateX(-100%)";
}
});
// setTimeout(() => {
// aIMG.forEach(function (innerArray, i) {
// if (aIMG[i].length > 2) {
// console.log("Image" + i);
// img = document.getElementById("Image" + i);
// // img.style.opacity = 1;
// // img.style.transform = "translateX(0)";
// img.src = aIMG[i][aIdx[i]];
// }
// });
// }, 1000);
}
function start() {
// Get the parent div for Menu container
var parentDiv = document.getElementById("myMenu");
var parentDivR = document.getElementById("myMenuR");
// Append the new div to the parent div
aURL.forEach(function (innerArray, index) {
// Create a new div element
var newDiv = document.createElement("div");
newDiv.innerHTML = `<a href="#" style="background-color:#${innerArray[0]};" onclick="MenuOpt(${index})">${innerArray[1]}</a>`;
console.log(innerArray[4]);
if (innerArray[4] == "R") {
// Set some properties for the new div
newDiv.id = "mySidenavR";
newDiv.className = "sidenavR";
parentDivR.appendChild(newDiv);
} else {
// Set some properties for the new div
newDiv.id = "mySidenav";
newDiv.className = "sidenav";
parentDiv.appendChild(newDiv);
}
});
// Get the parent div for Dashboard container
var parentDiv = document.getElementById("dash");
// Append the new div to the parent div
aIMG.forEach(function (innerArray, index) {
// Create a new div element
var newDiv = document.createElement("div");
// Set some properties for the new div
newDiv.className = "image-container";
// Create a new img element
var newImg = document.createElement("img");
newImg.id = `Image${index}`;
newImg.src = innerArray[1];
newImg.oncontextmenu = rotate;
newImg.ondblclick = larger;
parentDiv.appendChild(newDiv);
newDiv.appendChild(newImg);
// Create a new div element for img title
var newTtl = document.createElement("div");
newTtl.className = "image-title";
newTtl.innerHTML = innerArray[0];
newDiv.appendChild(newTtl);
});
// assign wheelzoom functionality to all 12 images
wheelzoom(document.querySelectorAll("img"));
window.addEventListener("resize", function () {
"use strict";
window.location.reload();
});
getSlideId = setInterval(() => slide(), 30000);
}
// This function update the time on the top bar
function updateTopBar() {
const now = new Date();
const options = { weekday: "long", month: "long", day: "numeric" };
const localDate = now.toLocaleDateString("en-US", options);
const localTime = now.toLocaleTimeString("en-US", {
hour12: true,
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
timeZoneName: "short",
});
const utcDate = now.toISOString().slice(0, 10);
const utcTime = now.toISOString().slice(11, 19) + " UTC";
const topBarLeft = document.getElementById("topBarLeft");
topBarLeft.textContent = `${localDate} - ${localTime}`;
const topBarCenter = document.getElementById("topBarCenter");
topBarCenter.textContent = topBarCenterText;
const topBarRight = document.getElementById("topBarRight");
topBarRight.textContent = `${utcDate} ${utcTime}`;
}
// Update every second
setInterval(updateTopBar, 1000);
// Initial call to update
updateTopBar();
</script>
<!--
d8888b. .d88b. d8888b. db db
88 `8D .8P Y8. 88 `8D `8b d8'
88oooY' 88 88 88 88 `8bd8'
88~~~b. 88 88 88 88 88
88 8D `8b d8' 88 .8D 88
Y8888P' `Y88P' Y8888D' YP
-->
<body onload="start()">
<div id="iFrameContainer" class="iframe-container">
<iframe
class="full-screen"
id="FullScreen"
src=""
title="Zoom"
scrolling="no"
></iframe>
</div>
<div id="imgZoom" class="img-zoom">
<img
class="image-large"
id="ImageLarge"
alt="pic"
ondblclick="larger(event);"
/>
</div>
<div id="myMenu" class="menu">
<!-- Left Menu container -->
</div>
<div id="myMenuR" class="menuR">
<!-- Right Menu container -->
</div>
<div id="defaultFrame" class="default-frame">
<div class="top-bar">
<div
id="topBarLeft"
class="child"
style="text-align: left; padding-left: 7px; color: blanchedalmond"
></div>
<div
id="topBarCenter"
class="child"
style="text-align: center; color: rgb(0, 119, 255)"
></div>
<div
id="topBarRight"
class="child"
style="text-align: right; padding-right: 5px; color: aquamarine"
></div>
</div>
<div id="dash" class="dashboard">
<!-- Images container -->
</div>
</div>
</body>
</html>