lisablunt / lisablunt.github.io

My portfolio site.
https://lisablunt.github.io
1 stars 0 forks source link

Make map's sidebar nav links dynamic #7

Closed lisablunt closed 3 years ago

lisablunt commented 3 years ago

After merging '/map/index.html' with the Mapbox GL JS file '/map/map_GLJS.html', the sidebar navigation menu no longer appears. If the sidebar is rendered on the page, the links no longer correspond to their respective city coordinates and all popups are disabled:

Places I've Lived & Travelled map

The desired result is along the lines of @alulsh's map.

alulsh commented 3 years ago

Hi @lisablunt! I'm happy and honored that my project in https://github.com/alulsh/military-brat-map was helpful for you!

I took a look at your code in https://github.com/lisablunt/lisablunt.github.io/blob/master/map/index.html and I've got something working for you! First, here's a GIF of it working locally on my computer for proof:

Mar-28-2021 18-18-35

I am dropping two git diffs for index.html and map.js. I tried my best to preserve your code style and only make the bare minimum changes needed to get the map working again so that the changes I made are easy to spot.

index.html

I noticed in index.html that you have two Mapbox GL JS map divs - one at the top with an id of map-init and another after the body tag with an id of map. This was causing the sidebar not to load. I changed the class for the first div from map-init to map and deleted the other map div on line 68. Once I did that the sidebar loaded again!

I also deleted all of the JavaScript code from lines 70 through 290 and moved it to map.js.

For easier readability and maintainability, I also strongly recommend that you move the CSS in lines 56-66 into your styles.css file.

Here is the full diff for the changes I made to index.html in the details (click on the arrow to expand and view):

```diff diff --git a/map/index.html b/map/index.html index 311104c..13a9591 100644 --- a/map/index.html +++ b/map/index.html @@ -25,7 +25,7 @@ -
+
@@ -65,228 +65,4 @@ } -
- - - ```

map.js

I noticed there was still some Mapbox.js code in lines 1-4 and line 220, so I removed that code (the L in those lines of code refers to Leaflet, Mapbox.js is a Leaflet plugin). I then copied over your Mapbox GL JS code from index.html to map.js.

I created a new object called markerSource that references your marker object with all of the place GeoJSON data. You could optionally make this a single object like in this code if you prefer. Adding the layout properties allows the symbols to display on the map. I also had to change all of the marker-symbol properties to icon in markers for this to work, similar to this Mapbox GL JS example that uses Maki icons.

For the fly to a location functionality, I replaced map.setView() (an old Mapbox.js method) with the new flyTo() method. I also switched from marker.openPopup() (a Mapbox.js method) to new mapboxgl.Popup(). map.on('click') has a similar HTML pop up, you could use a function like this one to reduce duplication, but this is optional.

Here is the full diff in the details for my changes to map.js:

