📢 新文章推送 · 每周更新优质内容 · 订阅更新 →
向下滚动
游戏娱乐

屏幕特效页面实现:14种全屏趣味效果

AI 智能总结

概述

Lumin 博客在 探索 菜单下新增了 屏幕特效 页面,提供 14 种全屏趣味效果,涵盖恶作剧、屏保、助眠等场景。本文详解完整的实现方案,包括 Fullscreen API 全屏控制、Canvas 2D 动画渲染、Web Audio API 噪音生成等核心技术。

架构设计

1hugo.toml                                    → 菜单注册(探索 → 屏幕特效,weight=28)
2content/screeneffects/_index.md              → 页面元数据(type=screeneffects)
3layouts/screeneffects/single.html            → 单页模板(内联 CSS + JS)
4layouts/_default/baseof.html                 → noSidebar 列表添加 screeneffects
5assets/css/main.css                          → :has(#screeneffects-page) 全宽布局选择器
6layouts/index.html                           → 首页排除 screeneffects 类型

采用 Hugo 的 Content Type 模式,所有效果逻辑内联在模板中,无需后端 API。

全屏机制

Fullscreen API

点击效果卡片时,先渲染效果内容,再请求浏览器全屏:

 1function requestFS(el){
 2  if(el.requestFullscreen) return el.requestFullscreen();
 3  if(el.webkitRequestFullscreen) return el.webkitRequestFullscreen();
 4  if(el.msRequestFullscreen) return el.msRequestFullscreen();
 5  return Promise.resolve();
 6}
 7
 8function showEffect(name){
 9  // 1. 渲染效果到 overlay
10  overlay.style.display = 'block';
11  overlay.className = 'se-overlay active';
12
13  // 2. 渲染具体效果
14  effectBSOD(); // 或其他效果
15
16  // 3. 延迟请求全屏(需要元素已在 DOM 中)
17  setTimeout(function(){
18    requestFS(overlay).catch(function(){});
19  }, 50);
20}

关键点:全屏请求的目标是 overlay 自身而非 documentElement,这样全屏后只显示效果内容。

退出全屏

三种退出方式:

 1// 1. ESC 键
 2document.addEventListener('keydown', function(e){
 3  if(e.key === 'Escape' && currentEffect) exitEffect();
 4});
 5
 6// 2. 浏览器原生退出全屏事件
 7document.addEventListener('fullscreenchange', function(){
 8  if(!document.fullscreenElement && currentEffect) exitEffect();
 9});
10
11// 3. 双击退出
12overlay.addEventListener('dblclick', function(){
13  if(currentEffect) exitEffect();
14});

退出时需要清理所有动画帧、定时器和音频:

1function exitEffect(){
2  animFrames.forEach(function(id){ cancelAnimationFrame(id); });
3  animFrames = [];
4  intervals.forEach(function(id){ clearInterval(id); });
5  intervals = [];
6  if(noiseNode){ try{ noiseNode.stop(); }catch(e){} noiseNode = null; }
7  // 退出浏览器全屏
8  if(document.fullscreenElement) document.exitFullscreen();
9}

14 种效果实现

1. 经典蓝屏(BSOD)

模拟 Windows 10/11 蓝屏死机界面,包含 :( 表情、错误代码、QR 码占位和进度百分比:

1var codes = ['CRITICAL_PROCESS_DIED','SYSTEM_THREAD_EXCEPTION_NOT_HANDLED',
2             'IRQL_NOT_LESS_OR_EQUAL','PAGE_FAULT_IN_NONPAGED_AREA'];
3var code = codes[Math.floor(Math.random()*codes.length)];

进度百分比每 900ms 随机递增,模拟"收集错误信息"过程。

2. Windows 更新

蓝色背景 + 旋转加载图标 + 进度条,关键细节:进度停在 97% 不再增长,模拟真实 Windows 更新卡住的体验:

1var iv = setInterval(function(){
2  if(pct < 97){
3    pct += Math.floor(Math.random()*3)+1;
4    if(pct > 97) pct = 97;  // 永远到不了 100%
5  }
6  if(pct >= 97) clearInterval(iv);
7}, 500);

3. macOS 更新

黑色背景 + Apple 图标 + 白色进度条 + 剩余时间倒计时,与真实 macOS 更新界面一致。

4. 黑客帝国数字雨

这是最复杂的效果之一,需要实现慢速下落 + 尾迹渐隐。

数据模型

每列维护一个独立的"流"对象:

1streams[i] = {
2  y: Math.random() * H / fontSize * -1,  // 从屏幕上方随机位置开始
3  speed: 0.3 + Math.random() * 0.5,       // 慢速下落(0.3-0.8)
4  trailLen: 12 + Math.floor(Math.random() * 18)  // 尾迹长度 12-30
5};

渲染流程

 1function draw(){
 2  // 半透明黑色覆盖,产生渐隐效果
 3  ctx.fillStyle = 'rgba(0,0,0,0.06)';
 4  ctx.fillRect(0, 0, W, H);
 5
 6  for(var i = 0; i < columns; i++){
 7    var s = streams[i];
 8
 9    // 隔帧移动,控制速度
10    if(frameCount % 2 === 0 || s.speed > 0.6){
11      s.y += s.speed;
12    }
13
14    // 头部字符 - 白色高亮 + 绿色发光
15    ctx.fillStyle = '#fff';
16    ctx.shadowColor = '#00ff41';
17    ctx.shadowBlur = 8;
18    ctx.fillText(headCh, x, y);
19    ctx.shadowBlur = 0;
20
21    // 尾迹字符 - 从亮绿到暗绿渐隐
22    for(var t = 1; t <= s.trailLen; t++){
23      var alpha = 1 - (t / s.trailLen);
24      var green = Math.floor(180 + 75 * alpha);
25      ctx.fillStyle = 'rgba(0,' + green + ',65,' + (alpha * 0.7) + ')';
26      ctx.fillText(tch, x, ty);
27    }
28  }
29}

关键优化:

  • rgba(0,0,0,0.06) 覆盖产生自然渐隐,上方字符逐步变黑消失
  • 头部白色 + shadowBlur 产生发光效果
  • 尾迹从亮绿 rgba(0,255,65,0.7) 渐变到暗绿 rgba(0,180,65,0.05)
  • 每列独立速度,视觉上更自然

5. 黑客终端

逐字打字动画,支持多种颜色类型:

1var lines = [
2  {t:'prompt', v:'root@kali:~# nmap -sV -sC --script=vuln 192.168.1.0/24'},
3  {t:'output', v:'Starting Nmap 7.94 at 2026-06-03 22:15 CST'},
4  {t:'warn',   v:'VULNERABLE: SQL Injection in /api/users'},
5  {t:'success',v:'Access granted. Welcome to Ubuntu 22.04 LTS'},
6  {t:'error',  v:'████ SYSTEM FULLY COMPROMISED ████'},
7];

CSS 类控制颜色:.se-hacker-prompt(暗绿)、.se-hacker-output(绿色)、.se-hacker-warn(黄色)、.se-hacker-error(红色)、.se-hacker-success(青绿)。

6. 睡眠白噪音

Canvas 绘制静态噪点 + Web Audio API 生成三种噪音:

噪音类型算法听感
白噪音Math.random() * 2 - 1嘶嘶声,均匀频谱
棕噪音布朗运动:(last + 0.02 * w) / 1.02低沉轰鸣
粉噪音Voss-McCartney 滤波器自然雨声
1// 棕噪音生成
2var last = 0;
3for(var i = 0; i < bufferSize; i++){
4  var w = Math.random() * 2 - 1;
5  data[i] = (last + 0.02 * w) / 1.02;
6  last = data[i];
7  data[i] *= 3.5;  // 增益补偿
8}

按钮切换时需要 stopPropagation() 防止触发 overlay 的退出事件。

7. FBI 锁定屏幕

DOJ 徽章 + 红色标题 + 法律条文,底部添加免责声明。

8. 碎屏效果

Canvas 递归裂纹算法:

 1function drawCrack(sx, sy, angle, length, depth){
 2  if(depth <= 0 || length < 5) return;
 3  var ex = sx + Math.cos(angle) * length;
 4  var ey = sy + Math.sin(angle) * length;
 5  ctx.beginPath();
 6  ctx.moveTo(sx, sy);
 7  ctx.lineTo(ex, ey);
 8  ctx.strokeStyle = 'rgba(255,255,255,' + (0.15 + depth * 0.08) + ')';
 9  ctx.lineWidth = depth * 0.8;
10  ctx.stroke();
11  // 递归分支
12  for(var i = 0; i < Math.floor(Math.random()*3)+1; i++)
13    drawCrack(ex, ey, angle + (Math.random()-0.5)*1.2,
14              length*(0.4+Math.random()*0.4), depth-1);
15}

从中心点辐射 6-10 条主裂纹,每条裂纹递归 5 层产生分支。配合冲击波圆环和中心亮点。

9. DVD 屏保

经典弹跳 Logo,碰壁换色 + 发光效果:

1if(hit){
2  ci = (ci + 1) % colors.length;
3  logo.style.color = colors[ci];
4  logo.style.textShadow = '0 0 20px ' + colors[ci] + ',0 0 40px ' + colors[ci];
5}
6logo.style.left = x + 'px';
7logo.style.top = y + 'px';

10. CRT 显示器

三层叠加实现复古 CRT 效果:

  1. Canvas 层:绿色磷光 DOS 启动文字,逐行输出
  2. 扫描线层:CSS repeating-linear-gradient 实现 3px 间距的水平线
  3. 暗角层:CSS radial-gradient 模拟 CRT 边缘变暗
  4. 闪烁层:CSS animation 模拟微弱闪烁
 1.se-crt-scanlines{
 2  background: repeating-linear-gradient(
 3    0deg,
 4    rgba(0,0,0,.15) 0px,
 5    rgba(0,0,0,.15) 1px,
 6    transparent 1px,
 7    transparent 3px
 8  );
 9}
10.se-crt-vignette{
11  background: radial-gradient(ellipse at center, transparent 60%, rgba(0,0,0,.7) 100%);
12}

Canvas 使用 rgba(0,10,0,0.01) 衰减模拟磷光余辉。

11. 故障效果(Glitch)

Canvas 实现赛博朋克故障艺术:

  • 随机色块:红/青色半透明矩形
  • 水平位移getImageData + putImageData 实现条纹错位
  • 噪点块:随机像素填充
  • RGB 分离文字:同一文字用红/青色偏移绘制
1// 水平位移条纹
2var sliceY = Math.random() * H;
3var sliceH = Math.random() * 30 + 5;
4var shift = (Math.random() - 0.5) * 60;
5var imgData = ctx.getImageData(0, sliceY, W, sliceH);
6ctx.putImageData(imgData, shift, sliceY);

12. 星空穿越

3D 透视投影 + 速度拖尾:

 1// 3D → 2D 投影
 2var sx = (s.x / s.z) * W/2 + cx;
 3var sy = (s.y / s.z) * H/2 + cy;
 4var r = Math.max(0.5, (1 - s.z/W) * 3);  // 近大远小
 5
 6// 拖尾线条
 7var prevZ = s.z + speed;
 8var psx = (s.x / prevZ) * W/2 + cx;
 9var psy = (s.y / prevZ) * H/2 + cy;
10ctx.beginPath();
11ctx.moveTo(psx, psy);
12ctx.lineTo(sx, sy);

600 颗星从中心向外飞散,z 坐标递减模拟接近效果。

13. 火焰效果

经典 DOOM 火焰算法,基于像素传播 + 衰减:

 1// 底部随机火源
 2for(var x = 0; x < W; x++){
 3  firePixels[(H-1)*W+x] = Math.random() > 0.4 ?
 4    Math.floor(Math.random()*160)+96 : 0;
 5}
 6
 7// 向上传播 + 衰减
 8for(var y = 0; y < H-1; y++){
 9  for(var x = 0; x < W; x++){
10    var src = ((y+1)*W) + ((x + Math.floor(Math.random()*3)-1+W) % W);
11    var val = firePixels[src] - Math.floor(Math.random()*3) - 1;
12    firePixels[y*W+x] = val > 0 ? val : 0;
13  }
14}

调色板从黑→红→橙→黄→白渐变,使用 4x 缩放降低计算量。

14. 假加载画面

旋转加载圈 + 进度条,永远到不了 100%

1if(pct >= 98 && Math.random() < 0.1){
2  itemIdx++;
3  pct = 96 + Math.floor(Math.random()*2);  // 回退到 96-97%
4}

循环切换 10 种加载提示文字,进度在 96-98% 之间反复跳动。

全宽布局集成

与像素画页面相同的集成方式:

1/* main.css */
2.main-wrapper:has(#screeneffects-page) {
3  padding: calc(var(--header-height) + 80px) 0 0 !important;
4}
1{{/* baseof.html */}}
2{{ $noSidebar := or ... (eq .Type "screeneffects") (eq .Type "error") }}

技术要点总结

技术应用场景
Fullscreen API全屏沉浸式体验
Canvas 2D数字雨/碎屏/CRT/故障/星空/火焰
Web Audio API白噪音/棕噪音/粉噪音生成
CSS animation旋转图标/光标闪烁/CRT扫描线
CSS :has()全宽布局选择器
requestAnimationFrame60fps 流畅动画
getImageData/putImageData故障效果水平位移
递归算法碎屏裂纹分支
3D 透视投影星空穿越
像素传播算法DOOM 火焰
7 / 9
版权声明

本文作者 Lumin

本文链接 https://www.zhengquan.xyz/game/screeneffects-implementation/

许可协议 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

请作者喝杯咖啡 ☕

  • 微信打赏
    微信支付
  • 支付宝打赏
    支付宝
点击按钮查看打赏二维码
🎁 推荐工具
试试这些实用在线工具,提升工作效率
前往工具集 →

留言评论

期待你的想法

评论加载中