Skip to content
Draft
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions assets/js/dialog.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { addClickListener } from "./panZoom.js";

function getCloseButton(dialog) {
return dialog.querySelector(".o-dialog__header > .a-button");
}
Expand Down Expand Up @@ -26,10 +28,9 @@ function openDialogOnHash() {

function initDialogs() {
document.querySelectorAll("dialog").forEach((dialog) => {
dialog.addEventListener("click", (e) => {
if (e.target === dialog) {
dialog.close();
}
addClickListener(dialog, (e) => {
if (e.target !== dialog) return;
dialog.close();
});

const closeButton = getCloseButton(dialog);
Expand Down
86 changes: 24 additions & 62 deletions assets/js/interactiveMap.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,36 @@
import Panzoom from "@panzoom/panzoom";
import { addClickListener, initPanZoom } from "./panZoom.js";

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 container = document.getElementById("interactive-map__container");
if (!container) return;

const panzoom = Panzoom(svg, {
maxScale: 5,
minScale: 1,
startScale: 1,
contain: "outside",
});
const panzoom = initPanZoom(container);
if (!panzoom) return;

// Enable mouse wheel zoom
svg.parentElement.addEventListener("wheel", panzoom.zoomWithWheel);
const svg = container.querySelector("svg");
if (!svg) return;

// Enable double-click zoom
svg.addEventListener("dblclick", (e) => {
e.preventDefault();
panzoom.zoomIn({ step: 0.5 });
});
svg.setAttribute("viewBox", "0 0 1300 1300");

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");
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");

if (zoomInBtn) {
zoomInBtn.addEventListener("click", (e) => {
e.preventDefault();
panzoom.zoomIn({ step: 0.5 });
addClickListener(country, (e) => {
window.location.href = `/${window.currentLanguage}/country/${country.id}/`;
});
}

if (zoomOutBtn) {
zoomOutBtn.addEventListener("click", (e) => {
e.preventDefault();
panzoom.zoomOut({ step: 0.5 });
});
}

if (resetBtn) {
resetBtn.addEventListener("click", (e) => {
e.preventDefault();
panzoom.reset();
});
if (
window.unavailableCountries &&
window.unavailableCountries.includes(country.id)
) {
country.classList.add("o-interactive-map__country--unavailable");
}

// 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}/`;
});
}

if (
window.unavailableCountries &&
window.unavailableCountries.includes(country.id)
) {
country.classList.add("o-interactive-map__country--unavailable");
}
});
}
});
};
15 changes: 15 additions & 0 deletions assets/js/lightbox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { initPanZoom } from "./panZoom.js";

function initLightboxes() {
document
.querySelectorAll(".o-dialog__wrapper--lightbox .o-pan-zoom__container")
.forEach((container) => {
initPanZoom(container);
});
}

if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", initLightboxes);
} else {
initLightboxes();
}
1 change: 1 addition & 0 deletions assets/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ import "./search.js";
import "./interactiveMap.js";
import "./expander.js";
import "./dialog.js";
import "./lightbox.js";
import "./fipValidityComparison.js";
79 changes: 79 additions & 0 deletions assets/js/panZoom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import Panzoom from "@panzoom/panzoom";

export function addClickListener(element, onClick) {
let pointerDownPos = null;

element.addEventListener("pointerdown", (e) => {
pointerDownPos = { x: e.clientX, y: e.clientY };
});

element.addEventListener("click", (e) => {
if (!pointerDownPos) return;
const dx = e.clientX - pointerDownPos.x;
const dy = e.clientY - pointerDownPos.y;
pointerDownPos = null;
if (Math.hypot(dx, dy) >= 5) return;
onClick(e);
});
}

export function initPanZoom(container) {
const pannable = container.querySelector("svg, img");
if (!pannable) return null;

const panzoom = Panzoom(pannable, {
maxScale: 5,
minScale: 1,
startScale: 1,
contain: "outside",
});

pannable.style.cursor = "grab";
pannable.addEventListener("pointerdown", () => {
pannable.style.cursor = "grabbing";
});
pannable.addEventListener("pointerup", () => {
pannable.style.cursor = "grab";
});

container.addEventListener("wheel", panzoom.zoomWithWheel);

pannable.addEventListener("dblclick", (e) => {
e.preventDefault();
panzoom.zoomIn({ step: 0.5 });
});

const containerId = container.id;
const zoomInBtn = document.querySelector(
`.o-pan-zoom__zoom-in[data-pan-zoom="${containerId}"]`,
);
const zoomOutBtn = document.querySelector(
`.o-pan-zoom__zoom-out[data-pan-zoom="${containerId}"]`,
);
const resetBtn = document.querySelector(
`.o-pan-zoom__reset[data-pan-zoom="${containerId}"]`,
);

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();
});
}

