基于高德地图实现 Hugo 足迹地图短代码
目录
依然是受 王叨叨:基于高德地图做足迹管理插件 文章启发,实在眼馋足迹功能,但苦于没有清晰的思路,看到叨叨大神发了这个插件,借助AI,终于抽空完成了这一功能,并融入了一些个人想法:
- 与站点主题同步,支持亮/暗模式自适应;
- 增加标签筛选功能;
- 在地图卡片中,若有多张图片,支持水平滚动并集成灯箱放大查看;
- 标记点智能集群,缩小地图时自动合并附近位置;
- 集群开关控制,可随时启用或关闭集群功能。
其余部分则为常规足迹功能的实现。
本文将简要介绍实现方式,完整的源码已在 GitHub 开源,包含所有 JS、CSS 和示例数据。具体样例在本站"关于"页面,如下所示:
注:本项目已在 2025-11-19 开源,并新增了一个可在线访问的 可视化编辑器 ,便于交互式创建/编辑
locations数据、导入示例/JSON、生成并下载 JSON 文件,以及即时预览地图效果。详见下方更新日志(2025-11-20 12:59)。
主要功能
- 短代码嵌入:
{{< footprintmap >}}自动注入脚本与样式,按需加载数据。 - JSON 数据支持:所有足迹数据集中保存在
footprints.json文件中,便于在 Git 里维护与复用。 - 自动标签筛选:脚本会扫描全部
categories字段,生成可点击的筛选按钮。 - 智能标记集群:缩小地图时自动将附近位置合并显示,点击集群标记可放大查看详情。
- 集群开关控制:地图底部提供开关按钮,支持亮/暗主题自动适配。
- 文章关联:通过手动设置
url字段,可添加关联的文章。 - 照片轻量查看器:支持多张图的横向轮播,点击后用自定义 Viewer 放大,适配移动端手势。
- 亮/暗主题联动:跟随站点
darkclass 切换高德地图底图与 InfoWindow 样式。 - 自定义 Marker 颜色:通过
markerColor选择预设(sunset/ocean/violet/forest/amber/citrus),也支持直接写#RRGGBB。 - 移动端优化:信息卡宽度移动端自适应、字号/间距重排、点击空白区域自动收起 InfoWindow。
JSON 数据格式
footprints.json 中维护一个 locations 数组,字段解释如下:
{
"locations": [
{
"name": "郑州",
"coordinates": "113.6254,34.7466",
"description": "长久扎根的城市,记录了无数启程与归来的故事。",
"date": "2011-02-02",
"url": "https://www.xxxx.com/post/2025/11/xxxx/",
"urlLabel": "阅读郑州故事",
"photos": [
"https://www.xiaoten.com/posts/2025/11/xxx/images/1.jpg",
"https://www.xiaoten.com/posts/2025/11/xxx/images/2.jpg"
],
"categories": ["2023", "家乡", "常驻"],
"markerColor": "sunset"
}
]
}
其中,坐标的选取可使用 高德地图坐标拾取器 或直接使用 小十足迹地图编辑器 。
字段对照表如下:
| 字段 | 类型 | 必填 | 默认行为 |
|---|---|---|---|
name | string | 否 | 省略时使用“未命名地点”。 |
coordinates | string | 是 | 支持 "经度,纬度" 字符串或 [lng,lat] 数组;无法解析则忽略该记录。 |
description | string | 否 | 留空则不显示正文段落。 |
date | string | 否 | 解析成功时显示格式化日期,失败则隐藏。 |
url | string | 否 | 默认不显示按钮;提供后渲染“查看相关内容”链接,可搭配 urlLabel。 |
urlLabel | string | 否 | 自定义按钮文字,未提供时默认显示“查看相关内容”。 |
photos | string[] | 否 | 空数组只展示文字卡片;多张时启用轮播与 Viewer。 |
categories | string[] | 否 | 空数组会自动填充为 ['未分类']。 |
markerColor | string | 否 | 未提供时自动分配线性渐变;可写预设名,也可写十六进制或 rgb() 值。 |
短代码实现
短代码文件位于 themes/xiaoten/layouts/shortcodes/footprintmap.html:
{{- $id := printf "footprintmap-%d" (now.UnixNano) -}}
{{- $height := .Get "height" | default "520px" -}}
{{- $data := .Get "data" | default "/data/footprints.json" -}}
{{- if and (not (hasPrefix $data "http")) (not (hasPrefix $data "//")) -}}
{{- $data = relURL $data -}}
{{- end -}}
{{- $key := .Get "key" | default .Site.Params.amapKey -}}
<div id="{{ $id }}" class="footprint-map" data-json="{{ $data }}" data-amap-key="{{ $key }}" style="height: {{ $height }};">
<div class="footprint-map__loading">正在加载足迹...</div>
{{- if not $key -}}
<div class="footprint-map__error">请在 <code>params.amapKey</code> 配置高德 Web JS API Key,或通过 <code>key</code> 覆盖。</div>
{{- end -}}
</div>
{{- if not (.Page.Scratch.Get "footprintmap-script") -}}
{{- .Page.Scratch.Set "footprintmap-script" true -}}
<script src="{{ "/js/footprintmap.js" | relURL }}" defer></script>
{{- end -}}
参数说明:
| 参数 | 说明 | 默认值 |
|---|---|---|
height | 地图容器高度 | 520px |
data | JSON 路径或外部 URL | /data/footprints.json |
key | 覆盖高德 Web JS API Key | params.amapKey |
class | 自定义附加 class | 空 |
小贴士:借助
class参数可以叠加外层样式,例如{{< footprintmap class="is-narrow" >}}搭配自定义媒体查询;Page.Scratch只会注入一次/js/footprintmap.js,因此同一页放置多个地图也不会重复加载脚本。
样式与交互
所有视觉都集中在 _custom.scss:
.footprint-map、.footprint-map__filters控制外框与筛选面板。.footprint-popup调整 InfoWindow 宽度、字号,桌面与移动端分别通过clamp()控制宽度。.amap-info-content/outer/inner统一设为透明,避免高德默认白色边框。.footprint-photo-viewer提供自定义遮罩与关闭按钮,避免引入第三方库。
Marker 预设目前包含六组渐变:
| 预设 | 色彩描述 | 颜色示例 |
|---|---|---|
sunset | 橙到红的暖色过渡 | |
ocean | 绿蓝相间的冷色 | |
violet | 紫色渐变 | |
forest | 蓝绿调 | |
amber | 琥珀色暖调 | |
citrus | 黄绿柑橘调 |
JavaScript 核心逻辑
主脚本 footprintmap.js 负责:
- 初始化地图:按需加载高德 SDK,自动共用同一个 Key。
- 读取 JSON:
fetchLocations()支持locations/points/ 纯数组三种格式。 - 数据清洗:
sanitizeLocations()负责校验经纬度、分类、日期、链接、Marker 颜色等字段。 - 渲染 Marker + InfoWindow:点击 Marker 会生成模板化的卡片,同时挂载照片轮播 & Viewer。
- 智能集群:
createClusters(zoom)使用网格算法(80px单元格)在缩放级别 < 10 时自动集群附近标记。 - 自动筛选:
renderFilters()会根据分类列表创建按钮,applyCategoryFilter()控制 Marker 显隐与视野,并与集群联动。 - 集群开关:
renderClusterToggle()创建底部居中的开关按钮,使用 MutationObserver 监听主题变化实现亮/暗模式自适配。 - 体验细节:
suppressNextMapClose避免 Marker 点击后被立即关闭。normalizeMarkerStyle()在 preset 失效时自动落回线性渐变与内联颜色。openPhotoViewer()/hidePhotoViewer()提供 ESC/遮罩关闭、禁止底层滚动。- 集群标记点击自动放大2级并居中显示。
接入步骤
💡 提示:完整源码已在 GitHub - XiaoTen-FootprintMap 开源,包含所有必需文件和详细文档。
- 准备数据:把示例 JSON 保存到
static/data/footprints.json,按需补充更多地点。 - 配置高德 Key:在
hugo.toml中加入params.amapKey = "你的 Web JS API Key"。 - 引入资源:将短代码、
footprintmap.js、相关 Sass 片段放入主题。 - 在文章或页面中插入短代码:
{{< footprintmap height="560px" data="/data/footprints.json" >}}
更新日志
2025-11-20 12:59 v1.3
开源与编辑器:
- 项目开源:完整工程已托管至 GitHub,包含示例数据、文档与演示页面,欢迎社区复用与贡献。
- 新增可视化编辑器(editor.html):提供本地交互式数据编辑器,主要功能:
- 地图拾取或手动输入经纬度;
- 添加/编辑地点(名称、描述、日期、分类、图片、链接、标记颜色);
- 导入 JSON 文件或一键导入仓库内示例数据(
static/data/footprints.example.json); - 生成并下载符合格式的 JSON,支持复制到剪贴板;
- 预览区即时渲染 FootprintMap(含聚类、筛选、主题同步);
- 移动端友好调整与若干交互修复(按钮换行对齐、日期行一行展示、图片查看器与轮播优化等)。
编辑器截图:

2025-11-19 12:14 v1.2
优化改进:
地图交互优化
- 限制地图为 2D 视图,禁用旋转和倾斜功能(
viewMode: '2D',rotateEnable: false,pitchEnable: false) - 仅保留平移(拖拽)和缩放功能,提升触控设备操作体验
- 添加缩放工具条(ToolBar)到右上角,提供直观的缩放按钮
- 添加比例尺(Scale)到右下角
- 限制地图为 2D 视图,禁用旋转和倾斜功能(
代码大幅精简
- JavaScript 优化:从 879 行精简到 475 行,减少 45.9%(403行)
- 删除所有
console.log调试语句 - 移除未使用的函数:
_renderMarker、_renderClusterMarker - 移除冗余辅助函数,直接内联处理逻辑
- 优化变量命名,简化常量定义
- 合并重复的事件处理逻辑
- CSS 优化:精简高德地图控件样式规则,从 74 行减少到 51 行,减少 31%
黑暗模式适配
- 完善缩放控件的黑暗模式样式
- 加减号按钮在黑暗模式下显示为白色,确保清晰可见
- 按钮分隔线降低亮度(透明度 0.08),避免过于扎眼
- 比例尺去掉背景框,白天和黑夜模式都只保留纯净的比例尺线条
- 控件背景使用半透明深灰色(rgba(34, 26, 26, 0.9)),与主题风格统一
2025-11-18 23:33 v1.1
新增功能:
智能标记集群
- 实现网格集群算法,当地图缩放级别 < 10 时,自动将距离较近的标记点合并显示
- 集群标记显示包含的点数量,点击后自动放大地图查看详细标记
- 采用 80px 网格大小进行集群计算,平衡性能与视觉效果
集群标记美化
- 三档尺寸设计:2-4个点(38px)、5-9个点(42px)、10+个点(46px)
- 渐变色彩方案:
- 小集群:青色渐变
linear-gradient(135deg, rgba(6,190,182,0.75), rgba(72,177,191,0.75)) - 中集群:海洋渐变
linear-gradient(135deg, rgba(94,231,223,0.75), rgba(6,190,182,0.75)) - 大集群:日落渐变
linear-gradient(135deg, rgba(255,179,71,0.75), rgba(255,111,97,0.75))
- 小集群:青色渐变
- 半透明效果(75%),让地图背景若隐若现
- 细边框设计(1px白色40%透明),轻盈精致
- 增强阴影效果,营造立体感
集群开关控制
- 地图底部居中位置新增集群开关按钮
- iOS风格滑动开关设计,支持一键开启/关闭集群
- 开关状态实时生效,无需刷新页面
- 使用 MutationObserver 监听主题切换,实时更新 UI
筛选与集群联动
- 标签筛选功能与集群完全兼容
- 筛选后自动基于过滤结果重新计算集群
- 保留原始数据,筛选切换流畅无延迟
© 转载需附带本文链接,依据 CC BY-NC-SA 4.0 发布。