Skip to content

Commit

Permalink
TODO: Display overlay when feature is clicked
Browse files Browse the repository at this point in the history
refs #49
  • Loading branch information
franthormel committed Aug 12, 2024
1 parent 30ad2b5 commit 0cb1e14
Showing 1 changed file with 46 additions and 8 deletions.
54 changes: 46 additions & 8 deletions app/listings/map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { NumberUtils } from "@/lib/commons/number_utils"
import { CURRENCY_FORMATTER } from "@/lib/formatter/currency"
import { Feature, View } from "ol"
import { Feature, Overlay, View } from "ol"
import Point from "ol/geom/Point"
import TileLayer from "ol/layer/Tile"
import VectorLayer from "ol/layer/Vector"
Expand Down Expand Up @@ -127,6 +127,13 @@ export function ListingsMap(props: ListingsMapInterface) {
features: mapFeatures.iconFeatures,
}),
});
const overlay = new Overlay({
autoPan: {
animation: {
duration: 250,
},
},
});

const map = new Map({
target: 'map',
Expand All @@ -136,12 +143,14 @@ export function ListingsMap(props: ListingsMapInterface) {
}),
vectorLayerIconFeatures
],
overlays: [overlay],
view: new View({
center: [0, 0],
zoom: 2,
}),
})

// Change features display style based on the map's zoom level
let featureDisplayState: 'icon' | 'text' = 'icon';
const MAP_ZOOM_TEXT = 15;
map.on('moveend', (e) => {
Expand All @@ -157,13 +166,14 @@ export function ListingsMap(props: ListingsMapInterface) {
}
})

// Change feature display style to active when hovered upon
let activeIndex: number = -1;
let previousStyle: StyleLike | undefined;
map.on('pointermove', (e) => {
// Hover (revert style)
if (activeIndex >= 0) {
// Use icons features if zoom level is big
// Use text features if zoom level is small
// Uses icon features if zoom level is big
// Uses text features if zoom level is small
let activeFeature = mapFeatures.iconFeatures.at(activeIndex);
if (featureDisplayState === 'text') {
activeFeature = mapFeatures.textFeatures.at(activeIndex);
Expand All @@ -184,10 +194,6 @@ export function ListingsMap(props: ListingsMapInterface) {
const hoveredFeature = hoveredFeatures.at(hoveredFeatures.length - 1) as Feature;
const hoveredIndex = NumberUtils.toNumber(hoveredFeature.getId(), -1)

// TODO: Display popup/banner of listing card
// 1. https://openlayers.org/en/latest/examples/overlay.html (HTML only)
// 2. https://openlayers.org/en/latest/examples/popup.html (Bootstrap)
// 3. https://openlayers.org/en/latest/examples/select-features.html
if (hoveredIndex !== activeIndex) {
activeIndex = hoveredIndex
const activeFeature = mapFeatures.activeFeatures.at(activeIndex);
Expand All @@ -200,10 +206,42 @@ export function ListingsMap(props: ListingsMapInterface) {
})
})

// TODO: Display popup/banner of listing card
// 2. https://openlayers.org/en/latest/examples/popup.html (HTML only)
// 3. https://openlayers.org/en/latest/examples/select-features.html
map.on('click', (e) => {
if (activeIndex >= 0) {
// Change content
const content = document.getElementById('popup-content')!;
content.innerHTML = '<p>You clicked here:</p><code>' + props.listings.at(activeIndex)?.id + '</code>';

// Set overlay's element and position
const container = document.getElementById('popup')!;
overlay.setElement(container);
overlay.setPosition(e.coordinate);

const closer = document.getElementById('popup-closer')!;
closer.onclick = function () {
overlay.setPosition(undefined);
return false;
};
}
})

return () => map.dispose()
}, [])

return (
<div id="map" className="basis-1/2 w-full h-full" tabIndex={0} />
<div className="basis-1/2 w-full h-full">
<div id="map" className="basis-1/2 w-full h-full" tabIndex={0} />
<div id="popup"
className="absolute bg-slate-50 shadow-sm shadow-slate-50/20 p-4 rounded-xl
border-[1px] border-gray-300 border-solid bottom-3 -left-12 min-w-[280px]">
<a href="#"
id="popup-closer"
className="no-underline absolute top-1 right-2">X</a>
<div id="popup-content" />
</div>
</div>
)
}

0 comments on commit 0cb1e14

Please sign in to comment.