```diff diff --git a/map/map.js b/map/map.js index 8bdff46..28c6fff 100644 --- a/map/map.js +++ b/map/map.js @@ -1,12 +1,66 @@ -L.mapboxgl.accessToken = 'pk.eyJ1IjoiYWx1bHNoIiwiYSI6ImY0NDBjYTQ1NjU4OGJmMDFiMWQ1Y2RmYjRlMGI1ZjIzIn0.pngboKEPsfuC4j54XDT3VA'; -var map = L.mapboxgl.map('map-init', 'mapbox.streets', { zoomControl: false }) - .setView([38.898, -77.043], 3); -new L.Control.Zoom({ position: 'topright' }).addTo(map); +mapboxgl.accessToken = 'pk.eyJ1IjoibGJsdW50IiwiYSI6ImNraXpvNHExdDJ3dWwyemxyNWNjM3g0d3MifQ.yH2wO_GlcKmsvKQhBC2lUg'; + +var map = new mapboxgl.Map({ + container: 'map', + style: 'mapbox://styles/mapbox/streets-v11', +center: [-77.0369, 38.9072], + zoom: 2 +}); + +// Add zoom and rotation controls to the map. +map.addControl(new mapboxgl.NavigationControl()); + +map.on('load', function () { + map.addLayer(markerSource); + + // Change the cursor to a pointer when the mouse is over the places layer. + map.on('mouseenter', 'places', function () { + map.getCanvas().style.cursor = 'pointer'; + }); + + // Change it back to a pointer when it leaves. + map.on('mouseleave', 'places', function () { + map.getCanvas().style.cursor = ''; + }); + + // 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', 'places', function (e) { + var coordinates = e.features[0].geometry.coordinates.slice(); + var description = e.features[0].properties.description; + var title = e.features[0].properties.title; + + map.flyTo({ + center: e.features[0].geometry.coordinates + }); + + // 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; + } + + new mapboxgl.Popup() + .setLngLat(coordinates) + .setHTML('' + title + '

' + description + '

') + .addTo(map); +}); +}); + function fly(lat, long, title) { - map.setView([lat, long], 7); - placesLayer.eachLayer(function(marker){ - if(marker.feature.properties.title === title) { - marker.openPopup(); + map.flyTo({ + center: [long, lat], + zoom: 7, + essential: true, + }); + markers.features.forEach(function(marker){ + if(marker.properties.title === title) { + new mapboxgl.Popup() + .setLngLat([long, lat]) + .setHTML('' + marker.properties.title + '

' + marker.properties.description + '

') + .addTo(map); } }) } @@ -36,7 +90,7 @@ var markers = { 'type': 'Feature', 'properties': { 'title': 'Washington, DC', - 'marker-symbol': 'star', + 'icon': 'star', 'description': '1980s - Present
My birthplace and current city.' }, 'geometry': { @@ -51,7 +105,7 @@ var markers = { 'type': 'Feature', 'properties': { 'title': 'Providence, RI', - 'marker-symbol': 'college', + 'icon': 'college', 'description': 'Spring 2009
Graduated from Brown University.' }, 'geometry': { @@ -66,7 +120,7 @@ var markers = { 'type': 'Feature', 'properties': { 'title': 'New York, NY', - 'marker-symbol': 'library', + 'icon': 'library', 'description': 'Summer 2007
Interned with the books division of Sports Illustrated.' }, 'geometry': { @@ -81,7 +135,7 @@ var markers = { 'type': 'Feature', 'properties': { 'title': 'New Haven, CT', - 'marker-symbol': 'library', + 'icon': 'library', 'description': 'Summer 2008
Interned with the Publicity and Marketing departments of Yale University Press.' }, 'geometry': { @@ -96,7 +150,7 @@ var markers = { 'type': 'Feature', 'properties': { 'title': 'Sacramento, CA', - 'marker-symbol': 'pitch', + 'icon': 'pitch', 'description': 'Summer 2015
Attended the CHIMEHACK 2 hackathon at
Twitter HQ in SF.' }, 'geometry': { @@ -112,7 +166,7 @@ var markers = { 'type': 'Feature', 'properties': { 'title': 'Toronto, ON, CAN', - 'marker-symbol': 'suitcase', + 'icon': 'suitcase', 'description': '1988
My very first trip outside the U.S.' }, 'geometry': { @@ -127,7 +181,7 @@ var markers = { 'type': 'Feature', 'properties': { 'title': 'Montréal, QC, CAN', - 'marker-symbol': 'suitcase', + 'icon': 'suitcase', 'description': '1996
Visited as part of a penpal exchange with a local elementary school.' }, 'geometry': { @@ -142,7 +196,7 @@ var markers = { 'type': 'Feature', 'properties': { 'title': 'Québec, QC, CAN', - 'marker-symbol': 'suitcase', + 'icon': 'suitcase', 'description': '1996
Visited as part of a penpal exchange with a Montréal elementary school.' }, 'geometry': { @@ -158,7 +212,7 @@ var markers = { 'type': 'Feature', 'properties': { 'title': 'Hamilton, Bermuda', - 'marker-symbol': 'suitcase', + 'icon': 'suitcase', 'description': 'Summer 2013
Pastel houses, pink sand beaches, gorgeous sunsets... take me back!' }, 'geometry': { @@ -173,7 +227,7 @@ var markers = { 'type': 'Feature', 'properties': { 'title': 'London, UK', - 'marker-symbol': 'suitcase', + 'icon': 'suitcase', 'description': 'Winter 2015
Waved hello to the Queen, saw Big Ben, and visited nearby Stonehenge.' }, 'geometry': { @@ -188,7 +242,7 @@ var markers = { 'type': 'Feature', 'properties': { 'title': 'Paris, FR', - 'marker-symbol': 'suitcase', + 'icon': 'suitcase', 'description': 'Winter 2015
Ice skated at the Eiffel Tower, visited the Louvre, and ate too many macarons.' }, 'geometry': { @@ -203,7 +257,7 @@ var markers = { 'type': 'Feature', 'properties': { 'title': 'Amsterdam, NL', - 'marker-symbol': 'suitcase', + 'icon': 'suitcase', 'description': 'Winter 2015
The people here were very nice and accommodating to a sick traveller.' }, 'geometry': { @@ -217,6 +271,17 @@ var markers = { ] }; -var placesLayer = L.mapbox.featureLayer().setGeoJSON(markers).addTo(map); +var markerSource = { + 'id': 'places', + 'type': 'symbol', + 'source': { + 'type': 'geojson', + 'data': markers, + }, + layout: { + 'icon-image': '{icon}-15', + 'icon-allow-overlap': true + } +} loadPlaces(markers); ```

Switching from base to Assembly

I noticed that your project is using base.css from Mapbox. This is an old CSS framework (see the 2013 blog post) that was replaced by Assembly.

I just updated https://github.com/alulsh/military-brat-map today to switch from Base to Assembly. You can check out the changes I made for the migration in https://github.com/alulsh/military-brat-map/compare/66d6f44..9370a5d. You're welcome to copy this code and switch to Assembly if you want! There is a lot of documentation and examples for Assembly (there isn't any for Base anymore) so it's a lot easier to work with Assembly.

lisablunt commented 3 years ago

@alulsh Infinite thanks, Alex! Really appreciate the time you took to help resolve my issue.