summaryrefslogtreecommitdiff
path: root/views/pages/global-map.html
diff options
from:
to:
context:
space:
mode:
Diffstat (limited to 'views/pages/global-map.html')
-rw-r--r--views/pages/global-map.html241
1 files changed, 241 insertions, 0 deletions
diff --git a/views/pages/global-map.html b/views/pages/global-map.html
new file mode 100644
index 0000000..09d7ab2
--- /dev/null
+++ b/views/pages/global-map.html
@@ -0,0 +1,241 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>SAYA TODAY // {{ .L.GlobalMap.Header }}</title>
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
+ <link rel="preconnect" href="https://fonts.googleapis.com">
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+ <link href="https://fonts.googleapis.com/css2?family=Spectral:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;0,800;1,200;1,300;1,400;1,500;1,600;1,700;1,800&family=Patua+One&display=swap" rel="stylesheet">
+ {{ block "header" . }}{{ end }}
+ <link href="/output.css" rel="stylesheet">
+ <link rel="stylesheet" href="https://f003.backblazeb2.com/file/sayana-static/libs/leaflet/1.9.4/leaflet.css">
+</head>
+
+<body data-theme="ram" class="font-spectral text-main-dark overflow-hidden bg-interlocked-hexagons h-screen flex flex-row ar-lt-0.8:flex-col">
+
+ <script>
+ function switchTheme(theme) {
+ if (theme == "" || typeof theme == "undefined") {
+ const currentTheme = document.body.getAttribute('data-theme');
+ switch (currentTheme) {
+ case "olive": theme = "lettuce"; break;
+ case "lettuce": theme = "night"; break;
+ case "night": theme = "ram"; break;
+ case "ram": theme = "olive"; break;
+ }
+ }
+ localStorage.setItem('theme', theme);
+ document.body.setAttribute('data-theme', theme);
+ }
+
+ const savedTheme = localStorage.getItem('theme') || 'ram';
+ switchTheme(savedTheme);
+ </script>
+
+ <script>
+ const clientTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
+ </script>
+
+ <div id="sidebar" class="bg-sidebar flex sticky flex-col ar-gt-0.8:items-center shadow-2xl z-20 w-[5vw] ar-lt-0.8:w-screen h-screen ar-lt-0.8:h-[8vh]">
+ <div class="logo-custom ar-lt-0.8:hidden text-sidebar font-patua font-extrabold text-center relative z-20">
+ saya.today
+ </div>
+ <div class="text-[3vw] ar-lt-0.8:text-[5vh] text-stroke-(--sidebar-stroke-color) text-stroke-[0.1vw] flex flex-col ar-lt-0.8:flex-row gap-0 relative z-20">
+ <i onclick="location.href='/';" class="fas fa-home w-[5vw] ar-lt-0.8:w-[8vh] h-[5vw] ar-lt-0.8:h-[8vh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i>
+ <i onclick="location.href='/{{ .Lang }}/blog';" class="fas fa-search w-[5vw] ar-lt-0.8:w-[8vh] h-[5vw] ar-lt-0.8:h-[8vh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i>
+ <i onclick="location.href='/{{ .Lang }}/map';" class="fas fa-map w-[5vw] ar-lt-0.8:w-[8vh] h-[5vw] ar-lt-0.8:h-[8vh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i>
+ <i onclick="toggleThemeWheel();" id="theme-button" class="fas fa-swatchbook w-[5vw] ar-lt-0.8:w-[8vh] h-[5vw] ar-lt-0.8:h-[8vh] content-center text-center text-sidebar hover:bg-background-dark cursor-pointer transition-colors duration-300 flex rounded-lg"></i>
+ </div>
+ <div class="theme-wheel" id="theme-wheel">
+ <div class="theme-icon" data-theme="olive"></div>
+ <div class="theme-icon" data-theme="lettuce"></div>
+ <div class="theme-icon" data-theme="night"></div>
+ <div class="theme-icon" data-theme="ram"></div>
+ </div>
+ </div>
+
+ <div id="map-container" class="bg-background-dark flex z-10 w-[95vw] ar-lt-0.8:w-screen h-screen ar-lt-0.8:h-[92vh]"></div>
+
+ <script src="https://f003.backblazeb2.com/file/sayana-static/libs/htmx/2.0.6/htmx.min.js"></script>
+ <script src="https://f003.backblazeb2.com/file/sayana-static/libs/leaflet/1.9.4/leaflet.js"></script>
+
+ <script>
+ const themeWheel = document.getElementById('theme-wheel');
+ const themeButton = document.getElementById('theme-button');
+ const themeIcons = document.querySelectorAll('.theme-icon');
+
+ themeIcons.forEach(icon => {
+ if (icon.getAttribute('data-theme') == savedTheme) {
+ icon.classList.add('active');
+ }
+ });
+
+ function calculateVmax(percent) {
+ const viewportWidth = window.innerWidth;
+ const viewportHeight = window.innerHeight;
+
+ const largerDimension = Math.max(viewportWidth, viewportHeight);
+
+ const vmaxValue = (largerDimension / 100) * percent;
+
+ return vmaxValue;
+ }
+
+ function positionThemeIcons() {
+ const icons = themeWheel.querySelectorAll('.theme-icon');
+ const iconCount = icons.length;
+ const vmax = calculateVmax(1);
+ const wheelRadius = 7.5*vmax; // Radius of the wheel
+ const iconRadius = 4*vmax; // Distance from center to place icons
+ const iconSize = 3*vmax; // Half of icon size for centering
+
+ icons.forEach((icon, index) => {
+ const angle = (index * 360 / iconCount) - 90;
+ const angleRad = (angle * Math.PI) / 180;
+
+ const x = Math.cos(angleRad) * iconRadius + wheelRadius - iconSize;
+ const y = Math.sin(angleRad) * iconRadius + wheelRadius - iconSize;
+
+ icon.style.left = x + 'px';
+ icon.style.top = y + 'px';
+ });
+ }
+
+ function positionThemeWheel() {
+ const buttonRect = themeButton.getBoundingClientRect();
+ const buttonCenterX = buttonRect.left + buttonRect.width / 2;
+ const buttonCenterY = buttonRect.top + buttonRect.height / 2;
+
+ const wheelRadius = calculateVmax(7.5);
+ const margin = calculateVmax(1);
+
+ let wheelX = buttonCenterX - wheelRadius;
+ let wheelY = buttonCenterY - wheelRadius;
+
+ const viewportWidth = window.innerWidth;
+ const viewportHeight = window.innerHeight;
+
+ if (wheelX < margin) {
+ wheelX = margin;
+ } else if (wheelX + (wheelRadius * 2) > viewportWidth - margin) {
+ wheelX = viewportWidth - (wheelRadius * 2) - margin;
+ }
+
+ if (wheelY < margin) {
+ wheelY = margin;
+ } else if (wheelY + (wheelRadius * 2) > viewportHeight - margin) {
+ wheelY = viewportHeight - (wheelRadius * 2) - margin;
+ }
+
+ themeWheel.style.left = wheelX + 'px';
+ themeWheel.style.top = wheelY + 'px';
+ }
+
+ function hideThemeWheel() {
+ themeWheel.classList.remove('active');
+ }
+
+ function showThemeWheel() {
+ positionThemeWheel();
+ positionThemeIcons();
+ themeWheel.classList.add('active');
+ }
+
+ function toggleThemeWheel() {
+ if (themeWheel.classList.contains('active')) {
+ hideThemeWheel();
+ } else {
+ showThemeWheel();
+ }
+ }
+
+ themeIcons.forEach(icon => {
+ icon.addEventListener('click', (e) => {
+ e.stopPropagation();
+ const theme = icon.getAttribute('data-theme');
+ switchTheme(theme);
+ themeIcons.forEach(icon => {
+ icon.classList.remove('active');
+ })
+ icon.classList.add('active');
+ });
+ });
+
+ themeWheel.addEventListener('mouseleave', hideThemeWheel);
+
+ document.addEventListener('click', (e) => {
+ if (!themeWheel.contains(e.target) && e.target !== themeButton) {
+ hideThemeWheel();
+ }
+ });
+ </script>
+
+ <script>
+ var map;
+
+ function initLocationMap() {
+ map = L.map('map-container').setView([{{ .MapLocationLat }}, {{ .MapLocationLong }}], 4);
+
+ L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
+ maxZoom: 18,
+ attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
+ }).addTo(map);
+ }
+
+ function stringToColor(str) {
+ let hash = 0;
+ for (let i = 0; i < str.length; i++) {
+ hash = str.charCodeAt(i) + ((hash << 5) - hash);
+ }
+
+ let color = '#';
+ for (let i = 0; i < 3; i++) {
+ const value = (hash >> (i * 8)) & 0xFF;
+ color += ('00' + value.toString(16)).substr(-2);
+ }
+
+ return color;
+ }
+
+ function mapAddMarker(x, y, relativeErrorMeters = 0, title = "", link = "", thumbnail = "") {
+ const titleColor = stringToColor(title);
+
+ if (relativeErrorMeters != 0) {
+ var circle = L.circle([x, y], {
+ color: titleColor,
+ fillColor: titleColor,
+ fillOpacity: 0.15,
+ radius: relativeErrorMeters
+ }).addTo(map);
+ }
+
+ var marker = L.marker([x, y], {
+ title: title,
+ }).addTo(map)
+ .bindPopup(`
+ <div class="flex flex-row justify-center justify-items-center">
+ <img onclick="location.href='${link}';" class="cursor-pointer object-cover rounded-[10%] select-none w-[3vmax] h-[3vmax] mr-[0.5vmax]" src="https://f003.backblazeb2.com/file/sayana-photos/webp-320p/${thumbnail}.webp">
+ <span><b><a href="${link}">${title}</a></b><br><a href="https://www.openstreetmap.org/#map=13/${x}/${y}">${x}, ${y}</a></span>
+ </div>`);
+ }
+
+ document.addEventListener('DOMContentLoaded', () => {
+ initLocationMap();
+ {{- range .MapMarkers }}
+ mapAddMarker({{ .Lat }}, {{ .Long }}, {{ .AccuracyMeters }}, {{ .Title }}, {{ .PageLink }}, {{ .Thumbnail }});
+ {{- end }}
+ });
+
+ window.addEventListener('resize', function() {
+ setTimeout(() => {
+ map.invalidateSize();
+ }, 100);
+ });
+ </script>
+
+ {{ block "footer" . }}{{ end }}
+
+</body>
+</html>