前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎 点赞 + 收藏 + 关注 哦 💕

📚 运行

CSDN1024程序员节代码效果

📚 本文简介

本文将以一段1024程序员节主题的HTML代码为切入点,深入探讨代码背后的技术原理、艺术价值,以及程序员在数字时代的使命与担当。通过解析这段融合了视觉效果与交互体验的代码,我们不仅能够了解前端开发的相关技术,更能感受到程序员将逻辑思维转化为视觉艺术的创造力。

📚 菜单

0.1 唤起菜单 ALT+M

 唤起菜单

0.2 聚集模式,聚集圆点

0.3 驱逐模式,驱逐圆点

0.4 变色,改变圆点颜色

0.5 长按充能,扩大范围,可移动

0.6 退出菜单使用ESC或者关闭按钮或者点击遮罩层

目录

 

———— ⬇️·`正文开始`·⬇️————

 

📚 引言:1024的特殊意义

每年的10月24日,对于普通人来说可能只是一个普通的秋日,但对于程序员群体而言,这是一个具有特殊意义的节日——1024程序员节。这个日期的选择并非偶然,它源自计算机世界最基本的计数单位——二进制。在二进制系统中,1024等于2的10次方,而在计算机存储容量计算中,1GB等于1024MB,1MB等于1024KB,1KB等于1024B。这种独特的计数方式,使得1024成为了程序员群体最熟悉、最亲切的数字之一。

随着信息技术的飞速发展,程序员已经成为推动社会进步的重要力量。他们用代码构建数字世界,用逻辑解决现实问题,用创新改变人们的生活方式。从日常使用的手机应用到复杂的人工智能系统,从简单的网页设计到庞大的企业级架构,背后都离不开程序员的辛勤付出。

本文将以一段1024程序员节主题的HTML代码为切入点,深入探讨代码背后的技术原理、艺术价值,以及程序员在数字时代的使命与担当。通过解析这段融合了视觉效果与交互体验的代码,我们不仅能够了解前端开发的相关技术,更能感受到程序员将逻辑思维转化为视觉艺术的创造力。

📚 一、代码解析:1024程序员节主题页面的实现

1.1 页面整体结构分析

提供的代码是一个完整的HTML文件,实现了一个具有视觉冲击力的1024程序员节主题页面。页面融合了多种动态效果,包括矩阵代码雨、粒子系统和标题动画,同时还提供了交互控制功能。整体结构可以分为以下几个部分:

  • HTML结构:定义页面的基本骨架,包括画布元素、遮罩层和控制按钮
  • CSS样式:负责页面的视觉呈现,包括颜色、布局和动画效果
  • JavaScript逻辑:实现页面的动态效果和交互功能,包括矩阵代码雨、粒子系统和用户交互

这种HTML+CSS+JavaScript的组合是现代前端开发的基础模式,体现了Web开发中结构、样式和行为分离的设计思想。

1.2 HTML结构详解

HTML部分采用了标准的文档结构,包含DOCTYPE声明、html根元素、head头部和body主体。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>1024程序员节 | 代码艺术</title>
    <!-- 其他头部内容 -->
</head>
<body>
    <canvas id="matrixCanvas"></canvas>
    <canvas id="titleCanvas"></canvas>
    <canvas id="particleCanvas"></canvas>

    <!-- 遮罩层 -->
    <div id="overlay" class="overlay">
        <!-- 遮罩层内容 -->
    </div>

    <script>
        // JavaScript代码
    </script>
</body>
</html>
1.2.1 元数据设置
  • <meta charset="UTF-8">:设置文档的字符编码为UTF-8,确保中文等特殊字符能够正确显示。
  • <meta name="viewport" content="width=device-width, initial-scale=1.0">:设置响应式视图,使页面在不同设备上都能正常显示。
  • <title>:定义页面标题,显示在浏览器标签栏中。
1.2.2 画布元素

页面中使用了三个canvas元素,分别用于实现不同的视觉效果:

  • matrixCanvas:用于绘制矩阵代码雨效果,模拟电影《黑客帝国》中的数字流效果。
  • titleCanvas:用于显示节日标题,包括主标题"CSDN·1024程序员节"和副标题"代码创造世界,逻辑改变未来"。
  • particleCanvas:用于实现粒子系统,提供与用户交互的动态效果。

Canvas是HTML5引入的重要元素,它允许开发者通过JavaScript在网页上绘制图形、动画和其他视觉效果,为Web开发提供了强大的图形处理能力。

1.2.3 遮罩层

遮罩层(overlay)是一个固定定位的元素,用于显示控制界面和节日信息。它默认处于隐藏状态,用户可以通过特定操作(如按下Alt+M键)显示出来。遮罩层包含以下内容:

  • 节日标题和副标题
  • 信息提示框
  • 控制按钮,包括模式选择、颜色选择和重置按钮
  • 关闭按钮

遮罩层的设计体现了良好的用户体验,它将控制功能与主视觉效果分离,既不影响页面的视觉美感,又能提供丰富的交互功能。

1.3 CSS样式分析

CSS部分负责页面的视觉呈现,采用了现代CSS技术,包括Flexbox布局、动画效果和响应式设计。

1.3.1 全局样式重置
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

这段代码使用通配符选择器对所有元素进行样式重置,消除了不同浏览器默认样式的差异,确保页面在不同浏览器中显示一致。box-sizing: border-box属性确保元素的内边距和边框不会影响元素的宽度和高度计算,方便布局设计。

1.3.2 主体样式
body {
    background-color: #000;
    color: #0f0;
    font-family: 'Courier New', monospace;
    overflow: hidden;
    height: 100vh;
    position: relative;
}

主体样式设置了页面的基本视觉风格:

  • 黑色背景(#000)和绿色文本(#0f0),模拟终端界面的视觉效果,符合程序员的审美偏好。
  • 使用等宽字体’Courier New’,增强代码感和科技感。
  • 设置overflow: hidden隐藏页面滚动条,确保页面整体感。
  • 使用height: 100vh使页面高度等于视口高度,实现全屏效果。
  • 设置position: relative为子元素的绝对定位提供参考。
1.3.3 画布样式
#matrixCanvas, #titleCanvas, #particleCanvas {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}

#matrixCanvas { z-index: 1; }
#titleCanvas { z-index: 2; }
#particleCanvas { z-index: 3; }

三个画布都采用绝对定位,覆盖整个页面。通过z-index属性设置它们的堆叠顺序,确保标题显示在代码雨之上,粒子效果显示在最上层,从而实现多层次的视觉效果。

1.3.4 遮罩层样式

遮罩层样式设计注重视觉效果和用户体验:

.overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    display: none;
    justify-content: center;
    align-items: center;
    z-index: 1000;
}

.overlay-content {
    position: relative;
    background-color: rgba(0, 20, 0, 0.9);
    border: 1px solid #0f0;
    border-radius: 10px;
    padding: 30px;
    max-width: 800px;
    width: 80%;
    box-shadow: 0 0 30px rgba(0, 255, 0, 0.5);
    text-align: center;
}
  • 遮罩层使用固定定位,覆盖整个视口,背景采用半透明黑色,既突出内容又不完全遮挡底层页面。
  • 使用Flexbox布局(display: flex)使内容居中显示,提高视觉舒适度。
  • 内容区域采用深绿色背景和绿色边框,与整体风格保持一致,同时添加阴影效果增强立体感。
  • 使用响应式设计,通过max-width和百分比宽度确保在不同设备上都能正常显示。
1.3.5 动画效果

CSS动画是页面视觉效果的重要组成部分,主要包括标题的发光动画:

@keyframes glow {
    from {
        text-shadow: 0 0 10px #0f0, 0 0 20px #0f0;
    }
    to {
        text-shadow: 0 0 20px #0f0, 0 0 30px #0f0, 0 0 40px #0f0;
    }
}

h1 {
    /* 其他样式 */
    animation: glow 2s infinite alternate;
}

这段代码定义了一个名为glow的关键帧动画,通过改变文本阴影的大小和强度,实现标题的发光效果。animation属性将动画应用到标题元素上,设置动画持续时间为2秒,无限循环,并在每次循环后反向播放。

1.3.6 响应式设计
@media (max-width: 768px) {
    h1 {
        font-size: 2.5rem;
    }
    
    .subtitle {
        font-size: 1.2rem;
    }
}

使用媒体查询实现响应式设计,当屏幕宽度小于等于768px时,调整标题和副标题的字体大小,确保在移动设备上显示效果良好。这种设计理念体现了现代Web开发中"移动优先"的思想,确保页面在各种设备上都能提供良好的用户体验。

1.4 JavaScript功能实现

JavaScript部分是页面动态效果和交互功能的核心,实现了矩阵代码雨、粒子系统、标题动画和用户交互等功能。

1.4.1 画布初始化
// 获取画布元素
const matrixCanvas = document.getElementById('matrixCanvas');
const matrixCtx = matrixCanvas.getContext('2d');
const particleCanvas = document.getElementById('particleCanvas');
const particleCtx = particleCanvas.getContext('2d');
const titleCanvas = document.getElementById('titleCanvas');
const titleCtx = titleCanvas.getContext('2d');

// 设置画布大小
function setCanvasSize() {
  matrixCanvas.width = window.innerWidth;
  matrixCanvas.height = window.innerHeight;
  titleCanvas.width = window.innerWidth;
  titleCanvas.height = window.innerHeight;
  particleCanvas.width = window.innerWidth;
  particleCanvas.height = window.innerHeight;
  
  // 更新扩散圆圈最大半径
  pulseMaxRadius = Math.min(window.innerWidth, window.innerHeight) / 4;
}

setCanvasSize();
window.addEventListener('resize', setCanvasSize);

这段代码完成了以下功能:

  1. 通过getElementById获取三个画布元素。
  2. 通过getContext('2d')获取2D绘图上下文,这是在canvas上绘制图形的基础。
  3. 定义setCanvasSize函数,设置画布大小等于窗口大小,确保画布全屏显示。
  4. 监听窗口resize事件,当窗口大小改变时重新设置画布大小,确保响应式效果。
1.4.2 矩阵代码雨效果

矩阵代码雨效果是页面最具特色的视觉效果之一,模拟了电影《黑客帝国》中的数字流效果:

// 矩阵代码雨配置
const chars = "01010101010101010101程序员1024节日快乐代码改变世界";
const fontSize = 14;
const columns = Math.floor(matrixCanvas.width / fontSize);
const drops = [];

// 初始化雨滴位置
for (let i = 0; i < columns; i++) {
    drops[i] = Math.floor(Math.random() * matrixCanvas.height / fontSize);
}

// 矩阵代码雨绘制函数
function drawMatrix() {
    // 半透明黑色背景,制造拖尾效果
    matrixCtx.fillStyle = 'rgba(0, 0, 0, 0.04)';
    matrixCtx.fillRect(0, 0, matrixCanvas.width, matrixCanvas.height);
    
    matrixCtx.fillStyle = '#0f0';
    matrixCtx.font = `${fontSize}px 'Courier New'`;
    
    for (let i = 0; i < drops.length; i++) {
        // 随机字符
        const text = chars[Math.floor(Math.random() * chars.length)];
        
        // 绘制字符
        matrixCtx.fillText(text, i * fontSize, drops[i] * fontSize);
        
        // 重置雨滴位置
        if (drops[i] * fontSize > matrixCanvas.height && Math.random() > 0.975) {
            drops[i] = 0;
        }
        
        // 移动雨滴
        drops[i]++;
    }
}

代码雨效果的实现原理如下:

  1. 定义字符集,包含二进制数字和与程序员节相关的中文字符,增强主题相关性。
  2. 根据画布宽度和字体大小计算列数,确定代码雨的密度。
  3. 初始化雨滴数组,每个元素代表一列雨滴的当前位置。
  4. drawMatrix函数中:
    • 绘制半透明黑色矩形覆盖整个画布,制造拖尾效果。
    • 遍历每一列,在当前雨滴位置绘制随机字符。
    • 向下移动雨滴,如果雨滴超出画布底部,则随机重置到顶部。
    • 使用较低的重置概率(0.025),使代码雨呈现出不规则的下落效果,更接近自然降雨。

这种实现方式既高效又视觉效果出色,通过简单的数学计算和循环操作,就能创造出复杂的动态效果。

1.4.3 标题动画

标题动画在单独的画布上实现,确保标题始终显示在代码雨之上:

// 绘制标题的函数
function drawTitle() {
  titleCtx.clearRect(0, 0, titleCanvas.width, titleCanvas.height);

  // 主标题设置
  titleCtx.font = 'bold 1.8rem "Courier New", monospace';
  titleCtx.textAlign = 'center';
  titleCtx.fillStyle = '#0f0';
  titleCtx.shadowColor = '#0f0';
  titleCtx.shadowBlur = 10;

  // 实现发光动画效果
  const glowIntensity = Math.sin(Date.now() / 1000) * 0.5 + 1.5;
  titleCtx.shadowBlur = 10 * glowIntensity;

  titleCtx.fillText('CSDN·1024程序员节', titleCanvas.width / 2, titleCanvas.height / 2 - 30);

  // 副标题设置
  titleCtx.font = '0.9rem "Courier New", monospace';
  titleCtx.fillStyle = '#0a0';
  titleCtx.shadowBlur = 0;
  titleCtx.fillText('代码创造世界,逻辑改变未来', titleCanvas.width / 2, titleCanvas.height / 2 + 30);
}

标题动画的实现特点:

  1. 使用clearRect清除画布内容,避免帧与帧之间的重叠。
  2. 主标题使用加粗字体和较大字号,突出显示节日主题。
  3. 通过shadowColorshadowBlur属性实现文本发光效果。
  4. 使用正弦函数计算发光强度,使发光效果随时间平滑变化,增强视觉吸引力。
  5. 副标题使用较浅的绿色和较小的字号,与主标题形成对比,同时保持整体风格一致。
  6. 标题居中显示,确保在不同屏幕尺寸下都能保持良好的视觉效果。
1.4.4 粒子系统

粒子系统是页面交互功能的核心,实现了粒子的生成、移动、碰撞检测和用户交互:

// 粒子系统变量声明
let particles = [];
const particleCount = 150;
let mouseX = 0;
let mouseY = 0;
let mode = 0; // 0: 跟随鼠标, 1: 避开鼠标
let colorMode = 0; // 0: 绿色, 1: 随机

// 粒子类
class Particle {
  constructor() {
    this.x = Math.random() * particleCanvas.width;
    this.y = Math.random() * particleCanvas.height;
    this.size = Math.random() * 5 + 1;
    this.speedX = Math.random() * 3 - 1.5;
    this.speedY = Math.random() * 3 - 1.5;
    this.color = colorMode === 0 ? '#0f0' :
      `hsl(${Math.random() * 360}, 100%, 50%)`;
  }

  update() {
    // 计算按压时间
    if (mouseDown) {
      pressDuration = Date.now() - mouseDownTime;
    }

    // 根据按压时间计算加速因子
    const accelerationFactor = Math.min(1 + pressDuration / 1000, 5);

    this.x += this.speedX * accelerationFactor;
    this.y += this.speedY * accelerationFactor;

    // 边界检查
    if (this.x > particleCanvas.width) this.x = 0;
    else if (this.x < 0) this.x = particleCanvas.width;

    if (this.y > particleCanvas.height) this.y = 0;
    else if (this.y < 0) this.y = particleCanvas.height;

    // 鼠标交互
    const dx = mouseX - this
# 1024程序员节:从代码艺术到数字世界的建造者
(接上篇)

.x;
const dy = mouseY - this.y;
const distance = Math.sqrt(dx * dx + dy * dy);

// 扩散圆圈内的粒子交互(根据模式不同)
if (pulseActive && pulseRadius > 0) {
  const pulseDx = mouseX - this.x;
  const pulseDy = mouseY - this.y;
  const pulseDistance = Math.sqrt(pulseDx * pulseDx + pulseDy * pulseDy);

  // 如果粒子在扩散圆圈内或附近
  if (pulseDistance < pulseRadius + 50) { // 圆圈及周围50px范围
    if (mode === 0) {
      // 聚集模式:粒子快速向鼠标中心移动
      this.x += pulseDx * 0.1;
      this.y += pulseDy * 0.1;
    } else {
      // 驱逐模式:粒子被推出圆外
      // 计算推力,距离越近推力越大
      const repelStrength = Math.max(0, 1 - pulseDistance / (pulseRadius + 50));
      // 向外推动(方向与聚集相反)
      this.x -= pulseDx * 0.15 * repelStrength;
      this.y -= pulseDy * 0.15 * repelStrength;
    }
  }
}

// 正常鼠标交互(在没有圆圈时的基本交互)
if (distance < 100) {
  if (mode === 0) {
    this.x += dx * 0.05 * accelerationFactor;
    this.y += dy * 0.05 * accelerationFactor;
  } else {
    this.x -= dx * 0.05 * accelerationFactor;
    this.y -= dy * 0.05 * accelerationFactor;
  }
}
}

draw() {
  particleCtx.fillStyle = this.color;
  particleCtx.beginPath();
  particleCtx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
  particleCtx.fill();
}
}

// 初始化粒子
function initParticles() {
particles = [];
for (let i = 0; i < particleCount; i++) {
    particles.push(new Particle());
}
}

initParticles();

粒子系统的实现体现了面向对象编程思想,通过Particle类封装粒子的属性和行为,主要特点包括:

  1. 粒子初始化:每个粒子随机生成位置、大小和初始速度,速度值范围为-1.5到1.5,确保粒子向各个方向均匀运动。
  2. 颜色模式:支持两种颜色模式,默认绿色模式和随机彩色模式,通过colorMode变量控制。
  3. 边界处理:采用循环边界模式,当粒子超出画布边界时,从对面重新进入,确保粒子系统的连续性。
  4. 鼠标交互:实现了两种交互模式——聚集模式和驱逐模式,粒子根据与鼠标的距离做出相应反应。
  5. 按压加速:根据鼠标按压时间计算加速因子,按压时间越长,粒子运动速度越快,增强交互的层次感。
  6. 扩散圆圈效果:当鼠标按压时,生成扩散圆圈,圈内粒子产生更强烈的交互效果,提升视觉冲击力。
1.4.5 事件监听与用户交互

页面实现了丰富的用户交互功能,包括鼠标事件、键盘事件和按钮点击事件:

// 鼠标移动事件
particleCanvas.addEventListener('mousemove', (e) => {
  mouseX = e.clientX;
  mouseY = e.clientY;
});

// 鼠标按下事件
particleCanvas.addEventListener('mousedown', function(e) {
  mouseDown = true;
  mouseDownTime = Date.now();
  pressDuration = 0;

  // 开始充能
  charging = true;
  chargeStartTime = Date.now();
  chargeCompleted = false;

  // 激活扩散圆圈效果
  pulseActive = true;
  pulseRadius = 0;
  pulseStartTime = Date.now();

  // 设置鼠标位置
  mouseX = e.clientX;
  mouseY = e.clientY;
});

// 鼠标释放事件
particleCanvas.addEventListener('mouseup', function(e) {
  mouseDown = false;
  pressDuration = 0;

  // 停止充能
  charging = false;
  chargeCompleted = false;

  // 停止扩散效果
  pulseActive = false;
  pulseRadius = 0;
});

// 键盘事件监听
document.addEventListener('keydown', function(e) {
  // Alt+M 显示遮罩层
  if (e.altKey && e.key.toLowerCase() === 'm') {
    e.preventDefault();
    document.getElementById('overlay').style.display = 'flex';
  }

  // ESC 键关闭遮罩层
  if (e.key === 'Escape') {
    document.getElementById('overlay').style.display = 'none';
  }
});

// 按钮事件
document.getElementById('attractBtn').addEventListener('click', () => {
    mode = 0;
    updateModeButtons();
});

document.getElementById('repelBtn').addEventListener('click', () => {
    mode = 1;
    updateModeButtons();
});

document.getElementById('defaultColorBtn').addEventListener('click', () => {
    colorMode = 0;
    updateColorButtons();
    initParticles();
});

document.getElementById('rainbowColorBtn').addEventListener('click', () => {
    colorMode = 1;
    updateColorButtons();
    initParticles();
});

document.getElementById('resetBtn').addEventListener('click', () => {
    initParticles();
});

// 关闭按钮事件
document.getElementById('closeBtn').addEventListener('click', function() {
  document.getElementById('overlay').style.display = 'none';
});

// 点击遮罩层关闭
document.getElementById('overlay').addEventListener('click', function(e) {
  if (e.target.id === 'overlay') {
    this.style.display = 'none';
  }
});

// 阻止遮罩层内容区域点击时关闭
document.querySelector('.overlay-content').addEventListener('click', function(e) {
  e.stopPropagation();
});

这些事件监听实现了以下交互功能:

  1. 鼠标移动:实时更新鼠标位置,为粒子系统提供交互目标。
  2. 鼠标按压/释放:触发充能效果和扩散圆圈,增强交互反馈。
  3. 键盘快捷键:支持Alt+M显示控制界面,ESC键关闭界面,提升操作效率。
  4. 按钮控制:提供模式选择、颜色切换和重置功能,方便用户调整效果。
  5. 遮罩层交互:支持点击关闭按钮、点击遮罩层空白区域关闭,以及阻止内容区域点击冒泡,确保交互逻辑的合理性。
1.4.6 动画循环
// 动画循环
function animate() {
    drawMatrix();
    drawTitle();
    drawParticles();
    requestAnimationFrame(animate);
}

animate();

动画循环是页面动态效果的核心驱动,通过requestAnimationFrame函数实现高效的动画渲染:

  1. requestAnimationFrame会根据浏览器的刷新频率自动调整调用时机,通常为每秒60次,确保动画流畅且不浪费资源。
  2. 每次循环依次调用drawMatrixdrawTitledrawParticles函数,更新三个画布的内容。
  3. 这种循环方式实现了三个独立效果的同步渲染,确保页面视觉效果的一致性。

📚 二、代码背后的技术思想与艺术价值

2.1 技术思想的体现

2.1.1 分层设计思想

页面采用了清晰的分层设计,通过三个独立的canvas元素实现不同的视觉效果,每个画布负责特定的功能:

  • 底层(matrixCanvas):实现矩阵代码雨效果,作为页面的背景层。
  • 中层(titleCanvas):显示节日标题,作为页面的信息层。
  • 上层(particleCanvas):实现粒子系统和交互功能,作为页面的交互层。

