基于高德地图实现 Hugo 足迹地图短代码

目录

依然是受 王叨叨:基于高德地图做足迹管理插件 文章启发,实在眼馋足迹功能,但苦于没有清晰的思路,看到叨叨大神发了这个插件,借助AI,终于抽空完成了这一功能,并融入了一些个人想法:

  1. 与站点主题同步,支持亮/暗模式自适应;
  2. 增加标签筛选功能;
  3. 在地图卡片中,若有多张图片,支持水平滚动并集成灯箱放大查看;
  4. 标记点智能集群,缩小地图时自动合并附近位置;
  5. 集群开关控制,可随时启用或关闭集群功能。

其余部分则为常规足迹功能的实现。

本文将简要介绍实现方式,完整的源码已在 GitHub 开源,包含所有 JS、CSS 和示例数据。具体样例在本站"关于"页面,如下所示:

正在加载足迹...

注:本项目已在 2025-11-19 开源,并新增了一个可在线访问的 可视化编辑器 ,便于交互式创建/编辑 locations 数据、导入示例/JSON、生成并下载 JSON 文件,以及即时预览地图效果。详见下方更新日志(2025-11-20 12:59)。

主要功能

  • 短代码嵌入{{< footprintmap >}} 自动注入脚本与样式,按需加载数据。
  • JSON 数据支持:所有足迹数据集中保存在 footprints.json 文件中,便于在 Git 里维护与复用。
  • 自动标签筛选:脚本会扫描全部 categories 字段,生成可点击的筛选按钮。
  • 智能标记集群:缩小地图时自动将附近位置合并显示,点击集群标记可放大查看详情。
  • 集群开关控制:地图底部提供开关按钮,支持亮/暗主题自动适配。
  • 文章关联:通过手动设置 url 字段,可添加关联的文章。
  • 照片轻量查看器:支持多张图的横向轮播,点击后用自定义 Viewer 放大,适配移动端手势。
  • 亮/暗主题联动:跟随站点 dark class 切换高德地图底图与 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"
    }
  ]
}

其中,坐标的选取可使用 高德地图坐标拾取器 或直接使用 小十足迹地图编辑器

字段对照表如下:

字段类型必填默认行为
namestring省略时使用“未命名地点”。
coordinatesstring支持 "经度,纬度" 字符串或 [lng,lat] 数组;无法解析则忽略该记录。
descriptionstring留空则不显示正文段落。
datestring解析成功时显示格式化日期,失败则隐藏。
urlstring默认不显示按钮;提供后渲染“查看相关内容”链接,可搭配 urlLabel
urlLabelstring自定义按钮文字,未提供时默认显示“查看相关内容”。
photosstring[]空数组只展示文字卡片;多张时启用轮播与 Viewer。
categoriesstring[]空数组会自动填充为 ['未分类']
markerColorstring未提供时自动分配线性渐变;可写预设名,也可写十六进制或 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
dataJSON 路径或外部 URL/data/footprints.json
key覆盖高德 Web JS API Keyparams.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。
  • 读取 JSONfetchLocations() 支持 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 开源,包含所有必需文件和详细文档。

  1. 准备数据:把示例 JSON 保存到 static/data/footprints.json,按需补充更多地点。
  2. 配置高德 Key:在 hugo.toml 中加入 params.amapKey = "你的 Web JS API Key"
  3. 引入资源:将短代码、footprintmap.js、相关 Sass 片段放入主题。
  4. 在文章或页面中插入短代码
{{< footprintmap height="560px" data="/data/footprints.json" >}}

更新日志

2025-11-20 12:59 v1.3

开源与编辑器:

  1. 项目开源:完整工程已托管至 GitHub,包含示例数据、文档与演示页面,欢迎社区复用与贡献。
  2. 新增可视化编辑器(editor.html):提供本地交互式数据编辑器,主要功能:
  • 地图拾取或手动输入经纬度;
  • 添加/编辑地点(名称、描述、日期、分类、图片、链接、标记颜色);
  • 导入 JSON 文件或一键导入仓库内示例数据(static/data/footprints.example.json);
  • 生成并下载符合格式的 JSON,支持复制到剪贴板;
  • 预览区即时渲染 FootprintMap(含聚类、筛选、主题同步);
  • 移动端友好调整与若干交互修复(按钮换行对齐、日期行一行展示、图片查看器与轮播优化等)。

编辑器截图:

FootprintMap 编辑器预览

2025-11-19 12:14 v1.2

优化改进:

  1. 地图交互优化

    • 限制地图为 2D 视图,禁用旋转和倾斜功能(viewMode: '2D', rotateEnable: false, pitchEnable: false
    • 仅保留平移(拖拽)和缩放功能,提升触控设备操作体验
    • 添加缩放工具条(ToolBar)到右上角,提供直观的缩放按钮
    • 添加比例尺(Scale)到右下角
  2. 代码大幅精简

    • JavaScript 优化:从 879 行精简到 475 行,减少 45.9%(403行)
    • 删除所有 console.log 调试语句
    • 移除未使用的函数:_renderMarker_renderClusterMarker
    • 移除冗余辅助函数,直接内联处理逻辑
    • 优化变量命名,简化常量定义
    • 合并重复的事件处理逻辑
    • CSS 优化:精简高德地图控件样式规则,从 74 行减少到 51 行,减少 31%
  3. 黑暗模式适配

    • 完善缩放控件的黑暗模式样式
    • 加减号按钮在黑暗模式下显示为白色,确保清晰可见
    • 按钮分隔线降低亮度(透明度 0.08),避免过于扎眼
    • 比例尺去掉背景框,白天和黑夜模式都只保留纯净的比例尺线条
    • 控件背景使用半透明深灰色(rgba(34, 26, 26, 0.9)),与主题风格统一

2025-11-18 23:33 v1.1

新增功能:

  1. 智能标记集群

    • 实现网格集群算法,当地图缩放级别 < 10 时,自动将距离较近的标记点合并显示
    • 集群标记显示包含的点数量,点击后自动放大地图查看详细标记
    • 采用 80px 网格大小进行集群计算,平衡性能与视觉效果
  2. 集群标记美化

    • 三档尺寸设计: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%透明),轻盈精致
    • 增强阴影效果,营造立体感
  3. 集群开关控制

    • 地图底部居中位置新增集群开关按钮
    • iOS风格滑动开关设计,支持一键开启/关闭集群
    • 开关状态实时生效,无需刷新页面
    • 使用 MutationObserver 监听主题切换,实时更新 UI
  4. 筛选与集群联动

    • 标签筛选功能与集群完全兼容
    • 筛选后自动基于过滤结果重新计算集群
    • 保留原始数据,筛选切换流畅无延迟
评论