return panzoom;
}
46 changes: 1 addition & 45 deletions assets/sass/interactiveMap.scss
Original file line number Diff line number Diff line change
@@ -1,31 +1,7 @@
.o-interactive-map {
&__wrapper {
position: relative;
}

&__container {
.o-pan-zoom__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;

@media print {
display: none;
}
}

.o-interactive-map__country--available {
Expand Down Expand Up @@ -55,26 +31,6 @@
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;
transition: background-color 0.2s ease;

&:hover,
&:focus {
background-color: var(--link-hovered);
}

@include focus-indicator(0.2rem);
}

&__legend {
display: flex;
column-gap: 2rem;
Expand Down
24 changes: 24 additions & 0 deletions assets/sass/lightbox.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.o-lightbox__trigger {
cursor: zoom-in;
}

.o-dialog__wrapper--lightbox {
.o-dialog__wrapper {
max-width: 90dvh;
}

.o-dialog {
max-height: unset;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some images aren’t appear in full size
see https://deploy-preview-740--fipguide.netlify.app/de/operator/sll/ "Kosten online herausfinden" -> "Step 1"

Image

}

.o-dialog__body {
padding: 0;
overflow: hidden;
flex: 1;
display: flex;
}

.o-pan-zoom__wrapper {
flex: 1;
}
}
2 changes: 2 additions & 0 deletions assets/sass/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
@import "identifyOperator.scss";
@import "button.scss";
@import "startpage.scss";
@import "pan-zoom.scss";
@import "interactiveMap.scss";
@import "dropdown.scss";
@import "trainCategory.scss";
@import "tag.scss";
@import "floatImage.scss";
@import "teamMember.scss";
@import "dialog.scss";
@import "lightbox.scss";
@import "fip-validity.scss";
53 changes: 53 additions & 0 deletions assets/sass/pan-zoom.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
.o-pan-zoom {
&__wrapper {
position: relative;
}

&__container {
width: 100%;
height: 100%;

svg {
width: 100%;
height: 100%;
}

img {
width: 100%;
height: 100%;
}
}

&__controls {
position: absolute;
bottom: 1rem;
right: 1rem;
display: flex;
flex-direction: column;
gap: 0.5rem;

@media print {
display: none;
}

button {
background-color: var(--link-default);
color: var(--bg-default);
border-radius: var(--border-radius-m);
border: 0;
width: 4rem;
aspect-ratio: 1 / 1;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.2s ease;

&:hover,
&:focus {
background-color: var(--link-hovered);
}

@include focus-indicator(0.2rem);
}
}
}
4 changes: 2 additions & 2 deletions content/operator/cd/index.de.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ FIP Freifahrtscheine und FIP 50 Tickets sind auf Verbindungen der ČD gültig. B
{{< float-image
src="cd-fip-map-overview-26.webp"
alt="FIP Gültigkeitskarte Überblick für Tschechien"
caption="[Überblick FIP Gültigkeitskarte](/en/operator/cd/cd-fip-map-overview-26.webp) für Tschechien (© Petr Duda)"
caption="Überblick FIP Gültigkeitskarte für Tschechien (© Petr Duda)"
width="40%"
position="left" >}}

Expand All @@ -39,7 +39,7 @@ Für einen ersten Eindruck, kann die Übersichtskarte für FIP Vergünstigungen
{{< float-image
src="cd-fip-map-detail-26.webp"
alt="FIP Gültigkeitskarte Detail für Tschechien"
caption="[Detail FIP Gültigkeitskarte](/en/operator/cd/cd-fip-map-detail-26.webp) für Tschechien (© Petr Duda)"
caption="Detail FIP Gültigkeitskarte für Tschechien (© Petr Duda)"
width="40%"
position="left" >}}
Für detaillierte Informartionen kann die Detailkarte für FIP Vergünstigungen genutzt werden.
Expand Down
Loading
Loading