Closed lisaschumann closed 1 year ago
I am not sure how you could hide popups with mapbox, so you will have to do some research there.
To access popups & markers, there are the useMapboxMarker
& useMapboxPopup
composable. You will just need to pass in their respective id (make sure each one has a unique id, and for the popup component it should be popup-id instead of pop-id).
See #38 for adding html events.
I had the same issue, definitely possible through using the mapbox api. I used the plugin but was mainly using the api directly:
const mapData = useCleanUpGQL(data?.value.data.page)
const mapBoxData =
mapData.map(venue => {
return {
'type': 'Feature',
'properties': {
'details': {
'title': venue.venueName,
'description': venue.description.text,
'url': venue.urlSlug,
'logo': {
'url': venue.logo.url,
'alt': venue.logo.altText,
'title': venue.logo.imageTitle,
},
'events': venue.venueEvents
}
},
'icon': 'profile-logo',
'geometry': {
'type': 'Point',
'coordinates': [
venue.venueAddress.geoCoordinates.longitude,
venue.venueAddress.geoCoordinates.latitude
]
}
}
});
const mapBoxLayer = {
'type': 'FeatureCollection',
'features':
mapBoxData
}
const {getWeekDay, getDay, nth} = useDateFormatter()
useMapboxBeforeLoad('IBWVenues', (map)=>{
map.on('load', () => {
map.loadImage(
'../map-icon.png',
(error, image) => {
if (error) throw error;
// Add the image to the map style.
map.addImage('IBW', image);
map.addSource('pubs', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features':
mapBoxData
}
});
// Add a layer showing the places.
map.addLayer({
'id': 'pubs',
'type': 'symbol',
'source': 'pubs',
'layout': {
'icon-image': 'IBW', // reference the image
'icon-size': .25,
'icon-anchor': 'bottom'
}
});
})
// When a click event occurs on a feature in the places layer, open a popup at the
// location of the feature, with description HTML from its properties.
map.on('click', 'pubs', (e) => {
// Copy coordinates array.
const coordinates = e.features[0].geometry.coordinates.slice();
const details = JSON.parse(e.features[0].properties.details);
let events = ''
const t = ()=> details.events.forEach(event => {
events = events + `<a class='eventLink' href="${event.urlSlug}" title="Link to ${event.eventName} page">
<span class="eventName">${event.eventName}</span> <span>${getWeekDay(event.eventStartDateTime)} ${getDay(event.eventStartDateTime)} ${nth(event.eventStartDateTime)}</span>
</a>`
});
t()
console.log(events)
const popupTemp = `
<div class="popupContent">
<a href="${details.url}" title="Link to ${details.title} page">
<img src="${details.logo.url}" alt="${details.logo.alt}" title="${details.logo.title}">
</a>
<h3>About ${details.title}</h3>
<p>${details.description.slice(0,200)}...</p>
<h3>${details.events?.length > 1 ? 'Events' : 'Event'}</h3>
${events}
</div>
`
// Ensure that if the map is zoomed out such that multiple
// copies of the feature are visible, the popup appears
// over the copy being pointed to.
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}
defineMapboxPopup('any', {closeButton: false, maxWidth: 'none', offset: 5, anchor: 'bottom' } );
useMapboxPopup('any', (popup)=>{
popup.setLngLat(coordinates).setHTML(popupTemp).addTo(map);
})
});
// Change the cursor to a pointer when the mouse is over the places layer.
map.on('mouseenter', 'pubs', () => {
map.getCanvas().style.cursor = 'pointer';
});
// Change it back to a pointer when it leaves.
map.on('mouseleave', 'pubs', () => {
map.getCanvas().style.cursor = '';
});
});
})
Not the most elegant solution but works for what I need. Would be amazing if this sort of feature could be more baked in to the plugin.
Used these two articles for the code:
useMapboxPopup(`popup-${index}`, (popup) => {
popup.remove()
})
Anybody has been able to solve this?
Hi there!
Thanks so much for such a great integration! A question on the popups; how do I hide them on initial load? They currently all display at once when the map loads.
Also, how do I target a marker individually and call a function on that marker click. In the mapbox docs I found you can target them each by their ID, but not sure how to retrieve that as with nuxt-mapbox are nested within HTML markup and not initiated like you would do while using mapbox directly.
Many thanks in advance for your help.