diff --git a/assets/js/interactiveMap.js b/assets/js/interactiveMap.js new file mode 100644 index 00000000..aaf38951 --- /dev/null +++ b/assets/js/interactiveMap.js @@ -0,0 +1,64 @@ +import Panzoom from '@panzoom/panzoom'; + +window.initializeInteractiveMap = function() { + const svg = document.querySelector('.o-interactive-map__container svg'); + if (svg) { + // Ensure proper scaling + svg.setAttribute('viewBox', '0 0 1300 1300'); + + const panzoom = Panzoom(svg, { + maxScale: 5, + minScale: 1, + startScale: 1, + contain: 'outside' + }); + + // Enable mouse wheel zoom + svg.parentElement.addEventListener('wheel', panzoom.zoomWithWheel); + + // Enable double-click zoom + svg.addEventListener('dblclick', (e) => { + e.preventDefault(); + panzoom.zoomIn({ step: 0.5 }); + }); + + const zoomInBtn = document.querySelector('.o-interactive-map__zoom-in'); + const zoomOutBtn = document.querySelector('.o-interactive-map__zoom-out'); + const resetBtn = document.querySelector('.o-interactive-map__reset'); + + if (zoomInBtn) { + zoomInBtn.addEventListener('click', (e) => { + e.preventDefault(); + panzoom.zoomIn({ step: 0.5 }); + }); + } + + if (zoomOutBtn) { + zoomOutBtn.addEventListener('click', (e) => { + e.preventDefault(); + panzoom.zoomOut({ step: 0.5 }); + }); + } + + if (resetBtn) { + resetBtn.addEventListener('click', (e) => { + e.preventDefault(); + panzoom.reset(); + }); + } + + // Add country click functionality + const countries = svg.querySelectorAll('[id]'); + countries.forEach(country => { + if (window.availableCountries && window.availableCountries.includes(country.id)) { + country.style.cursor = 'pointer'; + country.classList.add('o-interactive-map__country--available'); + + country.addEventListener('click', (e) => { + e.stopPropagation(); + window.location.href = `/${window.currentLanguage}/country/${country.id}/`; + }); + } + }); + } +}; diff --git a/assets/js/main.js b/assets/js/main.js index 09dcb987..af0aa235 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -4,3 +4,4 @@ import './resizeObserver.js'; import './mediaqueries.js'; import './highlightHeadline.js'; import './anchorlinks.js'; +import './interactiveMap.js'; diff --git a/assets/sass/interactiveMap.scss b/assets/sass/interactiveMap.scss new file mode 100644 index 00000000..3e8d5d77 --- /dev/null +++ b/assets/sass/interactiveMap.scss @@ -0,0 +1,61 @@ +.o-interactive-map { + &__wrapper { + position: relative; + } + + &__container { + border-radius: var(--border-radius-m); + box-shadow: var(--box-shadow); + width: 100%; + aspect-ratio: 1 / 1; + + svg { + width: 100%; + height: 100%; + } + } + + &__controls { + position: absolute; + bottom: 1rem; + right: 1rem; + display: flex; + flex-direction: column; + gap: 0.5rem; + z-index: 10; + } + + .o-interactive-map__country--available { + path { + fill: var(--link-default) !important; + transition: all 0.2s ease; + cursor: pointer; + } + + &:hover path { + fill: var(--link-hovered) !important; + } + } + + .o-interactive-map--loading { + padding: 1rem; + } + + .o-interactive-map__controls button { + background-color: var(--link-default); + color: var(--bg-neutral); + border-radius: var(--border-radius-m); + border: 0; + width: 4rem; + aspect-ratio: 1 / 1; + display: flex; + align-items: center; + justify-content: center; + font-size: 3rem; + transition: all 0.2s ease; + + &:hover { + background-color: var(--link-hovered); + } + } +} diff --git a/assets/sass/main.scss b/assets/sass/main.scss index 123ac786..8152fb6f 100644 --- a/assets/sass/main.scss +++ b/assets/sass/main.scss @@ -16,3 +16,4 @@ @import "booking.scss"; @import "button.scss"; @import "startpage.scss"; +@import "interactiveMap.scss"; diff --git a/assets/sass/styles.scss b/assets/sass/styles.scss index 9df8dd52..fab91a1b 100644 --- a/assets/sass/styles.scss +++ b/assets/sass/styles.scss @@ -142,6 +142,17 @@ img { align-items: center; } +.o-list__countries{ + display: grid; + grid-template-columns: 1fr 1fr; + gap: 1rem; + + @media (max-width: #{$breakpoint-lg}) { + display: flex; + flex-direction: column; + } +} + @mixin add-columns($columns) { &--columns-#{$columns} { columns: $columns; diff --git a/i18n/de.yaml b/i18n/de.yaml index 01f7ccee..d6ec7d7a 100644 --- a/i18n/de.yaml +++ b/i18n/de.yaml @@ -14,11 +14,13 @@ booking: reservation-costs: Reservierungskosten visit-additional-information-website: Weitere Informationen visit-booking-website: Zur Buchungsseite +countries: + overview: Alle Länder + selection: Länderauswahl country: many: Länder one: Land other: Länder -countryselection: Länderauswahl editPage: Seite bearbeiten footer-love: aria-label: Made with love in Aachen, Frankfurt, Köln & Paris @@ -32,6 +34,12 @@ home-page-text: FIP Guide Startseite information-disclaimer-short: >- Diese Informationen sind inoffiziell und ohne Gewähr. Es besteht keine rechtliche Verbindung zu FIP oder Bahngesellschaften. +interactiveMap: + loading: Lade interaktive Karte... + resetZoom: Zoom zurücksetzen + title: Interaktive Länderkarte + zoomIn: Hineinzoomen + zoomOut: Herauszoomen menu-close: Schließen menu-open: Menü navigate-to-country: Gehe zu Land diff --git a/i18n/en.yaml b/i18n/en.yaml index 4880f0d1..54839eef 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -13,11 +13,13 @@ booking: reservation-costs: Reservation Costs visit-additional-information-website: Additional Information visit-booking-website: To Booking Website +countries: + overview: All Countries + selection: choose country country: many: countries one: country other: countries -countryselection: choose country editPage: Edit page footer-love: aria-label: Made with love in Aachen, Frankfurt, Cologne & Paris @@ -31,6 +33,12 @@ home-page-text: FIP Guide Home Page information-disclaimer-short: >- The information provided is unofficial and without guarantee. There is no legal connection to FIP or railway companies. +interactiveMap: + loading: Loading interactive map... + resetZoom: Reset Zoom + title: Interactive Country Map + zoomIn: Zoom In + zoomOut: Zoom Out menu-close: Close menu-open: Menu navigate-to-country: Navigate to country diff --git a/i18n/fr.yaml b/i18n/fr.yaml index 488eb8ca..2fa6d987 100644 --- a/i18n/fr.yaml +++ b/i18n/fr.yaml @@ -30,6 +30,12 @@ home-page-text: Page d'accueil du FIP Guide information-disclaimer-short: >- Les informations fournies sont non officielles et sans garantie. Il n'existe aucun lien juridique avec le FIP ou les compagnies ferroviaires. +interactiveMap: + loading: Chargement de la carte interactive... + resetZoom: Réinitialiser le zoom + title: Carte interactive des pays + zoomIn: Zoom avant + zoomOut: Zoom arrière menu-close: Fermer menu-open: Menu navigate-to-country: Aller au pays diff --git a/layouts/country/list.html b/layouts/country/list.html index a0413e07..08975751 100644 --- a/layouts/country/list.html +++ b/layouts/country/list.html @@ -2,17 +2,63 @@

{{ .Title }}

{{ .Content }} -
- {{ range .Pages }} - -
- {{ partial "flag" (dict "country" .File.ContentBaseName) }} +
+
+

{{ T "countries.overview" }}

+
-
- {{ .Title }} +
+
+

{{ T "interactiveMap.title" }}

+
+
+

{{ T "interactiveMap.loading" }}

+
+
+ + + +
- - {{ end }} +
+ + + {{ end }} diff --git a/layouts/partials/menu.html b/layouts/partials/menu.html index 52ad9e47..927222b5 100644 --- a/layouts/partials/menu.html +++ b/layouts/partials/menu.html @@ -19,7 +19,7 @@
  • {{ T "country" }} diff --git a/package-lock.json b/package-lock.json index 6048a3fe..d6cedb47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@fontsource/material-symbols-rounded": "^5.2.10", "@fontsource/roboto": "^5.2.5", "@fontsource/sansita": "^5.2.5", + "@panzoom/panzoom": "^4.6.0", "pagefind": "^1.3.0" }, "devDependencies": { @@ -110,6 +111,12 @@ "win32" ] }, + "node_modules/@panzoom/panzoom": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@panzoom/panzoom/-/panzoom-4.6.0.tgz", + "integrity": "sha512-3KxkY1lNKFn98fW5ZFR6vV0YzsXj3I4EQDyFWSXME6/cic86eSS7VjuqIjrA3PEpySo0r5fFtlX8eYCt4JPUFQ==", + "license": "MIT" + }, "node_modules/pagefind": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.3.0.tgz", diff --git a/package.json b/package.json index fd931ec2..ca3c8870 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@fontsource/material-symbols-rounded": "^5.2.10", "@fontsource/roboto": "^5.2.5", "@fontsource/sansita": "^5.2.5", + "@panzoom/panzoom": "^4.6.0", "pagefind": "^1.3.0" }, "devDependencies": { diff --git a/static/map_europe.svg b/static/map_europe.svg new file mode 100644 index 00000000..215acbc2 --- /dev/null +++ b/static/map_europe.svg @@ -0,0 +1,5807 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + Addicted04 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +