1024程序员节:从代码艺术到数字世界的建造者, HTML+CSS+JavaScript Canvas代码雨 (文末附完整代码)
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎 点赞 + 收藏 + 关注 哦 💕
📚 运行
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);
这段代码完成了以下功能:
- 通过
getElementById获取三个画布元素。 - 通过
getContext('2d')获取2D绘图上下文,这是在canvas上绘制图形的基础。 - 定义
setCanvasSize函数,设置画布大小等于窗口大小,确保画布全屏显示。 - 监听窗口
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]++;
}
}
代码雨效果的实现原理如下:
- 定义字符集,包含二进制数字和与程序员节相关的中文字符,增强主题相关性。
- 根据画布宽度和字体大小计算列数,确定代码雨的密度。
- 初始化雨滴数组,每个元素代表一列雨滴的当前位置。
- 在
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);
}
标题动画的实现特点:
- 使用
clearRect清除画布内容,避免帧与帧之间的重叠。 - 主标题使用加粗字体和较大字号,突出显示节日主题。
- 通过
shadowColor和shadowBlur属性实现文本发光效果。 - 使用正弦函数计算发光强度,使发光效果随时间平滑变化,增强视觉吸引力。
- 副标题使用较浅的绿色和较小的字号,与主标题形成对比,同时保持整体风格一致。
- 标题居中显示,确保在不同屏幕尺寸下都能保持良好的视觉效果。
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.5到1.5,确保粒子向各个方向均匀运动。
- 颜色模式:支持两种颜色模式,默认绿色模式和随机彩色模式,通过
colorMode变量控制。 - 边界处理:采用循环边界模式,当粒子超出画布边界时,从对面重新进入,确保粒子系统的连续性。
- 鼠标交互:实现了两种交互模式——聚集模式和驱逐模式,粒子根据与鼠标的距离做出相应反应。
- 按压加速:根据鼠标按压时间计算加速因子,按压时间越长,粒子运动速度越快,增强交互的层次感。
- 扩散圆圈效果:当鼠标按压时,生成扩散圆圈,圈内粒子产生更强烈的交互效果,提升视觉冲击力。
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();
});
这些事件监听实现了以下交互功能:
- 鼠标移动:实时更新鼠标位置,为粒子系统提供交互目标。
- 鼠标按压/释放:触发充能效果和扩散圆圈,增强交互反馈。
- 键盘快捷键:支持Alt+M显示控制界面,ESC键关闭界面,提升操作效率。
- 按钮控制:提供模式选择、颜色切换和重置功能,方便用户调整效果。
- 遮罩层交互:支持点击关闭按钮、点击遮罩层空白区域关闭,以及阻止内容区域点击冒泡,确保交互逻辑的合理性。
1.4.6 动画循环
// 动画循环
function animate() {
drawMatrix();
drawTitle();
drawParticles();
requestAnimationFrame(animate);
}
animate();
动画循环是页面动态效果的核心驱动,通过requestAnimationFrame函数实现高效的动画渲染:
requestAnimationFrame会根据浏览器的刷新频率自动调整调用时机,通常为每秒60次,确保动画流畅且不浪费资源。- 每次循环依次调用
drawMatrix、drawTitle和drawParticles函数,更新三个画布的内容。 - 这种循环方式实现了三个独立效果的同步渲染,确保页面视觉效果的一致性。
📚 二、代码背后的技术思想与艺术价值
2.1 技术思想的体现
2.1.1 分层设计思想
页面采用了清晰的分层设计,通过三个独立的canvas元素实现不同的视觉效果,每个画布负责特定的功能:
- 底层(matrixCanvas):实现矩阵代码雨效果,作为页面的背景层。
- 中层(titleCanvas):显示节日标题,作为页面的信息层。
- 上层(particleCanvas):实现粒子系统和交互功能,作为页面的交互层。
这种分层设计具有以下优势:
- 功能解耦:每个层的功能独立,修改一个层的代码不会影响其他层,便于维护和扩展。
- 性能优化:可以针对不同层的复杂度调整渲染策略,提高整体性能。
- 视觉层次:通过z-index控制层的堆叠顺序,创造出丰富的视觉层次感。
2.1.2 面向对象编程思想
粒子系统的实现采用了面向对象编程(OOP)思想,通过Particle类封装粒子的属性和行为:
- 封装性:将粒子的位置、大小、速度、颜色等属性,以及更新、绘制等方法封装在类中,实现数据和行为的封装。
- 可扩展性:如果需要添加新的粒子效果,只需在类中添加相应的方法或属性,无需修改其他代码。
- 可维护性:类的结构清晰,代码逻辑易于理解和维护,便于后续修改和优化。
2.1.3 事件驱动编程思想
页面的交互功能基于事件驱动编程思想实现,通过监听用户的鼠标、键盘操作,触发相应的处理函数:
- 松耦合:事件触发者和处理者之间通过事件机制连接,无需直接依赖,降低了代码的耦合度。
- 响应式:能够实时响应用户的操作,提供即时反馈,提升用户体验。
- 可扩展性:可以轻松添加新的事件监听和处理函数,扩展页面的交互功能。
2.1.4 性能优化思想
代码中体现了多种性能优化思想,确保页面在各种设备上都能流畅运行:
- 高效渲染:使用
requestAnimationFrame实现高效的动画循环,避免使用setInterval导致的性能问题。 - 减少重绘:每个画布只更新必要的内容,例如粒子系统只清除和重绘粒子区域,而不是整个画布。
- 响应式调整:监听窗口大小变化,动态调整画布尺寸,确保在不同屏幕尺寸下都能保持最佳效果。
- 资源控制:限制粒子数量(150个),避免过多粒子导致的性能下降,平衡视觉效果和性能。
2.2 代码的艺术价值
2.2.1 视觉艺术:科技感与美感的结合
页面的视觉设计融合了科技感和艺术美感,创造出独特的视觉体验:
- 色彩搭配:黑色背景与绿色文本的搭配,模拟了终端界面的视觉效果,唤起程序员的职业共鸣,同时绿色的发光效果增添了科技感和未来感。
- 动态效果:矩阵代码雨、粒子系统、标题动画等动态效果,使页面充满活力,避免了静态页面的单调乏味。
- 视觉层次:通过三个画布的分层设计,创造出丰富的视觉层次,使页面具有深度感和立体感。
2.2.2 交互艺术:用户参与的创作过程
页面的交互设计将用户的操作融入到视觉效果中,使用户成为艺术创作的参与者:
- 实时反馈:用户的鼠标移动、按压操作会立即影响粒子的运动和扩散效果,提供即时反馈。
- 个性化体验:用户可以通过控制按钮选择不同的模式和颜色,定制自己喜欢的视觉效果。
- 沉浸感:全屏的视觉效果和丰富的交互反馈,使用户沉浸在数字世界中,体验代码带来的乐趣。
2.2.3 主题表达:程序员文化的体现
页面的设计充分体现了程序员文化的特点,传递了程序员节的主题:
- 符号元素:二进制数字、代码雨、终端风格等元素,都是程序员熟悉的符号,体现了程序员的职业特征。
- 文字内容:"代码创造世界,逻辑改变未来"等标语,表达了程序员对技术的热爱和对未来的愿景。
- 交互体验:通过代码实现的交互效果,展示了程序员用技术创造美好体验的能力,体现了"代码即艺术"的理念。
📚 三、程序员节的意义:从节日到文化
3.1 程序员节的起源与发展
1024程序员节起源于中国程序员群体的自发倡议,随着信息技术的发展,逐渐成为一个被广泛认可的行业节日。
3.1.1 起源:程序员的自我认同
1024程序员节的起源与程序员群体的自我认同密切相关。在互联网发展初期,程序员往往是幕后工作者,他们的贡献很少被公众关注和认可。为了提升程序员的职业认同感和社会关注度,一些程序员自发提议将10月24日定为程序员节,因为1024是计算机领域的重要数字,具有特殊的象征意义。
3.1.2 发展:行业与社会的认可
随着互联网行业的快速发展,程序员的作用日益凸显,1024程序员节也得到了越来越多的认可:
- 企业参与:许多互联网企业开始重视程序员节,通过举办活动、发放福利、表彰优秀程序员等方式,提升员工的归属感和幸福感。
- 媒体关注:主流媒体开始报道程序员节,关注程序员的工作状态和职业发展,提升了程序员群体的社会关注度。
- 文化形成:程序员节逐渐形成了独特的文化氛围,包括技术分享、代码创作、行业交流等活动,成为程序员群体交流和成长的平台。
3.2 程序员节的意义与价值
3.2.1 对程序员个人:职业认同与自我价值实现
程序员节对程序员个人而言,具有重要的意义:
- 职业认同:程序员节为程序员提供了一个展示自我的平台,让他们感受到自己的职业价值和社会认可,增强职业认同感和自豪感。
- 交流学习:在程序员节期间,各种技术分享、行业交流活动为程序员提供了学习和成长的机会,有助于提升专业技能和拓宽视野。
- 身心放松:程序员工作压力大、强度高,程序员节的各种活动可以让他们放松身心,缓解工作压力,保持良好的工作状态。
3.2.2 对企业:团队凝聚力与创新动力
对企业而言,程序员节是提升团队凝聚力和激发创新动力的重要契机:
- 团队建设:通过举办程序员节活动,企业可以增强团队成员之间的交流和合作,提升团队凝聚力和归属感。
- 人才激励:表彰优秀程序员、提供福利等方式,可以激励员工的工作积极性和创造力,提高工作效率和质量。
- 品牌形象:企业参与程序员节活动,展示对员工的关怀和对技术的重视,有助于提升企业的品牌形象和吸引力,吸引更多优秀人才。
3.2.3 对行业:技术交流与文化传承
程序员节对整个互联网行业而言,具有促进技术交流和文化传承的重要作用:
- 技术交流:各种技术分享、开源项目推广等活动,促进了行业内的技术交流和合作,推动了技术的创新和发展。
- 文化传承:程序员节逐渐形成了独特的行业文化,包括对技术的热爱、对创新的追求、对开源的支持等,这些文化理念通过节日活动得以传承和发扬。
- 行业发展:通过程序员节的活动,提升了整个行业的社会关注度和影响力,为行业的发展创造了良好的环境和氛围。
3.2.4 对社会:数字文明的推动力量
在数字时代,程序员作为数字世界的建造者,他们的工作对社会发展具有重要影响:
- 技术创新:程序员通过代码实现各种技术创新,推动了互联网、人工智能、大数据等领域的发展,改变了人们的生活方式和社会运行模式。
- 数字基建:从网站、APP到企业系统、国家政务平台,程序员构建了数字社会的基础设施,为社会的数字化转型提供了支撑。
- 社会进步:程序员开发的各种应用和系统,在教育、医疗、交通、金融等领域发挥了重要作用,推动了社会的进步和发展。
📚 四、程序员的使命与担当:在数字时代创造未来
4.1 程序员的核心使命
在数字时代,程序员的核心使命是通过技术创新和代码实现,构建数字世界,推动社会进步:
4.1.1 技术创新:突破技术边界
程序员是技术创新的核心力量,他们通过不断探索和实践,突破技术边界,推动技术的发展:
- 基础技术研发:在操作系统、编程语言、数据库等基础技术领域,程序员的研发工作为整个数字产业提供了技术基础。
- 应用技术创新:在人工智能、大数据、云计算、区块链等新兴领域,程序员通过创新的应用技术,开发出各种具有颠覆性的产品和服务。
- 技术优化升级:对现有技术进行优化和升级,提高系统的性能、安全性和可靠性,满足不断增长的用户需求。
4.1.2 产品实现:将想法变为现实
程序员的重要使命是将产品经理、设计师的想法和创意,通过代码转化为实际的产品和服务:
- 需求分析:深入理解用户需求和产品目标,将抽象的需求转化为具体的技术方案。
- 代码实现:根据技术方案,编写高质量的代码,实现产品的功能和性能要求。
- 测试优化:参与产品的测试和优化过程,确保产品的质量和用户体验,解决各种技术问题。
4.1.3 用户服务:创造价值体验
程序员的工作最终要服务于用户,通过技术手段为用户创造价值和良好的体验:
-
用户体验优化:关注用户的使用习惯和需求,通过技术手段优化产品的界面、交互和性能,提升用户体验。
-
问题解决:快速响应用户反馈的问题,通过技术手段修复漏洞、优化功能,确保用户能够正常使用产品。
-
价值创造:通过开发实用的功能和服务,为用户的工作、学习和生活提供便利,创造实际价值。
4.2 程序员的时代担当
在数字化浪潮席卷全球的今天,程序员作为数字世界的建造者,肩负着重要的时代担当:
4.2.1 推动数字化转型
随着数字经济的发展,传统行业的数字化转型已成为必然趋势。程序员在这一过程中扮演着关键角色:
- 传统行业赋能:为制造业、农业、服务业等传统行业开发数字化系统,实现生产、管理、营销等环节的数字化,提高效率、降低成本。
- 数字基础设施建设:参与建设云计算、大数据中心、物联网等数字基础设施,为传统行业的数字化转型提供技术支撑。
- 数字化人才培养:通过技术分享、开源项目等方式,培养更多数字化人才,为传统行业的数字化转型提供人才保障。
4.2.2 保障网络安全
在数字时代,网络安全至关重要。程序员作为数字系统的构建者,有责任保障系统的安全性:
- 安全开发:在系统开发过程中,遵循安全开发规范,采用安全的技术和架构,从源头防范安全风险。
- 漏洞修复:及时发现和修复系统中的安全漏洞,防止黑客攻击和数据泄露。
- 安全意识普及:向用户和企业普及网络安全知识,提高安全意识,共同营造安全的网络环境。
4.2.3 推动可持续发展
程序员可以通过技术手段,为实现可持续发展目标贡献力量:
- 绿色技术开发:开发节能、环保的技术和产品,降低能源消耗和环境影响。例如,优化数据中心的能源管理系统,减少能源浪费。
- 资源优化配置:利用大数据、人工智能等技术,实现资源的优化配置,提高资源利用效率。例如,通过智能交通系统优化交通流量,减少交通拥堵和碳排放。
- 公益项目开发:参与开发公益性质的技术项目,为教育、医疗、扶贫等公益事业提供技术支持,推动社会公平和可持续发展。
📚 五、总结与展望
5.1 总结:代码铸就的数字世界
通过对1024程序员节主题页面代码的深入解析,我们不仅了解了前端开发的技术细节,更感受到了代码背后蕴含的技术思想和艺术价值。这段代码以简洁高效的方式,实现了矩阵代码雨、粒子系统、标题动画等丰富的视觉效果和交互功能,展现了程序员将逻辑思维转化为视觉艺术的创造力。
1024程序员节从最初的行业自发倡议,发展到如今被广泛认可的行业节日,不仅体现了程序员群体的自我认同和职业自豪感,更反映了社会对程序员群体的重视和认可。在数字时代,程序员作为数字世界的建造者,肩负着技术创新、产品实现、用户服务的核心使命,同时也承担着推动数字化转型、保障网络安全、促进可持续发展的时代担当。
回顾程序员行业的发展历程,我们看到了技术的飞速进步和程序员群体的不断成长。从早期的汇编语言到如今的高级编程语言,从单机应用到分布式系统,从互联网到人工智能,每一次技术变革都离不开程序员的辛勤付出。他们用代码构建了数字世界的基础设施,用逻辑解决了现实世界的复杂问题,用创新改变了人们的生活方式。
5.2 展望:未来程序员的机遇与挑战
随着技术的不断发展,未来程序员行业将面临更多的机遇和挑战:
5.2.1 技术变革带来的机遇
- 新兴技术领域的崛起:人工智能、大数据、云计算、区块链、元宇宙等新兴技术领域的快速发展,将为程序员提供更多的就业机会和发展空间。这些领域需要大量具备专业技能的程序员,开发创新的技术和产品,推动行业的发展。
- 跨领域融合的需求:随着技术与各行业的深度融合,对具备跨领域知识的程序员需求将不断增加。例如,医疗健康领域需要既懂医学知识又懂信息技术的程序员,开发医疗信息化系统和医疗人工智能产品;金融领域需要既懂金融知识又懂区块链技术的程序员,开发金融科技产品。
- 开源生态的繁荣:开源生态的不断繁荣,为程序员提供了更多的学习和合作机会。程序员可以通过参与开源项目,提升自己的技术水平,积累项目经验,同时也可以与全球的开发者合作,共同推动技术的创新和发展。
5.2.2 行业发展面临的挑战
- 技术更新速度加快:随着技术的快速发展,编程语言、框架、工具等不断更新迭代,程序员需要不断学习和掌握新的技术,才能适应行业的发展需求。这对程序员的学习能力和适应能力提出了更高的要求。
- 职业竞争日益激烈:随着程序员群体的不断扩大,行业竞争日益激烈。企业对程序员的技术水平、项目经验、综合素质等要求越来越高,程序员需要不断提升自己的竞争力,才能在行业中立足。
- 工作压力与身心健康:程序员工作强度大、压力高,长期的高强度工作容易导致身心健康问题。如何平衡工作与生活,保持良好的身心健康,成为程序员需要面对的重要挑战。
5.3 对未来程序员的建议
面对未来的机遇与挑战,作为新时代的程序员,需要不断提升自己,适应行业的发展需求:
- 保持持续学习的热情:技术更新速度加快,程序员需要保持持续学习的热情,不断学习新的编程语言、框架、工具和技术理念,提升自己的技术水平。可以通过阅读技术书籍、参加技术培训、关注技术博客和开源项目等方式,获取最新的技术知识。
- 培养跨领域的知识储备:随着技术与各行业的深度融合,具备跨领域知识的程序员将更具竞争力。程序员可以根据自己的兴趣和职业规划,学习相关领域的知识,例如金融、医疗、教育等,培养跨领域的思维和能力。
- 注重代码质量和安全:代码质量和安全是程序员工作的核心要求。程序员需要遵循编码规范,编写高质量、可维护、安全的代码,确保系统的稳定性和安全性。同时,要重视代码审查和测试工作,及时发现和修复代码中的问题。
- 关注用户需求和体验:技术最终要服务于用户,程序员需要关注用户的需求和体验,从用户的角度出发,开发出满足用户需求、提升用户体验的产品和服务。可以通过用户调研、用户反馈等方式,了解用户的需求和痛点,不断优化产品和服务。
- 保持身心健康和工作生活平衡:身心健康是程序员工作和生活的基础。程序员需要合理安排工作时间,避免过度加班,保持良好的作息习惯。同时,要适当参加体育锻炼和社交活动,缓解工作压力,保持身心健康和工作生活的平衡。
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">×</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())操作
更多推荐

所有评论(0)