这种分层设计具有以下优势:

  1. 功能解耦:每个层的功能独立,修改一个层的代码不会影响其他层,便于维护和扩展。
  2. 性能优化:可以针对不同层的复杂度调整渲染策略,提高整体性能。
  3. 视觉层次:通过z-index控制层的堆叠顺序,创造出丰富的视觉层次感。
2.1.2 面向对象编程思想

粒子系统的实现采用了面向对象编程(OOP)思想,通过Particle类封装粒子的属性和行为:

  1. 封装性:将粒子的位置、大小、速度、颜色等属性,以及更新、绘制等方法封装在类中,实现数据和行为的封装。
  2. 可扩展性:如果需要添加新的粒子效果,只需在类中添加相应的方法或属性,无需修改其他代码。
  3. 可维护性:类的结构清晰,代码逻辑易于理解和维护,便于后续修改和优化。
2.1.3 事件驱动编程思想

页面的交互功能基于事件驱动编程思想实现,通过监听用户的鼠标、键盘操作,触发相应的处理函数:

  1. 松耦合:事件触发者和处理者之间通过事件机制连接,无需直接依赖,降低了代码的耦合度。
  2. 响应式:能够实时响应用户的操作,提供即时反馈,提升用户体验。
  3. 可扩展性:可以轻松添加新的事件监听和处理函数,扩展页面的交互功能。
2.1.4 性能优化思想

代码中体现了多种性能优化思想,确保页面在各种设备上都能流畅运行:

  1. 高效渲染:使用requestAnimationFrame实现高效的动画循环,避免使用setInterval导致的性能问题。
  2. 减少重绘:每个画布只更新必要的内容,例如粒子系统只清除和重绘粒子区域,而不是整个画布。
  3. 响应式调整:监听窗口大小变化,动态调整画布尺寸,确保在不同屏幕尺寸下都能保持最佳效果。
  4. 资源控制:限制粒子数量(150个),避免过多粒子导致的性能下降,平衡视觉效果和性能。

2.2 代码的艺术价值

2.2.1 视觉艺术:科技感与美感的结合

页面的视觉设计融合了科技感和艺术美感,创造出独特的视觉体验:

  1. 色彩搭配:黑色背景与绿色文本的搭配,模拟了终端界面的视觉效果,唤起程序员的职业共鸣,同时绿色的发光效果增添了科技感和未来感。
  2. 动态效果:矩阵代码雨、粒子系统、标题动画等动态效果,使页面充满活力,避免了静态页面的单调乏味。
  3. 视觉层次:通过三个画布的分层设计,创造出丰富的视觉层次,使页面具有深度感和立体感。
2.2.2 交互艺术:用户参与的创作过程

页面的交互设计将用户的操作融入到视觉效果中,使用户成为艺术创作的参与者:

  1. 实时反馈:用户的鼠标移动、按压操作会立即影响粒子的运动和扩散效果,提供即时反馈。
  2. 个性化体验:用户可以通过控制按钮选择不同的模式和颜色,定制自己喜欢的视觉效果。
  3. 沉浸感:全屏的视觉效果和丰富的交互反馈,使用户沉浸在数字世界中,体验代码带来的乐趣。
2.2.3 主题表达:程序员文化的体现

页面的设计充分体现了程序员文化的特点,传递了程序员节的主题:

  1. 符号元素:二进制数字、代码雨、终端风格等元素,都是程序员熟悉的符号,体现了程序员的职业特征。
  2. 文字内容:"代码创造世界,逻辑改变未来"等标语,表达了程序员对技术的热爱和对未来的愿景。
  3. 交互体验:通过代码实现的交互效果,展示了程序员用技术创造美好体验的能力,体现了"代码即艺术"的理念。

📚 三、程序员节的意义:从节日到文化

3.1 程序员节的起源与发展

1024程序员节起源于中国程序员群体的自发倡议,随着信息技术的发展,逐渐成为一个被广泛认可的行业节日。

3.1.1 起源:程序员的自我认同

1024程序员节的起源与程序员群体的自我认同密切相关。在互联网发展初期,程序员往往是幕后工作者,他们的贡献很少被公众关注和认可。为了提升程序员的职业认同感和社会关注度,一些程序员自发提议将10月24日定为程序员节,因为1024是计算机领域的重要数字,具有特殊的象征意义。

3.1.2 发展:行业与社会的认可

随着互联网行业的快速发展,程序员的作用日益凸显,1024程序员节也得到了越来越多的认可:

  1. 企业参与:许多互联网企业开始重视程序员节,通过举办活动、发放福利、表彰优秀程序员等方式,提升员工的归属感和幸福感。
  2. 媒体关注:主流媒体开始报道程序员节,关注程序员的工作状态和职业发展,提升了程序员群体的社会关注度。
  3. 文化形成:程序员节逐渐形成了独特的文化氛围,包括技术分享、代码创作、行业交流等活动,成为程序员群体交流和成长的平台。

3.2 程序员节的意义与价值

3.2.1 对程序员个人:职业认同与自我价值实现

程序员节对程序员个人而言,具有重要的意义:

  1. 职业认同:程序员节为程序员提供了一个展示自我的平台,让他们感受到自己的职业价值和社会认可,增强职业认同感和自豪感。
  2. 交流学习:在程序员节期间,各种技术分享、行业交流活动为程序员提供了学习和成长的机会,有助于提升专业技能和拓宽视野。
  3. 身心放松:程序员工作压力大、强度高,程序员节的各种活动可以让他们放松身心,缓解工作压力,保持良好的工作状态。
3.2.2 对企业:团队凝聚力与创新动力

对企业而言,程序员节是提升团队凝聚力和激发创新动力的重要契机:

  1. 团队建设:通过举办程序员节活动,企业可以增强团队成员之间的交流和合作,提升团队凝聚力和归属感。
  2. 人才激励:表彰优秀程序员、提供福利等方式,可以激励员工的工作积极性和创造力,提高工作效率和质量。
  3. 品牌形象:企业参与程序员节活动,展示对员工的关怀和对技术的重视,有助于提升企业的品牌形象和吸引力,吸引更多优秀人才。
3.2.3 对行业:技术交流与文化传承

程序员节对整个互联网行业而言,具有促进技术交流和文化传承的重要作用:

  1. 技术交流:各种技术分享、开源项目推广等活动,促进了行业内的技术交流和合作,推动了技术的创新和发展。
  2. 文化传承:程序员节逐渐形成了独特的行业文化,包括对技术的热爱、对创新的追求、对开源的支持等,这些文化理念通过节日活动得以传承和发扬。
  3. 行业发展:通过程序员节的活动,提升了整个行业的社会关注度和影响力,为行业的发展创造了良好的环境和氛围。
3.2.4 对社会:数字文明的推动力量

在数字时代,程序员作为数字世界的建造者,他们的工作对社会发展具有重要影响:

  1. 技术创新:程序员通过代码实现各种技术创新,推动了互联网、人工智能、大数据等领域的发展,改变了人们的生活方式和社会运行模式。
  2. 数字基建:从网站、APP到企业系统、国家政务平台,程序员构建了数字社会的基础设施,为社会的数字化转型提供了支撑。
  3. 社会进步:程序员开发的各种应用和系统,在教育、医疗、交通、金融等领域发挥了重要作用,推动了社会的进步和发展。

📚 四、程序员的使命与担当:在数字时代创造未来

4.1 程序员的核心使命

在数字时代,程序员的核心使命是通过技术创新和代码实现,构建数字世界,推动社会进步:

4.1.1 技术创新:突破技术边界

