← All writing

Hexo blog adds interactive trail map

This article will show you how to create an interactive world map page in your GitHub Pages blog based on Hexo and Next. This map will display the cities you have visited. You can display different colored markers on the map based on the frequency of your visits to each city. You can also click on these markers to display more information about the city.

阅读中文版 →

Add an interactive trail map to your blog

This article will show you how to create an interactive world map page in your GitHub Pages blog based on Hexo and Next. This map will display the cities you have visited. You can display different colored markers on the map based on the frequency of your visits to each city. You can also click on these markers to display more information about the city.

Preparation

You need to install the following tools:

  • Node.js and NPM
  • Hexo

Make sure your blog has been deployed to GitHub Pages and that your local development environment has been set up correctly.

Step 1: Create a new page

In the root directory of your Hexo project, run the following command:

1
hexo new page "travel"

This command will be insourceCreate a folder named "travel" in the directory and create aindex.mdfile.

Step 2: Install Leaflet

In the root directory of your Hexo project, run the following command:

1
npm install leaflet

then inindex.mdThe top of the file introduces Leaflet’s CSS and JS:

1
2
3
4
5
6
7
8
9
---
title: Travel
---

<!-- 引入 Leaflet 的 CSS -->
<link rel="stylesheet" href="/node_modules/leaflet/dist/leaflet.css" />

<!-- 引入 Leaflet 的 JavaScript 文件 -->
<script src="/node_modules/leaflet/dist/leaflet.js"></script>

Step 3: Create a map container

inindex.md, create a map to host the<div>element and then set an explicit height to it via CSS:

1
2
3
4
5
6
7
8
9
<style>
#map {
height: 500px;
width: 100%;
position: relative;
}
</style>

<div id="map"></div>

Step 4: Initialize the map

Initialize the map using Leaflet's API and set its center to longitude 0, latitude 0 (mid-Atlantic), and set the initial zoom level to 2.

1
2
3
4
5
6
7
8
9
<script>
document.addEventListener('DOMContentLoaded', function() {
var map = L.map('map').setView([0, 0], 2);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
}).addTo(map);
});
</script>

Step 5: Add city data

Create a GeoJSON file to store city data, including the city's name, latitude and longitude, the number of times you have visited, and a URL to an image. The format of the file should be as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"name": "北京",
"visits": 3,
"image": "https://your-image-url.com"
},
"geometry": {
"type": "Point",
"coordinates": [116.4074, 39.9042]
}
},
...
]
}

Save this file in your Hexo projectsourcedirectory, for example, you could name itcities.json

Step 6: Load the data and display it on the map

inindex.mdfile, add the following code to load the GeoJSON file and then display the data on the map:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<script>
document.addEventListener('DOMContentLoaded', function() {
var map = L.map('map').setView([0, 0], 2);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
}).addTo(map);

fetch('/travel/cities.json')
.then(response => response.json())
.then(data => {
L.geoJSON(data, {
pointToLayer: function (feature, latlng) {
var color = getColor(feature.properties.visits);
return L.circleMarker(latlng, { fillColor: color, fillOpacity: 0.5 });
},
onEachFeature: function (feature, layer) {
layer.bindPopup(`<h2>${feature.properties.name}</h2><img src="${feature.properties.image}" width="200">`);
}
}).addTo(map);
});

function getColor(visits) {
// 根据你访问的次数返回不同的颜色
return visits > 10 ? '#800026' :
visits > 5 ? '#BD0026' :
visits > 2 ? '#E31A1C' :
visits > 1 ? '#FC4E2A' :
'#FFEDA0';
}

// 强制Leaflet重新计算地图的尺寸
setTimeout(function() {
map.invalidateSize();
}, 100);
});
</script>

The above JavaScript code will run after the page is loaded. It first initializes the map, then loads and parses the GeoJSON file. For each city, a circular marker is created, with the color determined based on the number of visits. When the marker is clicked, a window pops up with the city name and picture.

At this point, your blog has successfully added an interactive footprint map page.