Hexo Hiker 主题:用 TagCloud.js 做 3D 标签云

标签页原来会把每个标签下面的文章全部展开。标签涨到两百多个之后,页面先是一长串标签,再接上一长串文章列表,翻下去很累。点某个标签本来就有独立页(/tags/Python/ 这种),总览页没必要再把文章重复列一遍。

这次把 themes/hiker/layout/tags.ejs 收成一个球面标签云:全部标签都在球面上,字号按文章数加权,点击跳到该标签的文章页。用的是 TagCloud.js(CodeBlanks 的 3D Tag Cloud 也是这套库),大约 7KB,不依赖 jQuery。

为什么不用 Canvas 版 TagCanvas

中间试过 TagCanvas。效果是 3D 的,但转得快,标签叠在一起发晕;更麻烦的是独立版 TagCanvas.Start() **成功时返回 undefined,失败才返回 false**。

当时用了 if (!started) 判断失败,成功也被当成失败,canvas 容器被 display: none 藏掉,页面上什么都没有。改成只在 started === false 时降级之后才能看见球体。

即便修完,旋转仍然偏晕,所以换成 TagCloud.js,并把速度设成 slow。

页面上只留标签,不留文章列表

tags.ejs 里用 JSON 把名称、链接和文章数交给前端。useHTML: true 时,数组里的每一项可以是一段 HTML,这样标签本身就是 <a>,点下去就是标签页。

1
2
3
<script type="application/json" id="tag-cloud-data"><%- JSON.stringify(tagData) %></script>
<script src="<%- config.root %>js/TagCloud.min.js?v=2.5.0"></script>
<script src="<%- config.root %>js/tag-cloud.js?v=3.0.0" defer></script>

tagData 在模板里从 site.tags 收集:name、url_for(tag.path)、count(tag.length)。按文章数从多到少排,热门标签字号更大,范围大约 11px 到 19px,不要拉得太开,否则球心会糊成一团。

初始化:

1
2
3
4
5
6
7
8
TagCloud(root, texts, {
radius: getRadius(),
maxSpeed: 'slow',
initSpeed: 'slow',
direction: 135,
keep: true,
useHTML: true
});

keep: true 表示鼠标移开后继续慢慢转,而不是突然停住。direction: 135 是初始朝右下。半径按视口收:手机约 110,平板约 150,桌面约 260。resize 时先 destroy() 再按新半径重建,横竖屏切换不用手动刷新。

容器加上 touch-action: none,手指在球上滑动时不会把整页一起拖走。

一个容易踩的返回值

如果以后又换回 TagCanvas,失败判断要写成:

1
2
3
4
var started = TagCanvas.Start(canvasId, listId, options);
if (started === false) {
// 只有明确失败才隐藏 canvas、改成普通标签列表
}

!started 会把 undefined 也算失败。

和原来列表页的差别

  • 总览页不再按标签重复列出文章,高度固定在一块区域里(桌面大约 460px)。
  • 全部标签都在球面上,不会因为 max-height + 滚动把后面的标签裁掉。
  • 文章数多的标签更大;点击进入 /tags/<name>/,不在本页锚点展开。
  • 库加载失败时,同一份数据落到一个普通的换行标签列表,避免空白页。

本地看效果:hexo s 后打开 /tags/,鼠标或手指带动球体,点一个标签应进入对应文章列表。

Notice: 正常情况下,这里会有一个基于utteranc.es的留言系统,如果看不到,可能要想想办法才能看到。

Powered by Hexo and Hexo-theme-hiker

Copyright © 2012 - 2026 tiaobug.com All Rights Reserved.

鲁ICP备2024124237号-1