玩命加载中 . . .

Hexo Matery text 页面添加 Canvas 彩色粒子上升特效教程


一、改造前后对比

对比项 改造前 改造后
特效层数 1 层(CSS 荧光绿气泡) 2 层(CSS 气泡 + Canvas 彩色粒子)
粒子颜色 荧光绿 rgba(128,255,0,0.7) 新增随机彩色(不透明)
技术方案 CSS @keyframes + jQuery DOM 新增 Canvas 2D + requestAnimationFrame

改造后 /text/ 页面拥有双层粒子效果:底层荧光绿 CSS 气泡 + 顶层 Canvas 随机彩色粒子。


二、修改文件

1
themes/hexo-theme-matery/layout/page.ejs

page.ejs 是 Hexo Matery 主题的通用页面模板,所有 layout: "page" 的页面都使用它(包括 /text/)。


三、实现思路

3.1 包裹容器

<div id="page-canvas-wrap"> 包裹整个 <main> 内部内容,作为 Canvas 的定位参照:

1
2
3
4
5
6
<main class="content">
<div id="page-canvas-wrap" style="position: relative; overflow: hidden;">
<!-- 原有内容(卡片 + CSS 气泡)全部在此内部 -->
</div>
<!-- Canvas 粒子脚本在包裹容器之后 -->
</main>
样式 作用
position: relative 让 Canvas 的 absolute 定位相对于内容区
overflow: hidden 防止粒子飞出内容区边界

3.2 Canvas 覆盖层

在包裹容器上动态创建 Canvas,绝对定位在内容之上:

1
2
3
4
5
canvas.style.position = 'absolute';
canvas.style.left = '0';
canvas.style.top = '0';
canvas.style.pointerEvents = 'none'; // 鼠标事件穿透
canvas.style.zIndex = '1'; // 在内容之上

pointerEvents: none 确保用户仍可正常点击链接、选择文本、播放视频。


四、Canvas 粒子核心代码

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
(function(){
var container = document.getElementById('page-canvas-wrap');
if (!container) return;
var width = container.offsetWidth;
var height = container.offsetHeight;

// 创建 Canvas
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
canvas.style.position = 'absolute';
canvas.style.left = '0';
canvas.style.top = '0';
canvas.style.pointerEvents = 'none';
canvas.style.zIndex = '1';
container.appendChild(canvas);

var ctx = canvas.getContext('2d');
var circles = [];
var density = 0.3; // 粒子密度
var radius = 10; // 粒子半径
var clearOffset = 0.9; // 初始生命值范围

// 随机彩色(不透明)
function randomColor() {
var r = Math.floor(Math.random() * 255);
var g = Math.floor(Math.random() * 255);
var b = Math.floor(Math.random() * 255);
return 'rgba(' + r + ',' + g + ',' + b + ',1)';
}

// 粒子对象
function Circle() {
this.init = function() {
this.x = Math.random() * width;
this.y = height + Math.random() * 100;
this.alpha = 0.1 + Math.random() * clearOffset;
this.scale = 0.1 + Math.random() * 0.3;
this.speed = Math.random();
this.color = randomColor();
};
this.draw = function() {
if (this.alpha <= 0) this.init();
this.y -= this.speed;
this.alpha -= 0.0001; // 最慢衰减 = 最高上升
ctx.beginPath();
ctx.arc(this.x, this.y, this.scale * radius, 0, 2 * Math.PI, false);
ctx.fillStyle = this.color;
ctx.fill();
ctx.closePath();
};
this.init();
}

for (var i = 0; i < width * density; i++) {
circles.push(new Circle());
}

function animate() {
ctx.clearRect(0, 0, width, height);
for (var j = 0; j < circles.length; j++) {
circles[j].draw();
}
requestAnimationFrame(animate);
}

// 响应式
window.addEventListener('resize', function() {
width = container.offsetWidth;
height = container.offsetHeight;
canvas.width = width;
canvas.height = height;
});

animate();
})();

五、参数与主页一致性对照

参数 主页 index.ejs text 页面 page.ejs 说明
颜色模式 'random' randomColor() 随机 RGB
alpha 1 1 完全不透明
density 0.3 0.3 每像素宽度生成 0.3 个粒子
radius 10 10 最大半径 10px
clearOffset 0.9 0.9 alpha 范围 0.1~1.0
alpha 衰减 0.0001 0.0001 最长寿命 ~167 秒

六、双层特效共存原理

/text/ 页面现在有两层粒子同时运行:

1
2
3
4
5
6
7
8
┌─────────────────────────────────┐
│ Canvas 彩色粒子(z-index: 1) │ ← 随机彩色,不透明
│ pointerEvents: none │
├─────────────────────────────────┤
│ 页面内容(卡片、文本、图片、视频) │ ← 用户可正常交互
├─────────────────────────────────┤
│ CSS 荧光绿气泡(position: relative)│ ← rgba(128,255,0,0.7)
└─────────────────────────────────┘
  • Canvas 层position: absolute + zIndex: 1,浮在最上方
  • 内容层:正常文档流,可交互(Canvas 的 pointerEvents: none 保证穿透)
  • CSS 气泡层position: relative,跟随文档流

两层粒子的颜色、大小、速度、方向各自独立,视觉上形成丰富的多层动态效果。


七、自定义调参

效果 修改位置 示例
只要 Canvas 彩色粒子,去掉 CSS 气泡 删除 page-bubbles 相关 CSS 和 HTML
只要 CSS 气泡,去掉 Canvas 粒子 删除 page-canvas-wrap 和对应 <script>
Canvas 粒子更多 density = 0.6 粒子数翻倍
Canvas 粒子更大 radius = 20 最大 20px
Canvas 粒子半透明 return 'rgba('+r+','+g+','+b+',0.5)' 50% 透明
CSS 气泡改成彩色 background-color: hsl(var(--hue),100%,50%) 需配合 JS 随机
上升更快 this.speed = Math.random() * 3 速度提升 3 倍

八、同一模式已应用的页面汇总

页面 文件 Canvas 彩色粒子 CSS 气泡
主页轮播区 index.ejs circleMagic()
/text/ 页面 page.ejs page-canvas-wrap page-bubbles
/musics/ 音乐区 musics.ejs music-bubbles
/musics/ 留言区 musics.ejs musics-twikoo-wrap
文章封面 post-cover.ejs bubbles-cover
文章正文 post.ejs bubbles
通用封面 bg-cover.ejs bubbles-bg

Author: 500饭
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source 500饭 !
留言互动
Powered by Twikoo
评论互动
- 条评论
 Previous
Hexo Matery 修改导航菜单名称教程 Hexo Matery 修改导航菜单名称教程
修改 Hexo Matery 主题导航栏菜单项的显示名称,以将 /musics/ 页面的菜单名从 Musics 改为 liuyan 为例。
2026-04-16
Next 
Hexo Matery 留言区添加 Canvas 彩色粒子上升特效教程 Hexo Matery 留言区添加 Canvas 彩色粒子上升特效教程
将主页轮播区的 Canvas 彩色粒子上升特效移植到 musics 页面的 Twikoo 留言区,不影响公共模板,不干扰留言操作。
2026-04-16
  TOC
过节
福到
小程序