程序员是技术创新的核心力量,他们通过不断探索和实践,突破技术边界,推动技术的发展:

  1. 基础技术研发:在操作系统、编程语言、数据库等基础技术领域,程序员的研发工作为整个数字产业提供了技术基础。
  2. 应用技术创新:在人工智能、大数据、云计算、区块链等新兴领域,程序员通过创新的应用技术,开发出各种具有颠覆性的产品和服务。
  3. 技术优化升级:对现有技术进行优化和升级,提高系统的性能、安全性和可靠性,满足不断增长的用户需求。
4.1.2 产品实现:将想法变为现实

程序员的重要使命是将产品经理、设计师的想法和创意,通过代码转化为实际的产品和服务:

  1. 需求分析:深入理解用户需求和产品目标,将抽象的需求转化为具体的技术方案。
  2. 代码实现:根据技术方案,编写高质量的代码,实现产品的功能和性能要求。
  3. 测试优化:参与产品的测试和优化过程,确保产品的质量和用户体验,解决各种技术问题。
4.1.3 用户服务:创造价值体验

程序员的工作最终要服务于用户,通过技术手段为用户创造价值和良好的体验:

  1. 用户体验优化:关注用户的使用习惯和需求,通过技术手段优化产品的界面、交互和性能,提升用户体验。

  2. 问题解决:快速响应用户反馈的问题,通过技术手段修复漏洞、优化功能,确保用户能够正常使用产品。

  3. 价值创造:通过开发实用的功能和服务,为用户的工作、学习和生活提供便利,创造实际价值。

4.2 程序员的时代担当

在数字化浪潮席卷全球的今天,程序员作为数字世界的建造者,肩负着重要的时代担当:

4.2.1 推动数字化转型

随着数字经济的发展,传统行业的数字化转型已成为必然趋势。程序员在这一过程中扮演着关键角色:

  1. 传统行业赋能:为制造业、农业、服务业等传统行业开发数字化系统,实现生产、管理、营销等环节的数字化,提高效率、降低成本。
  2. 数字基础设施建设:参与建设云计算、大数据中心、物联网等数字基础设施,为传统行业的数字化转型提供技术支撑。
  3. 数字化人才培养:通过技术分享、开源项目等方式,培养更多数字化人才,为传统行业的数字化转型提供人才保障。
4.2.2 保障网络安全

在数字时代,网络安全至关重要。程序员作为数字系统的构建者,有责任保障系统的安全性:

  1. 安全开发:在系统开发过程中,遵循安全开发规范,采用安全的技术和架构,从源头防范安全风险。
  2. 漏洞修复:及时发现和修复系统中的安全漏洞,防止黑客攻击和数据泄露。
  3. 安全意识普及:向用户和企业普及网络安全知识,提高安全意识,共同营造安全的网络环境。
4.2.3 推动可持续发展

程序员可以通过技术手段,为实现可持续发展目标贡献力量:

  1. 绿色技术开发:开发节能、环保的技术和产品,降低能源消耗和环境影响。例如,优化数据中心的能源管理系统,减少能源浪费。
  2. 资源优化配置:利用大数据、人工智能等技术,实现资源的优化配置,提高资源利用效率。例如,通过智能交通系统优化交通流量,减少交通拥堵和碳排放。
  3. 公益项目开发:参与开发公益性质的技术项目,为教育、医疗、扶贫等公益事业提供技术支持,推动社会公平和可持续发展。

📚 五、总结与展望

5.1 总结:代码铸就的数字世界

通过对1024程序员节主题页面代码的深入解析,我们不仅了解了前端开发的技术细节,更感受到了代码背后蕴含的技术思想和艺术价值。这段代码以简洁高效的方式,实现了矩阵代码雨、粒子系统、标题动画等丰富的视觉效果和交互功能,展现了程序员将逻辑思维转化为视觉艺术的创造力。

1024程序员节从最初的行业自发倡议,发展到如今被广泛认可的行业节日,不仅体现了程序员群体的自我认同和职业自豪感,更反映了社会对程序员群体的重视和认可。在数字时代,程序员作为数字世界的建造者,肩负着技术创新、产品实现、用户服务的核心使命,同时也承担着推动数字化转型、保障网络安全、促进可持续发展的时代担当。

回顾程序员行业的发展历程,我们看到了技术的飞速进步和程序员群体的不断成长。从早期的汇编语言到如今的高级编程语言,从单机应用到分布式系统,从互联网到人工智能,每一次技术变革都离不开程序员的辛勤付出。他们用代码构建了数字世界的基础设施,用逻辑解决了现实世界的复杂问题,用创新改变了人们的生活方式。

5.2 展望:未来程序员的机遇与挑战

随着技术的不断发展,未来程序员行业将面临更多的机遇和挑战:

5.2.1 技术变革带来的机遇
  1. 新兴技术领域的崛起:人工智能、大数据、云计算、区块链、元宇宙等新兴技术领域的快速发展,将为程序员提供更多的就业机会和发展空间。这些领域需要大量具备专业技能的程序员,开发创新的技术和产品,推动行业的发展。
  2. 跨领域融合的需求:随着技术与各行业的深度融合,对具备跨领域知识的程序员需求将不断增加。例如,医疗健康领域需要既懂医学知识又懂信息技术的程序员,开发医疗信息化系统和医疗人工智能产品;金融领域需要既懂金融知识又懂区块链技术的程序员,开发金融科技产品。
  3. 开源生态的繁荣:开源生态的不断繁荣,为程序员提供了更多的学习和合作机会。程序员可以通过参与开源项目,提升自己的技术水平,积累项目经验,同时也可以与全球的开发者合作,共同推动技术的创新和发展。
5.2.2 行业发展面临的挑战
  1. 技术更新速度加快:随着技术的快速发展,编程语言、框架、工具等不断更新迭代,程序员需要不断学习和掌握新的技术,才能适应行业的发展需求。这对程序员的学习能力和适应能力提出了更高的要求。
  2. 职业竞争日益激烈:随着程序员群体的不断扩大,行业竞争日益激烈。企业对程序员的技术水平、项目经验、综合素质等要求越来越高,程序员需要不断提升自己的竞争力,才能在行业中立足。
  3. 工作压力与身心健康:程序员工作强度大、压力高,长期的高强度工作容易导致身心健康问题。如何平衡工作与生活,保持良好的身心健康,成为程序员需要面对的重要挑战。

5.3 对未来程序员的建议

面对未来的机遇与挑战,作为新时代的程序员,需要不断提升自己,适应行业的发展需求:

  1. 保持持续学习的热情:技术更新速度加快,程序员需要保持持续学习的热情,不断学习新的编程语言、框架、工具和技术理念,提升自己的技术水平。可以通过阅读技术书籍、参加技术培训、关注技术博客和开源项目等方式,获取最新的技术知识。
  2. 培养跨领域的知识储备:随着技术与各行业的深度融合,具备跨领域知识的程序员将更具竞争力。程序员可以根据自己的兴趣和职业规划,学习相关领域的知识,例如金融、医疗、教育等,培养跨领域的思维和能力。
  3. 注重代码质量和安全:代码质量和安全是程序员工作的核心要求。程序员需要遵循编码规范,编写高质量、可维护、安全的代码,确保系统的稳定性和安全性。同时,要重视代码审查和测试工作,及时发现和修复代码中的问题。
  4. 关注用户需求和体验:技术最终要服务于用户,程序员需要关注用户的需求和体验,从用户的角度出发,开发出满足用户需求、提升用户体验的产品和服务。可以通过用户调研、用户反馈等方式,了解用户的需求和痛点,不断优化产品和服务。
  5. 保持身心健康和工作生活平衡:身心健康是程序员工作和生活的基础。程序员需要合理安排工作时间,避免过度加班,保持良好的作息习惯。同时,要适当参加体育锻炼和社交活动,缓解工作压力,保持身心健康和工作生活的平衡。

