diff --git a/frontend/assets/JetBrainsMono-Bold.woff2 b/frontend/assets/JetBrainsMono-Bold.woff2
new file mode 100644
index 0000000..4917f43
Binary files /dev/null and b/frontend/assets/JetBrainsMono-Bold.woff2 differ
diff --git a/frontend/index.html b/frontend/index.html
index 4173382..297be81 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -22,6 +22,7 @@
+
diff --git a/frontend/src/coordinates.ts b/frontend/src/coordinates.ts
new file mode 100644
index 0000000..54392b8
--- /dev/null
+++ b/frontend/src/coordinates.ts
@@ -0,0 +1,30 @@
+import { Size } from "./size";
+
+export type Coordinate = {
+ longitude: number;
+ latitude: number;
+};
+
+export type Position = {
+ x: number;
+ y: number;
+};
+
+const scalar = { x: 8.26, y: 3.6 } as const;
+const offset = { x: 6, y: 57.92 } as const;
+
+
+export function convertPixelsToCoordinate(mouse: Position, map: Size): Coordinate {
+ return {
+ longitude: offset.x + mouse.x * (scalar.x / map.width),
+ latitude: offset.y - mouse.y * (scalar.y / map.height),
+ };
+}
+
+export function convertCoordinateToPixels(coords: Coordinate, map: Size): Position {
+ return {
+ x: map.width * (coords.longitude - offset.x) / scalar.x,
+ y: map.height * (offset.y - coords.latitude) / scalar.y,
+ };
+}
+
diff --git a/frontend/src/main.ts b/frontend/src/main.ts
index 6c9e492..aef62cb 100644
--- a/frontend/src/main.ts
+++ b/frontend/src/main.ts
@@ -1,20 +1,11 @@
import { Throttler } from "./Throttler";
-
-type Position = {
- x: number;
- y: number;
-};
-
-type Size = { width: number; height: number };
-
-type Coordinate = {
- longitude: number;
- latitude: number;
-};
+import { Coordinate, Position, convertPixelsToCoordinate, convertCoordinateToPixels } from "./coordinates";
+import { Size } from "./size";
type ZipCodeReverseResponse = {
nr: number | null;
navn: string;
+ visueltcenter: number[];
};
async function fetchZipCode({
@@ -35,15 +26,6 @@ async function fetchZipCode({
.catch(() => null as never);
}
-function convertPixelsToCoordinate(mouse: Position, map: Size): Coordinate {
- const scalar = { x: 8, y: 3.6 };
- const offset = { x: 6.2, y: 57.93 };
- return {
- longitude: (mouse.x / map.width) * scalar.x + offset.x,
- latitude: Math.abs((mouse.y / map.height) * scalar.y - offset.y),
- };
-}
-
function displayMousePosition(element: HTMLParagraphElement, mouse: Position) {
element.innerHTML = `Mouse position: (${mouse.x}px, ${mouse.y}px)
`;
}
@@ -57,12 +39,34 @@ function displayCoords(element: HTMLParagraphElement, coords: Coordinate) {
function displayZipCode(
element: HTMLParagraphElement,
zipCode: number | null,
- name: string,
+ name: string | null,
+ center: Coordinate | null,
) {
element.innerHTML =
zipCode === null
? `Postnummer ikke fundet`
: `Postnummer: ${zipCode}
, ${name}`;
+
+ if (center == null) return;
+
+ const dot = document.getElementById("dot")!;
+
+ if (!zipCode) {
+ dot.style.display = "none";
+ return;
+ }
+
+ const mapImg = document.getElementById("map")!;
+ const mapSize: Size = {
+ width: mapImg.clientWidth,
+ height: mapImg.clientHeight,
+ };
+
+ const position = convertCoordinateToPixels(center, mapSize);
+ const rect = document.getElementById("map")!.getBoundingClientRect();
+ dot.style.display = "block";
+ dot.style.left = (position.x + rect.left) + "px";
+ dot.style.top = (position.y + rect.top) + "px";
}
function setupMap(
@@ -84,7 +88,12 @@ function setupMap(
displayCoords(coordsElement, coords);
fetcher.call(async () => {
const response = await fetchZipCode(coords);
- displayZipCode(zipCodeElement, response.nr, response.navn);
+ displayZipCode(
+ zipCodeElement,
+ response.nr,
+ response.navn,
+ response.visueltcenter ? { longitude: response.visueltcenter[0], latitude: response.visueltcenter[1] } : null,
+ );
});
};
@@ -99,13 +108,18 @@ function setupMap(
displayCoords(coordsElement, coords);
fetcher.call(async () => {
const response = await fetchZipCode(coords);
- displayZipCode(zipCodeElement, response.nr, response.navn);
- console.log("test")
+ displayZipCode(
+ zipCodeElement,
+ response.nr,
+ response.navn,
+ response.visueltcenter ? { longitude: response.visueltcenter[0], latitude: response.visueltcenter[1] } : null,
+ );
});
}
mapImg.onmouseleave = (_event: MouseEvent) => {
+ document.getElementById("dot")!.style.display = "none";
[mousePositionElement, coordsElement, zipCodeElement].forEach(
(e) => (e.innerHTML = ""),
);
@@ -119,10 +133,11 @@ function setupSearchBar(zipCodeElement: HTMLParagraphElement) {
document.querySelector("#search-input")!;
// Prevent typing letters
- searchBar.onkeypress = (event: KeyboardEvent) => {console.log(event);
- event.key !== "Enter" || !isNaN(parseInt(event.key));}
+ searchBar.onkeypress = event => {
+ event.key !== "Enter" || !isNaN(parseInt(event.key));
+ }
- searchBar.addEventListener("submit", async (event: SubmitEvent) => {
+ searchBar.addEventListener("submit", async (event: Event) => {
event.preventDefault();
const inputValue = searchInput.value;
@@ -137,6 +152,7 @@ function setupSearchBar(zipCodeElement: HTMLParagraphElement) {
zipCodeElement,
data.length ? parseInt(data[0]["nr"]) : null,
data.length ? data[0]["navn"] : null,
+ data.length ? { longitude: data[0]["visueltcenter"][0], latitude: data[0]["visueltcenter"][1] } : null,
);
});
diff --git a/frontend/src/size.ts b/frontend/src/size.ts
new file mode 100644
index 0000000..e2dbad5
--- /dev/null
+++ b/frontend/src/size.ts
@@ -0,0 +1,5 @@
+export type Size = {
+ width: number;
+ height: number
+};
+
diff --git a/frontend/style.css b/frontend/style.css
index c5c998b..f7bc917 100644
--- a/frontend/style.css
+++ b/frontend/style.css
@@ -1,6 +1,11 @@
@font-face {
- font-family: "Jetbrains Mono";
- src: url("assets/JetbrainsMono-Regular.woff2");
+ font-family: "JetBrains Mono";
+ src: url("assets/JetBrainsMono-Regular.woff2");
+}
+
+@font-face {
+ font-family: "JetBrains Mono Bold";
+ src: url("assets/JetBrainsMono-Bold.woff2");
}
* {
@@ -40,8 +45,7 @@ main > * {
}
code {
- font-family: "Jetbrains Mono", monospace;
- font-weight: bold;
+ font-family: "JetBrains Mono Bold", monospace;
}
#search-bar {
@@ -109,6 +113,17 @@ code {
font-size: 0.9em;
}
+#dot {
+ width: 15px;
+ height: 15px;
+ border-radius: 50%;
+ border: 2px solid black;
+ filter: drop-shadow(1px 1px 2px black);
+ background-color: red;
+ position: absolute;
+ display: none;
+}
+
@media screen and (max-width: 1000px) {
main {
width: 100%;