Repository: VA3HDL/hamdashboard Branch: main Commit: c9f9b6c92e1e Files: 9 Total size: 120.0 KB Directory structure: gitextract_72fn_dc0/ ├── .gitignore ├── LICENSE ├── README.md ├── config.js ├── config.json ├── config_jsonp.js ├── hamdash.html ├── satellite.js └── wheelzoom.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .vscode *sync* ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2024 Pablo Sabbag, VA3HDL Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Ham Dashboard (hamdashboard) Live demo: [Hamdash Demo](https://va3hdl.github.io/hamdash/) This repository provides a simple, browser-based ham radio dashboard that displays images, maps, web pages, and feeds in a configurable grid. It is lightweight, easy to host, and suitable for use on a local computer, Raspberry Pi, or a static host such as GitHub Pages or Cloudflare Pages. Quick demo videos: - Original presentation: [YouTube - VA3HDL presentation](https://www.youtube.com/watch?v=sIdqMQTGNSc) - Spanish overview: [YouTube - VA3HDL en español](https://www.youtube.com/watch?v=IBMxELofKVA) ## User-submitted public dashboards These live dashboards were shared by members of the ham community: - [BCAT N4TDX](https://qsl.net/n/n5ng/BCAT/) — Steve N5NG (Brevard County ARES) - Steve's config files (as .txt): and - [FFX DEMS](https://kq4dne.github.io/WeatherDash/WeatherDash.html) — Sandy KQ4DNE - [FFX ARES](https://kq4dne.github.io/hamdash/hamdash.html) — Sandy KQ4DNE - [WA4MED](https://dashboard.wa4med.us/hamdash.html) — Matthew WA4MED - [PY3TX](https://dashboard.py3tx.com/) — South America - [VE7CAS](https://hamradio.smecher.bc.ca/) — Vancouver, BC - [G0IKV](https://g0ikv.qsy.to/) — Southport, England - [OK1SLM](https://www.qsl.net/ok1slm/) — Prague - [VK3VSN](https://www.vicscan.com/hamdash/) — Melbourne, Australia - [K6BCW](https://elihickox.com/radio/hamdashboard/hamdash.html) — San Francisco Bay Area - [KN6PTQ](https://kn6ptq.com/) — San Francisco Bay Area - [W2SZ](https://dashboard.w2sz.org/) — NE US - [N2YQT](https://dashboard.tourge.net/) — NE US - [KC2VWR](https://baef57ae.ham-desktop.pages.dev/) — NE US - [KD2YFY](https://dash.kd2yfy.net/) — NE US - [KD4VRD](https://hamdashboard-8fn.pages.dev/) — North Carolina - [KD5PQJ](https://kd5pqj.com/dash/index.html) — Texas - [N5GAH](http://n5gah.com/) — Texas - [KJ7YYI](https://kj7yyi.net/ham-dash/) — Arizona - [NQ0M](https://hamdash.nq0m.com/#) — Kansas - [W3RDW](https://dashboard.w3rdw.radio/) — Ohio - [W4QAL](https://w4qal.net/dashboard/index.html) — West Florida ## Quick start 1. Download the following files from this repository into a single folder: `hamdash.html`, `config.js`, and `wheelzoom.js`. 2. Open `hamdash.html` in your browser. 3. Use the right-side menu and select "Setup" to open the settings UI and configure your dashboard. 4. Alternatively, edit `config.js` in a text editor to set sources, menus, and layout. 5. Load configuration from the browser (Local Storage) or from `config.js`, then save your settings. **Notes** - For hosted (server) installations, store settings in `config.js` so the server serves the same configuration to all visitors. - For personal use or testing, Local Storage keeps changes specific to your browser session. - Now is possible to use a pure Json file format for the configuration load on hosted environments - For file:// access (non-hosted usage) a newer JsonP-style format is available for the configuration load ## Settings UI The settings UI provides buttons to manage configurations and backups: - Save Settings to Local Storage — Save current page settings in the browser. - Reset to Defaults — Restore sample settings for testing. - Backup Settings to JSON file — Download a JSON file with your settings. - Restore Settings from JSON file — Load settings from a JSON backup. - Import from `config.js` — Load settings defined in a `config.js` file (recommended for servers). - Export to `config.js` — Export current settings in `config.js` format for hosting. ## Public dashboards and safety The "Setup" UI cannot modify the server-side `config.js` file. When a visitor switches a public dashboard to Local Storage, the change affects only that visitor's browser. To hide the **Setup** option or **Load Cfg** option on public installations, add the following lines to your `config.js`: ``` const disableSetup = true; const disableLdCfg = true; ``` ## Video guides - [Configuration instructions — Jason KM4ACK](https://youtu.be/9ZZXg60tN-o) - [Raspberry Pi setup — Andreas M0FXB](https://www.youtube.com/watch?v=Km_vOCvCMFM) - [Live stream — Frank KG6NLW](https://www.youtube.com/watch?v=rJHCpNHDbC0&t=140s) - [Live stream — KM9G](https://www.youtube.com/watch?v=ohlHaSsf6B8=400s) - [Ham Dashboard on Inovato Quadra — Peter KJ5AJB](https://www.youtube.com/watch?v=u07Oz-YSrQY) - [French review — Jean-Benard F5SVP](https://www.youtube.com/watch?v=o9Dl9A5hqQI) - [Spanish instructions — Jose EA8EE](https://www.youtube.com/watch?v=3CnsfB3zNuM) ## Getting help Always check the [Q&A section](https://github.com/VA3HDL/hamdashboard/discussions/categories/q-a) for solutions to common issues. ## Docker Michael Stevens maintains a Docker image: [michaelsteven/hamdashboard](https://registry.hub.docker.com/r/michaelsteven/hamdashboard) ## How to use - Double-click an image to view full-screen; double-click again to close. - Right-click an image to cycle to the next image (if multiple images are assigned to a tile). - Tiles refresh independently (default refresh behavior: every 5 minutes for most sources). - Tiles with iFrames: double click to unlock the tile and interact with the content ## Pi-Star iFrame embedding (fix) If a remote site sets the `X-Frame-Options` header it may prevent embedding via iframes. On Pi-Star you can temporarily switch to read/write, edit the nginx security config, and restart nginx: ```bash rpi-rw sudo nano /etc/nginx/default.d/security.conf # comment out: add_header X-Frame-Options "SAMEORIGIN"; sudo systemctl restart nginx.service ``` This screenshot shows Pi-Star settings: ## iFrame tips If the source server forbids embedding and you cannot change its headers, options are limited. A local proxy that strips the header can work but adds complexity. Use the online tool to test a URL before adding it to a tile: [iFrame Tester online](https://iframetester.com/) ## Changelog highlights (most recent) See the chronological entries below for full details. Notable recent changes: - 2026.01.30 — Fixed RSS feeds not loading on some hosting situations due to a CORS issue. - 2026.01.24 — Added 10 features: 1. JSON & JSONP Configuration Support (example .json and JsonP .js files added to the repo) 2. Dynamic Date Placeholders 3. Rotating Tile **Titles** - Requested by multiple users, see example in all 3 config files 4. Smart Mixed-Media Interactivity (for tiles mixing images, videos, iFrames) 5. Enhanced Full-Screen Navigation 6. Setup UI Improvements 7. Enhanced Breadcrumb Navigation to provide always a return path to previous configs 8. PREVIOUS Menu Button 9. Enhanced Config File Detection to support various file formats 10. File Picker Integration to load different dashboards on the fly - 2026.01.22 — Added directives to load images and iframes with colors inverted. Full details on the release notes. - 2026.01.17 — Ability to load any config files via the menu. - 2025.11.12 — Switch between multiple config files (e.g., `satellite.js`) via the menu. - 2025.04.02 — RSS feed refresh times configurable; feed ticker added. - 2025.03.29 — Scrolling RSS ticker and clickable feed items. - 2025.01.24 — Settings merged into `hamdash.html`; realtime variable changes enabled. ## Upgrade notes - For simpler sintax you can now use Json or JsonP files for config files - Read the specific upgrade notes in the changelog below before replacing `config.js` - To use multiple config files, add a menu entry in `config.js` such as: ``` var aURL = [ ["f3de21ff", "SATS", "satellite.js"], ["f3de21ff", "WX", "weather.js", "1", "R"] ]; ``` **Rotating Tile Titles Usage:** Pass an array as the first element of a tile configuration. ```javascript // Example in config.js [ ["Radar CONUS", "Radar Local"], "https://radar.com/map1.gif", "https://radar.com/map2.gif" ] ``` ## Example images Grid examples ## More notes and history The repository includes a detailed changelog documenting fixes, features, and upgrade instructions dating back through 2024. Please review the changelog entries below before performing upgrades. [Releases & Change logs](https://github.com/VA3HDL/hamdashboard/releases) ## Host with Cloudflare Pages (free) Tutorial contributed by Robert W3RDW: [How to host your dashboard with Cloudflare Pages, free](https://w3rdw.radio/posts/hamdashboard/) ## Sample dashboards submitted by users ![VA3HDL Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/dashboard_sample.png?raw=true) ![N4NBC Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/N4NBC-sample.jpg?raw=true) ![KM4ACK Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/KM4ACK-sample.png?raw=true) ![TI3GB Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/TI3GB-sample.png?raw=true) ![N5NG Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/N5NG-sample.png?raw=true) ![VK3MLT Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/VK3MLT-sample.png?raw=true) ![VK5TUX Sample Dashboard](examples/VK5TUX_Sample_VA3HDL_Ham_Radio_Dashboard.png?raw=true) ![VK5TUX Sample Dashboard Sources](examples/VK5TUX_Sample_VA3HDL_Ham_Radio_Dashboard_Sources.png?raw=true) ![N4TDX Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/N4TDX-sample.png?raw=true) ![WG5EEK Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/WG5EEK-sample.jpg?raw=true) ![KJ5FMX Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/KJ5FMX-sample.jpg?raw=true) ![N0RMJ Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/N0RMJ-sample.jpg?raw=true) ![N5GAH Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/N5GAH-sample.jpg?raw=true) ![OES MarTech Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/OESmartech.jpg?raw=true) ![TheSky Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/TheSky.jpg?raw=true) ![KJ7T Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/KJ7T-sample.png?raw=true) ![K4HNH Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/K4HNH-sample.jpg?raw=true) ![CT1ETE Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/CT1ETE-sample.jpg?raw=true) ![VK3FS Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/VK3FS-sample.png?raw=true) ![W5EAK Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/W5EAK-sample.jpg?raw=true) ![WI5L Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/WI5L-sample.jpg?raw=true) ![WX9WTF Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/WX9WTF-sample.jpg?raw=true) ### Dual menu example ![Dual side Menu Sample Dashboard](https://github.com/VA3HDL/hamdashboard/blob/main/examples/DualMenu.png?raw=true) ### Sources display example ![Sources display example](https://github.com/VA3HDL/hamdashboard/blob/main/examples/sources.png?raw=true) ================================================ FILE: config.js ================================================ const disableSetup = false; const disableLdCfg = false; var topBarCenterText = `VA3HDL - FN04ga - .js`; // Grid layout var layout_cols = 4; var layout_rows = 3; // 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! var aURL = [ ["f3de21", "SATS", "satellite.js"], ["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", "dark|https://weather.gc.ca/?layers=alert,radar¢er=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. var aIMG = [ [["Radar CONUS", "Radar Small"], "https://radar.weather.gov/ridge/standard/CONUS-LARGE_loop.gif", "https://radar.weather.gov/ridge/standard/CONUS_loop.gif"], [ "LOCAL RADAR (inverted)", "invert|https://radar.weather.gov/ridge/standard/KNQA_loop.gif", ], [ "NOAA D-RAP (inverted)", "invert|https://s.w-x.co/staticmaps/wu/wxtype/county_loc/bgm/animate.png", ], [ "ISS POSITION", "https://www.heavens-above.com/orbitdisplay.aspx?icon=iss&width=600&height=300&mode=M&satid=25544", ], [ "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", ], ["YOUTUBE EXAMPLE", "iframe|https://www.youtube.com/embed/fzPFaXAV_2Y?autoplay=1&mute=1"], [ "WEBSITE EXAMPLE", "iframe|https://globe.adsbexchange.com/?airport=YYZ", ], ["VIDEO EXAMPLE", "https://himawari8.nict.go.jp/movie/720/20240611_pifd.mp4"], ["HF PROPAGATION", "https://www.hamqsl.com/solar101vhf.php"], ]; // Image rotation intervals in milliseconds per tile - If the line below is commented, all tiles will be rotated every 30000 milliseconds (30s) var tileDelay = [ 11200,10000,11000,10100, 10200,10500,10300,10600, 30400,60700,60900,10800 ]; // RSS feed items // Structure is [feed URL, refresh interval in minutes] var aRSS = [ ["https://www.amsat.org/feed/", 60], // Example RSS feed, refresh every 60 minutes ["https://daily.hamweekly.com/atom.xml", 120], // Example Atom feed, refresh every 120 minutes ]; ================================================ FILE: config.json ================================================ { "disableSetup": false, "disableLdCfg": false, "topBarCenterText": "VA3HDL - FN04ga - JSON", "layout_cols": 4, "layout_rows": 3, "aURL": [ ["f3de21", "SATS", "satellite.js"], ["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", "dark|https://weather.gc.ca/?layers=alert,radar¢er=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"] ], "aIMG": [ [["Radar CONUS", "Radar Small"], ["https://radar.weather.gov/ridge/standard/CONUS-LARGE_loop.gif", "https://radar.weather.gov/ridge/standard/CONUS_loop.gif"], 60100], ["LOCAL RADAR (inverted)", "invert|https://radar.weather.gov/ridge/standard/KNQA_loop.gif", 10000], ["NOAA D-RAP (inverted)", "invert|https://s.w-x.co/staticmaps/wu/wxtype/county_loc/bgm/animate.png", 11000], ["ISS POSITION", "https://www.heavens-above.com/orbitdisplay.aspx?icon=iss&width=600&height=300&mode=M&satid=25544", 10100], ["SATELLITE CAN", "https://cdn.star.nesdis.noaa.gov/GOES16/GLM/SECTOR/can/EXTENT3/GOES16-CAN-EXTENT3-1125x560.gif", 10200], ["SATELLITE CGL", "https://cdn.star.nesdis.noaa.gov/GOES16/GLM/SECTOR/cgl/EXTENT3/GOES16-CGL-EXTENT3-600x600.gif", 10500], ["LIGHTNING", "https://images.lightningmaps.org/blitzortung/america/index.php?animation=usa", 10300], ["LIGHTNING LOCAL", "https://www.blitzortung.org/en/Images/image_b_ny.png", 10600], ["YOUTUBE EXAMPLE", "iframe|https://www.youtube.com/embed/fzPFaXAV_2Y?autoplay=1&mute=1", 30400], ["WEBSITE EXAMPLE", "iframe|https://globe.adsbexchange.com/?airport=YYZ", 60700], ["VIDEO EXAMPLE", "https://himawari8.nict.go.jp/movie/720/20240611_pifd.mp4", 60900], ["HF PROPAGATION", "https://www.hamqsl.com/solar101vhf.php", 10800] ], "aRSS": [ ["https://www.amsat.org/feed/", 60], ["https://daily.hamweekly.com/atom.xml", 120] ] } ================================================ FILE: config_jsonp.js ================================================ window.hamdashConfig = { "disableSetup": false, "disableLdCfg": false, "topBarCenterText": "VA3HDL-FN04ga-JsonP", "layout_cols": 4, "layout_rows": 3, "aURL": [ ["f3de21", "SATS", "satellite.js"], ["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", "dark|https://weather.gc.ca/?layers=alert,radar¢er=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"] ], "aIMG": [ [["Radar CONUS", "Radar Small"], ["https://radar.weather.gov/ridge/standard/CONUS-LARGE_loop.gif", "https://radar.weather.gov/ridge/standard/CONUS_loop.gif"], 60100], ["LOCAL RADAR (inverted)", "invert|https://radar.weather.gov/ridge/standard/KNQA_loop.gif", 10000], ["NOAA D-RAP (inverted)", "invert|https://s.w-x.co/staticmaps/wu/wxtype/county_loc/bgm/animate.png", 11000], ["ISS POSITION", "https://www.heavens-above.com/orbitdisplay.aspx?icon=iss&width=600&height=300&mode=M&satid=25544", 10100], ["SATELLITE CAN", "https://cdn.star.nesdis.noaa.gov/GOES16/GLM/SECTOR/can/EXTENT3/GOES16-CAN-EXTENT3-1125x560.gif", 10200], ["SATELLITE CGL", "https://cdn.star.nesdis.noaa.gov/GOES16/GLM/SECTOR/cgl/EXTENT3/GOES16-CGL-EXTENT3-600x600.gif", 10500], ["LIGHTNING", "https://images.lightningmaps.org/blitzortung/america/index.php?animation=usa", 10300], ["LIGHTNING LOCAL", "https://www.blitzortung.org/en/Images/image_b_ny.png", 10600], ["YOUTUBE EXAMPLE", "iframe|https://www.youtube.com/embed/fzPFaXAV_2Y?autoplay=1&mute=1", 30400], ["WEBSITE EXAMPLE", "iframe|https://globe.adsbexchange.com/?airport=YYZ", 60700], ["VIDEO EXAMPLE", "https://himawari8.nict.go.jp/movie/720/20240611_pifd.mp4", 60900], ["HF PROPAGATION", "https://www.hamqsl.com/solar101vhf.php", 10800] ], "aRSS": [ ["https://www.amsat.org/feed/", 60], ["https://daily.hamweekly.com/atom.xml", 120] ] }; ================================================ FILE: hamdash.html ================================================ Ham Radio Dashboard

Dashboard Setup

(Please choose the source of the settings for the next time the dashboard is loaded.)
(The number of Dashboard Items table will adjust automatically for the grid layout selected here.)
Tile Title Tile URLs URL Rotation Interval (ms) Actions
Feed URL Refresh Interval (minutes) Actions
pic
 
 
 
Full config.js file: (Open in new tab)

Menu Options:
Image Sources:
Feed Sources:
Development by:
================================================ FILE: satellite.js ================================================ // CUT START // const disableSetup = true; var topBarCenterText = "Satellite Dashboard"; // Grid layout desired var layout_cols = 2; var layout_rows = 2; // 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! var aURL = [ [ "2196F3", "LIGHTNING", "https://map.blitzortung.org/#3.87/36.5/-89.41", "1", "R", ], [ "2196F3", "RADAR", "https://weather.gc.ca/?layers=alert,radar¢er=43.39961001,-78.53212031&zoom=6&alertTableFilterProv=ON", "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", ], [ "2196F3", "WINDY", "https://embed.windy.com/embed2.html?lat=44.01&lon=-79.45&width=900&detailLat=44.01&detailLon=-79.45&height=600&zoom=8&level=surface&overlay=clouds&product=ecmwf&menu=&message=&marker=&calendar=now&pressure=&type=map&location=coordinates&detail=true&metricWind=km%2Fh&metricTemp=%C2%B0C&radarRange=-1", "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. var currentDate = new Date(); var aIMG = [ // 1 ["Radar NA", "https://radar.weather.gov/ridge/standard/CONUS-LARGE_loop.gif", "https://radar.weather.gov/ridge/standard/CONUS_loop.gif"], // 2 [ "Radar Local", "https://s.w-x.co/staticmaps/wu/wxtype/county_loc/bgm/animate.png", ], // 3 [ "Satellite NA (inverted)", "invert|https://cdn.star.nesdis.noaa.gov/GOES16/ABI/SECTOR/can/GEOCOLOR/GOES16-CAN-GEOCOLOR-1125x560.gif", ], // 4 [ "Satellite Local (inverted)", "invert|https://cdn.star.nesdis.noaa.gov/GOES16/GLM/SECTOR/cgl/EXTENT3/GOES16-CGL-EXTENT3-600x600.gif", ], ]; // Image rotation intervals in milliseconds per tile - If the line below is commented, tiles will be rotated every 5000 milliseconds (5s) var tileDelay = [ 60100, 60200, 300300, 60400, ]; var aRSS = [ ["https://weather.gc.ca/rss/battleboard/onrm28_e.xml", 60], ]; // CUT END ================================================ FILE: wheelzoom.js ================================================ /*! Wheelzoom 4.0.1 license: MIT http://www.jacklmoore.com/wheelzoom */ window.wheelzoom = (function(){ var defaults = { zoom: 0.10, maxZoom: false, initialZoom: 1, initialX: 0.5, initialY: 0.5, }; var main = function(img, options){ if (!img || !img.nodeName || img.nodeName !== 'IMG') { return; } var settings = {}; var width; var height; var bgWidth; var bgHeight; var bgPosX; var bgPosY; var previousEvent; var transparentSpaceFiller; function setSrcToBackground(img) { img.style.backgroundRepeat = 'no-repeat'; img.style.backgroundImage = 'url("'+img.src+'")'; transparentSpaceFiller = 'data:image/svg+xml;base64,'+window.btoa(''); img.src = transparentSpaceFiller; } function updateBgStyle() { if (bgPosX > 0) { bgPosX = 0; } else if (bgPosX < width - bgWidth) { bgPosX = width - bgWidth; } if (bgPosY > 0) { bgPosY = 0; } else if (bgPosY < height - bgHeight) { bgPosY = height - bgHeight; } img.style.backgroundSize = bgWidth+'px '+bgHeight+'px'; img.style.backgroundPosition = bgPosX+'px '+bgPosY+'px'; } function reset() { bgWidth = width; bgHeight = height; bgPosX = bgPosY = 0; updateBgStyle(); } function onwheel(e) { var deltaY = 0; e.preventDefault(); if (e.deltaY) { // FireFox 17+ (IE9+, Chrome 31+?) deltaY = e.deltaY; } else if (e.wheelDelta) { deltaY = -e.wheelDelta; } // As far as I know, there is no good cross-browser way to get the cursor position relative to the event target. // We have to calculate the target element's position relative to the document, and subtrack that from the // cursor's position relative to the document. var rect = img.getBoundingClientRect(); var offsetX = e.pageX - rect.left - window.pageXOffset; var offsetY = e.pageY - rect.top - window.pageYOffset; // Record the offset between the bg edge and cursor: var bgCursorX = offsetX - bgPosX; var bgCursorY = offsetY - bgPosY; // Use the previous offset to get the percent offset between the bg edge and cursor: var bgRatioX = bgCursorX/bgWidth; var bgRatioY = bgCursorY/bgHeight; // Update the bg size: if (deltaY < 0) { bgWidth += bgWidth*settings.zoom; bgHeight += bgHeight*settings.zoom; } else { bgWidth -= bgWidth*settings.zoom; bgHeight -= bgHeight*settings.zoom; } if (settings.maxZoom) { bgWidth = Math.min(width*settings.maxZoom, bgWidth); bgHeight = Math.min(height*settings.maxZoom, bgHeight); } // Take the percent offset and apply it to the new size: bgPosX = offsetX - (bgWidth * bgRatioX); bgPosY = offsetY - (bgHeight * bgRatioY); // Prevent zooming out beyond the starting size if (bgWidth <= width || bgHeight <= height) { reset(); } else { updateBgStyle(); } } function drag(e) { e.preventDefault(); bgPosX += (e.pageX - previousEvent.pageX); bgPosY += (e.pageY - previousEvent.pageY); previousEvent = e; updateBgStyle(); } function removeDrag() { document.removeEventListener('mouseup', removeDrag); document.removeEventListener('mousemove', drag); } // Make the background draggable function draggable(e) { e.preventDefault(); previousEvent = e; document.addEventListener('mousemove', drag); document.addEventListener('mouseup', removeDrag); } function load() { var initial = Math.max(settings.initialZoom, 1); if (img.src === transparentSpaceFiller) return; var computedStyle = window.getComputedStyle(img, null); width = parseInt(computedStyle.width, 10); height = parseInt(computedStyle.height, 10); bgWidth = width * initial; bgHeight = height * initial; bgPosX = -(bgWidth - width) * settings.initialX; bgPosY = -(bgHeight - height) * settings.initialY; setSrcToBackground(img); img.style.backgroundSize = bgWidth+'px '+bgHeight+'px'; img.style.backgroundPosition = bgPosX+'px '+bgPosY+'px'; img.addEventListener('wheelzoom.reset', reset); img.addEventListener('wheel', onwheel); img.addEventListener('mousedown', draggable); } var destroy = function (originalProperties) { img.removeEventListener('wheelzoom.destroy', destroy); img.removeEventListener('wheelzoom.reset', reset); img.removeEventListener('load', load); img.removeEventListener('mouseup', removeDrag); img.removeEventListener('mousemove', drag); img.removeEventListener('mousedown', draggable); img.removeEventListener('wheel', onwheel); img.style.backgroundImage = originalProperties.backgroundImage; img.style.backgroundRepeat = originalProperties.backgroundRepeat; img.src = originalProperties.src; }.bind(null, { backgroundImage: img.style.backgroundImage, backgroundRepeat: img.style.backgroundRepeat, src: img.src }); img.addEventListener('wheelzoom.destroy', destroy); options = options || {}; Object.keys(defaults).forEach(function(key){ settings[key] = options[key] !== undefined ? options[key] : defaults[key]; }); if (img.complete) { load(); } img.addEventListener('load', load); }; // Do nothing in IE9 or below if (typeof window.btoa !== 'function') { return function(elements) { return elements; }; } else { return function(elements, options) { if (elements && elements.length) { Array.prototype.forEach.call(elements, function (node) { main(node, options); }); } else if (elements && elements.nodeName) { main(elements, options); } return elements; }; } }());