5.4 结语:致敬每一位程序员

1024程序员节不仅是一个节日,更是对程序员群体辛勤付出的认可和致敬。在数字时代,程序员用代码构建了数字世界的基石,用逻辑解决了现实世界的难题,用创新推动了社会的进步。他们是数字世界的建造者,是技术创新的推动者,是未来生活的创造者。

每一行代码都承载着程序员的智慧和汗水,每一个产品都凝聚着程序员的心血和梦想。在这个特殊的节日里,让我们向每一位程序员致敬,感谢他们为数字世界的发展所做出的贡献。同时,也希望每一位程序员能够在未来的工作中,保持对技术的热爱和对创新的追求,不断提升自己,为数字时代的发展创造更多的价值,共同构建一个更加美好的数字未来。

最后,再次祝愿所有程序员1024节日快乐!愿每一位程序员都能在代码的世界里,书写属于自己的精彩篇章,创造出更多改变世界的作品!

要不要我帮你整理一份1024程序员节主题页面代码核心功能清单?清单会提炼代码中矩阵代码雨、粒子系统、交互控制等核心模块的实现要点,方便快速回顾和复用关键技术。

📚 六、完整代码,html + css + javascript

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>1024程序员节 | 代码艺术</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            background-color: #000;
            color: #0f0;
            font-family: 'Courier New', monospace;
            overflow: hidden;
            height: 100vh;
            position: relative;
        }
        
        #matrixCanvas {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 1;
        }
        
        #particleCanvas {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 3;
        }
        /* 添加遮罩层样式 */
        .overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.8);
            display: none;
            justify-content: center;
            align-items: center;
            z-index: 1000;
        }

        .overlay-content {
            position: relative;
            background-color: rgba(0, 20, 0, 0.9);
            border: 1px solid #0f0;
            border-radius: 10px;
            padding: 30px;
            max-width: 800px;
            width: 80%;
            box-shadow: 0 0 30px rgba(0, 255, 0, 0.5);
            text-align: center;
        }

        .close-btn {
            position: absolute;
            top: 10px;
            right: 15px;
            background: transparent;
            border: none;
            color: #0f0;
            font-size: 1.5rem;
            cursor: pointer;
            width: 30px;
            height: 30px;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .close-btn:hover {
            background-color: rgba(0, 255, 0, 0.2);
            border-radius: 50%;
        }
        .content {
            display: none;
            position: relative;
            z-index: 4;
            /*display: flex;*/
            flex-direction: column;
            justify-content: center;
            align-items: center;
            height: 100%;
            text-align: center;
            padding: 20px;
        }
        
        h1 {
            font-size: 3.5rem;
            margin-bottom: 20px;
            text-shadow: 0 0 10px #0f0;
            animation: glow 2s infinite alternate;
        }
        
        .subtitle {
            font-size: 1.5rem;
            margin-bottom: 30px;
            color: #0a0;
        }
        
        .info-box {
            background-color: rgba(0, 20, 0, 0.7);
            border: 1px solid #0f0;
            padding: 20px;
            border-radius: 5px;
            max-width: 600px;
            margin-top: 20px;
            box-shadow: 0 0 15px rgba(0, 255, 0, 0.3);
        }
        
        .controls {
            margin-top: 20px;
        }
        
        button {
            background: transparent;
            border: 1px solid #0f0;
            color: #0f0;
            padding: 10px 20px;
            margin: 0 10px;
            cursor: pointer;
            font-family: 'Courier New', monospace;
            transition: all 0.3s;
        }
        
        button:hover {
            background-color: rgba(0, 255, 0, 0.2);
            box-shadow: 0 0 10px #0f0;
        }
        
        button.active {
            background-color: rgba(0, 255, 0, 0.3);
            box-shadow: 0 0 15px #0f0;
        }
        #titleCanvas {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            z-index: 2;
        }


        
        @keyframes glow {
            from {
                text-shadow: 0 0 10px #0f0, 0 0 20px #0f0;
            }
            to {
                text-shadow: 0 0 20px #0f0, 0 0 30px #0f0, 0 0 40px #0f0;
            }
        }
        
        @media (max-width: 768px) {
            h1 {
                font-size: 2.5rem;
            }
            
            .subtitle {
                font-size: 1.2rem;
            }
        }

    </style>
</head>
<body>
    <canvas id="matrixCanvas"></canvas>
    <canvas id="titleCanvas"></canvas>
    <canvas id="particleCanvas"></canvas>

    <!-- 添加遮罩层 -->
    <div id="overlay" class="overlay">
        <div class="overlay-content">
            <button class="close-btn" id="closeBtn">&times;</button>
            <div class="content" style="display: block;">
                <h1>1024 程序员节</h1>
                <div class="subtitle">代码创造世界,逻辑改变未来</div>

                <div class="info-box">
                    <p>移动鼠标与粒子互动 | 选择不同效果模式</p>
                    <p>祝所有程序员节日快乐!</p>
                </div>

                <div class="controls">
                    <div style="display: flex; align-items: center; margin-bottom: 15px;">
                        <div style="color: #0a0; margin-right: 15px; font-size: 0.9rem; min-width: 80px;">模式选择:</div>
                        <div>
                            <button id="attractBtn" class="mode-btn active">✓ 聚集模式</button>
                            <button id="repelBtn" class="mode-btn">驱逐模式</button>
                        </div>
                    </div>
                    <div style="display: flex; align-items: center; margin-bottom: 15px;">
                        <div style="color: #0a0; margin-right: 15px; font-size: 0.9rem; min-width: 80px;">颜色选择:</div>
                        <div>
                            <button id="defaultColorBtn" class="color-btn active">✓ 默认色</button>
                            <button id="rainbowColorBtn" class="color-btn">彩色</button>
                        </div>
                    </div>
                    <div style="text-align: center;">
                        <button id="resetBtn">重置</button>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script>
        // 矩阵代码雨效果
        const matrixCanvas = document.getElementById('matrixCanvas');
        const matrixCtx = matrixCanvas.getContext('2d');
        
        // 粒子系统
        const particleCanvas = document.getElementById('particleCanvas');
        const particleCtx = particleCanvas.getContext('2d');

        const titleCanvas = document.getElementById('titleCanvas');
        const titleCtx = titleCanvas.getContext('2d');

        // 粒子系统变量声明(必须在 setCanvasSize 之前)
        let particles = [];
        const particleCount = 150;
        let mouseX = 0;
        let mouseY = 0;
        let mode = 0; // 0: 跟随鼠标, 1: 避开鼠标
        let colorMode = 0; // 0: 绿色, 1: 随机

        // 添加鼠标按下相关变量
        let mouseDown = false;
        let mouseDownTime = 0;
        let pressDuration = 0;

        // 添加扩散圆圈相关变量
        let pulseActive = false;
        let pulseRadius = 0;
        let pulseMaxRadius = Math.min(window.innerWidth, window.innerHeight) / 4; // 最大为窗口宽度的1/4
        let pulseSpeed = 8; // 扩散速度
        let pulseStartTime = 0;

        // 添加充能相关变量
        let charging = false;
        let chargeStartTime = 0;
        let chargeDuration = 10000; // 10秒充能时间
        let chargeCompleted = false;

        // 修改setCanvasSize函数,加入titleCanvas尺寸设置
        function setCanvasSize() {
          matrixCanvas.width = window.innerWidth;
          matrixCanvas.height = window.innerHeight;
          titleCanvas.width = window.innerWidth;
          titleCanvas.height = window.innerHeight;
          particleCanvas.width = window.innerWidth;
          particleCanvas.height = window.innerHeight;
          
          // 更新扩散圆圈最大半径
          pulseMaxRadius = Math.min(window.innerWidth, window.innerHeight) / 4;
        }

        // 添加绘制标题的函数
        function drawTitle() {
          titleCtx.clearRect(0, 0, titleCanvas.width, titleCanvas.height);

          // 主标题设置更合适的字体大小
          titleCtx.font = 'bold 1.8rem "Courier New", monospace';
          titleCtx.textAlign = 'center';
          titleCtx.fillStyle = '#0f0';
          titleCtx.shadowColor = '#0f0';
          titleCtx.shadowBlur = 10;

          // 实现发光动画效果
          const glowIntensity = Math.sin(Date.now() / 1000) * 0.5 + 1.5;
          titleCtx.shadowBlur = 10 * glowIntensity;

          titleCtx.fillText('CSDN·1024程序员节', titleCanvas.width / 2, titleCanvas.height / 2 - 30);

          // 副标题设置更合适的字体大小
          titleCtx.font = '0.9rem "Courier New", monospace';
          titleCtx.fillStyle = '#0a0';
          titleCtx.shadowBlur = 0;
          titleCtx.fillText('代码创造世界,逻辑改变未来', titleCanvas.width / 2, titleCanvas.height / 2 + 30);
        }


        
        setCanvasSize();
        window.addEventListener('resize', setCanvasSize);

        // 矩阵代码雨配置
        const chars = "01010101010101010101程序员1024节日快乐代码改变世界";
        const fontSize = 14;
        const columns = Math.floor(matrixCanvas.width / fontSize);
        const drops = [];
        
        // 初始化雨滴位置
        for (let i = 0; i < columns; i++) {
            drops[i] = Math.floor(Math.random() * matrixCanvas.height / fontSize);
        }
        
        // 矩阵代码雨绘制函数
        function drawMatrix() {
            // 半透明黑色背景,制造拖尾效果
            matrixCtx.fillStyle = 'rgba(0, 0, 0, 0.04)';
            matrixCtx.fillRect(0, 0, matrixCanvas.width, matrixCanvas.height);
            
            matrixCtx.fillStyle = '#0f0';
            matrixCtx.font = `${fontSize}px 'Courier New'`;
            
            for (let i = 0; i < drops.length; i++) {
                // 随机字符
                const text = chars[Math.floor(Math.random() * chars.length)];
                
                // 绘制字符
                matrixCtx.fillText(text, i * fontSize, drops[i] * fontSize);
                
                // 重置雨滴位置
                if (drops[i] * fontSize > matrixCanvas.height && Math.random() > 0.975) {
                    drops[i] = 0;
                }
                
                // 移动雨滴
                drops[i]++;
            }
        }

        // 修改鼠标按下事件
        particleCanvas.addEventListener('mousedown', function(e) {
          mouseDown = true;
          mouseDownTime = Date.now();
          pressDuration = 0;

          // 开始充能
          charging = true;
          chargeStartTime = Date.now();
          chargeCompleted = false;

          // 激活扩散圆圈效果
          pulseActive = true;
          pulseRadius = 0;
          pulseStartTime = Date.now();

          // 设置鼠标位置
          mouseX = e.clientX;
          mouseY = e.clientY;
        });

        // 修改鼠标释放事件
        particleCanvas.addEventListener('mouseup', function(e) {
          mouseDown = false;
          pressDuration = 0;

          // 停止充能
          charging = false;
          chargeCompleted = false;

          // 停止扩散效果
          pulseActive = false;
          pulseRadius = 0;
        });


        // 修改Particle类的update方法
        // 修改Particle类的update方法
        class Particle {
          constructor() {
            this.x = Math.random() * particleCanvas.width;
            this.y = Math.random() * particleCanvas.height;
            this.size = Math.random() * 5 + 1;
            this.speedX = Math.random() * 3 - 1.5;
            this.speedY = Math.random() * 3 - 1.5;
            this.color = colorMode === 0 ? '#0f0' :
              `hsl(${Math.random() * 360}, 100%, 50%)`;
          }

          update() {
            // 计算按压时间
            if (mouseDown) {
              pressDuration = Date.now() - mouseDownTime;
            }

            // 根据按压时间计算加速因子
            const accelerationFactor = Math.min(1 + pressDuration / 1000, 5);

            this.x += this.speedX * accelerationFactor;
            this.y += this.speedY * accelerationFactor;

            // 边界检查
            if (this.x > particleCanvas.width) this.x = 0;
            else if (this.x < 0) this.x = particleCanvas.width;

            if (this.y > particleCanvas.height) this.y = 0;
            else if (this.y < 0) this.y = particleCanvas.height;

            // 鼠标交互
            const dx = mouseX - this.x;
            const dy = mouseY - this.y;
            const distance = Math.sqrt(dx * dx + dy * dy);

            // 扩散圆圈内的粒子交互(根据模式不同)
            if (pulseActive && pulseRadius > 0) {
              const pulseDx = mouseX - this.x;
              const pulseDy = mouseY - this.y;
              const pulseDistance = Math.sqrt(pulseDx * pulseDx + pulseDy * pulseDy);

              // 如果粒子在扩散圆圈内或附近
              if (pulseDistance < pulseRadius + 50) { // 圆圈及周围50px范围
                if (mode === 0) {
                  // 聚集模式:粒子快速向鼠标中心移动
                  this.x += pulseDx * 0.1;
                  this.y += pulseDy * 0.1;
                } else {
                  // 驱逐模式:粒子被推出圆外
                  // 计算推力,距离越近推力越大
                  const repelStrength = Math.max(0, 1 - pulseDistance / (pulseRadius + 50));
                  // 向外推动(方向与聚集相反)
                  this.x -= pulseDx * 0.15 * repelStrength;
                  this.y -= pulseDy * 0.15 * repelStrength;
                }
              }
            }

            // 正常鼠标交互(在没有圆圈时的基本交互)
            if (distance < 100) {
              if (mode === 0) {
                this.x += dx * 0.05 * accelerationFactor;
                this.y += dy * 0.05 * accelerationFactor;
              } else {
                this.x -= dx * 0.05 * accelerationFactor;
                this.y -= dy * 0.05 * accelerationFactor;
              }
            }
          }

          draw() {
            particleCtx.fillStyle = this.color;
            particleCtx.beginPath();
            particleCtx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
            particleCtx.fill();
          }
        }

        // 修改drawParticles函数,添加扩散圆圈绘制
        function drawParticles() {
          particleCtx.clearRect(0, 0, particleCanvas.width, particleCanvas.height);

          // 处理充能逻辑
          if (charging) {
            const elapsed = Date.now() - chargeStartTime;
            const remaining = Math.max(0, chargeDuration - elapsed);
            const secondsRemaining = Math.ceil(remaining / 1000);
            const chargeProgress = Math.min(1, elapsed / chargeDuration); // 充能进度 0-1

            // 显示充能进度文字
            particleCtx.font = '20px "Courier New", monospace';
            particleCtx.fillStyle = '#0f0';
            particleCtx.textAlign = 'center';
            particleCtx.shadowColor = '#0f0';
            particleCtx.shadowBlur = 10;

            // 根据充能状态显示不同文字
            if (elapsed >= chargeDuration) {
              // 充能完成,显示完成提示
              particleCtx.fillText("充能完成", mouseX, mouseY - 50);
              chargeCompleted = true;
            } else {
              // 充能中,显示倒计时
              particleCtx.fillText(`再按${secondsRemaining}秒充能完成`, mouseX, mouseY - 50);
              
              // 绘制进度条(只在充能中显示,充能完成后消失)
              const progressBarWidth = 200; // 进度条总宽度
              const progressBarHeight = 8; // 进度条高度
              const progressBarX = mouseX - progressBarWidth / 2; // 进度条起始X坐标
              const progressBarY = mouseY - 30; // 进度条Y坐标(在文字下方)
              
              // 绘制进度条背景
              particleCtx.shadowBlur = 0;
              particleCtx.fillStyle = 'rgba(0, 255, 0, 0.2)';
              particleCtx.fillRect(progressBarX, progressBarY, progressBarWidth, progressBarHeight);
              
              // 绘制进度条边框
              particleCtx.strokeStyle = 'rgba(0, 255, 0, 0.5)';
              particleCtx.lineWidth = 1;
              particleCtx.strokeRect(progressBarX, progressBarY, progressBarWidth, progressBarHeight);
              
              // 绘制进度条填充(根据充能进度)
              particleCtx.fillStyle = '#0f0';
              particleCtx.shadowColor = '#0f0';
              particleCtx.shadowBlur = 5;
              particleCtx.fillRect(progressBarX, progressBarY, progressBarWidth * chargeProgress, progressBarHeight);
            }
            particleCtx.shadowBlur = 0;

            // 根据充能进度设置圆圈大小
            if (elapsed >= chargeDuration) {
              // 充能完成,圆圈达到最大值
              pulseRadius = pulseMaxRadius;
            } else {
              // 充能中,圆圈逐渐增大(根据充能进度)
              pulseRadius = (elapsed / chargeDuration) * pulseMaxRadius;
            }
          }

          // 更新并绘制扩散圆圈
          if (pulseActive) {
            // 绘制扩散圆圈(保持可见的透明度)
            particleCtx.beginPath();
            particleCtx.arc(mouseX, mouseY, pulseRadius, 0, Math.PI * 2);
            // 修改透明度计算:从1开始,随着扩散逐渐降低到0.3,确保圆圈始终可见
            const alpha = Math.max(0.3, 1 - (pulseRadius / pulseMaxRadius) * 0.7);
            particleCtx.strokeStyle = `rgba(0, 255, 0, ${alpha})`;
            particleCtx.lineWidth = 2;
            particleCtx.stroke();
          }

          // 绘制粒子之间的连线
          for (let i = 0; i < particles.length; i++) {
            for (let j = i; j < particles.length; j++) {
              const dx = particles[i].x - particles[j].x;
              const dy = particles[i].y - particles[j].y;
              const distance = Math.sqrt(dx * dx + dy * dy);

              if (distance < 100) {
                particleCtx.beginPath();
                particleCtx.strokeStyle = colorMode === 0 ?
                  `rgba(0, 255, 0, ${0.2 - distance/500})` :
                  particles[i].color.replace(')', `, ${0.2 - distance/500})`).replace('hsl', 'hsla');
                particleCtx.lineWidth = 1;
                particleCtx.moveTo(particles[i].x, particles[i].y);
                particleCtx.lineTo(particles[j].x, particles[j].y);
                particleCtx.stroke();
              }
            }
          }

          // 更新并绘制粒子
          for (let i = 0; i < particles.length; i++) {
            particles[i].update();
            particles[i].draw();
          }
        }


        // 初始化粒子
        function initParticles() {
            particles = [];
            for (let i = 0; i < particleCount; i++) {
                particles.push(new Particle());
            }
        }
        
        initParticles();



        // 鼠标移动事件
        particleCanvas.addEventListener('mousemove', (e) => {
          mouseX = e.clientX;
          mouseY = e.clientY;
        });
        
        // 按钮事件
        // 更新按钮状态的函数
        function updateModeButtons() {
            const attractBtn = document.getElementById('attractBtn');
            const repelBtn = document.getElementById('repelBtn');
            
            if (mode === 0) {
                // 聚集模式
                attractBtn.classList.add('active');
                attractBtn.textContent = '✓ 聚集模式';
                repelBtn.classList.remove('active');
                repelBtn.textContent = '驱逐模式';
            } else {
                // 驱逐模式
                attractBtn.classList.remove('active');
                attractBtn.textContent = '聚集模式';
                repelBtn.classList.add('active');
                repelBtn.textContent = '✓ 驱逐模式';
            }
        }
        
        // 更新颜色按钮状态的函数
        function updateColorButtons() {
            const defaultColorBtn = document.getElementById('defaultColorBtn');
            const rainbowColorBtn = document.getElementById('rainbowColorBtn');
            
            if (colorMode === 0) {
                // 默认色
                defaultColorBtn.classList.add('active');
                defaultColorBtn.textContent = '✓ 默认色';
                rainbowColorBtn.classList.remove('active');
                rainbowColorBtn.textContent = '彩色';
            } else {
                // 彩色
                defaultColorBtn.classList.remove('active');
                defaultColorBtn.textContent = '默认色';
                rainbowColorBtn.classList.add('active');
                rainbowColorBtn.textContent = '✓ 彩色';
            }
        }
        
        // 聚集模式按钮
        document.getElementById('attractBtn').addEventListener('click', () => {
            mode = 0;
            updateModeButtons();
        });
        
        // 驱逐模式按钮
        document.getElementById('repelBtn').addEventListener('click', () => {
            mode = 1;
            updateModeButtons();
        });
        
        // 默认色按钮
        document.getElementById('defaultColorBtn').addEventListener('click', () => {
            colorMode = 0;
            updateColorButtons();
            initParticles();
        });
        
        // 彩色按钮
        document.getElementById('rainbowColorBtn').addEventListener('click', () => {
            colorMode = 1;
            updateColorButtons();
            initParticles();
        });
        
        document.getElementById('resetBtn').addEventListener('click', () => {
            initParticles();
        });
        
        // 动画循环
        function animate() {
            drawMatrix();
            drawTitle();
            drawParticles();
            requestAnimationFrame(animate);
        }

        // 添加键盘事件监听
        document.addEventListener('keydown', function(e) {
          // Alt+M 显示遮罩层
          if (e.altKey && e.key.toLowerCase() === 'm') {
            e.preventDefault();
            document.getElementById('overlay').style.display = 'flex';
          }

          // ESC 键关闭遮罩层
          if (e.key === 'Escape') {
            document.getElementById('overlay').style.display = 'none';
          }
        });

        // 点击关闭按钮关闭遮罩层
        document.getElementById('closeBtn').addEventListener('click', function() {
          document.getElementById('overlay').style.display = 'none';
        });

        // 点击遮罩层关闭
        document.getElementById('overlay').addEventListener('click', function(e) {
          if (e.target.id === 'overlay') {
            this.style.display = 'none';
          }
        });

        // 阻止遮罩层内容区域点击时关闭
        document.querySelector('.overlay-content').addEventListener('click', function(e) {
          e.stopPropagation();
        });
        
        // 初始化按钮状态
        updateModeButtons();
        updateColorButtons();

        animate();
    </script>
</body>
</html>

 

———— ⬆️·`正文结束`·⬆️————

 


到此这篇文章就介绍到这了,更多精彩内容请关注本人以前的文章或继续浏览下面的文章,创作不易,如果能帮助到大家,希望大家多多支持宝码香车~💕,若转载本文,一定注明本文链接。


整理不易,点赞关注宝码香车

更多专栏订阅推荐:
👍 html+css+js 绚丽效果
💕 vue
✈️ Electron
⭐️ js
📝 字符串
✍️ 时间对象(Date())操作

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