document.addEventListener('DOMContentLoaded', function() { initCodeFlowBackground(); initFloatingElements(); initTypingEffect(); initParticleEffects(); initCyberTrail(); }); // 代码流动背景效果 function initCodeFlowBackground() { const codeFlowContainer = document.querySelector('.matrix-code-rain'); // 如果没有容器则创建 if (!codeFlowContainer) { const container = document.createElement('div'); container.className = 'matrix-code-rain'; container.id = 'codeRain'; document.body.appendChild(container); } else { // 清空容器 codeFlowContainer.innerHTML = ''; } // 创建代码列 for (let i = 0; i < 50; i++) { createCodeColumn(codeFlowContainer); } } // 创建单个代码列 function createCodeColumn(container) { const column = document.createElement('div'); column.className = 'code-column'; // 随机代码内容 const codeLength = Math.floor(Math.random() * 30) + 20; let codeContent = ''; for (let i = 0; i < codeLength; i++) { const randomChar = getRandomCodeChar(); codeContent += `${randomChar}`; } column.innerHTML = codeContent; // 随机位置和动画 const leftPos = Math.random() * 100; const duration = Math.random() * 20 + 10; const delay = Math.random() * 5; column.style.left = `${leftPos}%`; column.style.animationDuration = `${duration}s`; column.style.animationDelay = `${delay}s`; container.appendChild(column); } // 获取随机代码字符 function getRandomCodeChar() { const codeChars = '01{}[]()<>/*-+!&|~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; return codeChars.charAt(Math.floor(Math.random() * codeChars.length)); } // 初始化浮动元素 function initFloatingElements() { // 创建技术图标浮动元素 const techIcons = [ 'html5', 'css3', 'js', 'vue', 'react', 'node', 'db', 'cloud', 'security', 'network', 'ai', 'iot' ]; const containers = document.querySelectorAll('.tech-background'); containers.forEach(container => { // 为每个容器创建6-10个随机技术图标 const numIcons = Math.floor(Math.random() * 5) + 6; for (let i = 0; i < numIcons; i++) { const icon = document.createElement('div'); const randomIcon = techIcons[Math.floor(Math.random() * techIcons.length)]; icon.className = `floating-tech tech-${randomIcon}`; icon.innerHTML = ``; // 随机位置 const posX = Math.random() * 80 + 10; const posY = Math.random() * 80 + 10; // 随机大小 const size = Math.random() * 30 + 20; // 随机动画参数 const duration = Math.random() * 30 + 20; const delay = Math.random() * 10; icon.style.left = `${posX}%`; icon.style.top = `${posY}%`; icon.style.width = `${size}px`; icon.style.height = `${size}px`; icon.style.animationDuration = `${duration}s`; icon.style.animationDelay = `${delay}s`; container.appendChild(icon); } }); } // 打字效果 function initTypingEffect() { const typingElements = document.querySelectorAll('.typing-effect'); typingElements.forEach(element => { const text = element.getAttribute('data-text') || element.textContent; element.textContent = ''; let index = 0; const typingSpeed = parseInt(element.getAttribute('data-speed')) || 50; function typeNextChar() { if (index < text.length) { element.textContent += text.charAt(index); index++; setTimeout(typeNextChar, typingSpeed); } else { // 添加光标闪烁效果 element.classList.add('typing-done'); // 如果需要重复打字效果 if (element.hasAttribute('data-repeat')) { setTimeout(() => { element.textContent = ''; index = 0; typeNextChar(); }, 2000); } } } // 延迟开始 const delay = parseInt(element.getAttribute('data-delay')) || 0; setTimeout(typeNextChar, delay); }); } // 粒子效果 function initParticleEffects() { const containers = document.querySelectorAll('.particle-container'); containers.forEach(container => { // 创建20-40个粒子 const numParticles = Math.floor(Math.random() * 20) + 20; for (let i = 0; i < numParticles; i++) { createParticle(container); } }); } // 创建单个粒子 function createParticle(container) { const particle = document.createElement('div'); particle.className = 'particle'; // 随机大小 const size = Math.random() * 6 + 2; // 随机颜色 const colors = ['rgba(0, 255, 255, ', 'rgba(0, 191, 255, ', 'rgba(0, 128, 255, ', 'rgba(0, 255, 217, ']; const randomColor = colors[Math.floor(Math.random() * colors.length)]; const opacity = Math.random() * 0.5 + 0.3; // 随机位置 const posX = Math.random() * 100; const posY = Math.random() * 100; // 随机动画参数 const duration = Math.random() * 15 + 10; const delay = Math.random() * 5; particle.style.width = `${size}px`; particle.style.height = `${size}px`; particle.style.backgroundColor = `${randomColor}${opacity})`; particle.style.left = `${posX}%`; particle.style.top = `${posY}%`; particle.style.animationDuration = `${duration}s`; particle.style.animationDelay = `${delay}s`; container.appendChild(particle); // 动画结束后重新创建 particle.addEventListener('animationend', () => { container.removeChild(particle); createParticle(container); }); } // 赛博朋克鼠标拖尾效果 function initCyberTrail() { // 创建拖尾容器 const trailContainer = document.createElement('div'); trailContainer.className = 'cyber-trail-container'; document.body.appendChild(trailContainer); // 鼠标跟踪数组 const trail = []; const trailLength = 20; // 拖尾长度 let mouseX = 0; let mouseY = 0; let isClicking = false; // 存储所有创建的粒子元素,用于清理 const allParticles = []; // 定期清理超时的粒子 setInterval(() => { const now = Date.now(); while (allParticles.length > 0 && allParticles[0].expireTime < now) { const particle = allParticles.shift(); if (particle.element && particle.element.parentNode) { particle.element.parentNode.removeChild(particle.element); } } }, 1000); // 鼠标移动事件 document.addEventListener('mousemove', (e) => { mouseX = e.clientX; mouseY = e.clientY; // 移动时偶尔创建额外粒子 if (Math.random() < 0.1) { // 只在有效区域内创建闪光粒子,避开边缘 if (mouseX > 50 && mouseX < window.innerWidth - 50 && mouseY > 50 && mouseY < window.innerHeight - 50) { createTrailSparkle(mouseX, mouseY); } } }); // 鼠标点击事件 - 创建爆炸效果 document.addEventListener('mousedown', (e) => { isClicking = true; // 只在有效区域内创建爆炸效果,避开边缘 if (e.clientX > 50 && e.clientX < window.innerWidth - 50 && e.clientY > 50 && e.clientY < window.innerHeight - 50) { createClickBurst(e.clientX, e.clientY); } }); document.addEventListener('mouseup', () => { isClicking = false; }); // 创建初始拖尾粒子 for (let i = 0; i < trailLength; i++) { const particle = document.createElement('div'); particle.className = 'cyber-trail-particle'; particle.style.opacity = '0'; // 初始不可见 trailContainer.appendChild(particle); trail.push({ element: particle, x: 0, y: 0, }); } // 更新拖尾位置 function updateTrail() { // 更新第一个粒子到鼠标位置 trail[0].x = mouseX; trail[0].y = mouseY; // 更新其他粒子,跟随前一个粒子 for (let i = 1; i < trail.length; i++) { const dx = trail[i-1].x - trail[i].x; const dy = trail[i-1].y - trail[i].y; // 点击时粒子加速移动 const speedFactor = isClicking ? 0.35 : 0.2; trail[i].x += dx * speedFactor; trail[i].y += dy * speedFactor; // 设置粒子位置 const particle = trail[i].element; // 只有鼠标移动后才显示粒子 if (mouseX > 0 || mouseY > 0) { particle.style.opacity = '1'; particle.style.left = trail[i].x + 'px'; particle.style.top = trail[i].y + 'px'; // 根据距离调整大小和透明度 const scale = 1 - (i / trail.length) * 0.8; const opacity = 1 - (i / trail.length) * 0.9; particle.style.transform = `scale(${scale})`; particle.style.opacity = opacity; } } requestAnimationFrame(updateTrail); } // 创建闪光粒子 function createTrailSparkle(x, y) { const sparkle = document.createElement('div'); sparkle.className = 'cyber-trail-sparkle'; sparkle.style.left = x + 'px'; sparkle.style.top = y + 'px'; // 随机位置偏移 const offsetX = (Math.random() - 0.5) * 40; const offsetY = (Math.random() - 0.5) * 40; // 随机大小 const size = 3 + Math.random() * 6; sparkle.style.width = size + 'px'; sparkle.style.height = size + 'px'; trailContainer.appendChild(sparkle); // 记录这个粒子和它的过期时间 allParticles.push({ element: sparkle, expireTime: Date.now() + 1000 }); // 动画 setTimeout(() => { if (sparkle.parentNode) { sparkle.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(0)`; sparkle.style.opacity = 0; } }, 10); // 移除元素 setTimeout(() => { if (sparkle.parentNode) { sparkle.parentNode.removeChild(sparkle); } }, 1000); } // 鼠标点击爆炸效果 function createClickBurst(x, y) { const burstCount = 15; for (let i = 0; i < burstCount; i++) { const burst = document.createElement('div'); burst.className = 'cyber-trail-burst'; burst.style.left = x + 'px'; burst.style.top = y + 'px'; // 随机角度和距离 const angle = (Math.PI * 2) * (i / burstCount); const distance = 30 + Math.random() * 70; const speedX = Math.cos(angle) * distance; const speedY = Math.sin(angle) * distance; // 随机大小 const size = 5 + Math.random() * 10; burst.style.width = size + 'px'; burst.style.height = size + 'px'; trailContainer.appendChild(burst); // 记录这个粒子和它的过期时间 allParticles.push({ element: burst, expireTime: Date.now() + 1000 }); // 动画 setTimeout(() => { if (burst.parentNode) { burst.style.transform = `translate(${speedX}px, ${speedY}px) scale(0)`; burst.style.opacity = 0; } }, 10); // 移除元素 setTimeout(() => { if (burst.parentNode) { burst.parentNode.removeChild(burst); } }, 1000); } } // 开始动画 updateTrail(); // 页面可见性变化时清理所有粒子 document.addEventListener('visibilitychange', () => { if (document.hidden) { // 清理所有粒子 allParticles.forEach(particle => { if (particle.element && particle.element.parentNode) { particle.element.parentNode.removeChild(particle.element); } }); allParticles.length = 0; // 重置拖尾位置 for (let i = 0; i < trail.length; i++) { trail[i].x = 0; trail[i].y = 0; const particle = trail[i].element; particle.style.opacity = '0'; } } }); } // 3D 图表效果初始化 function init3DCharts() { const chartContainers = document.querySelectorAll('.chart-3d'); chartContainers.forEach(container => { const type = container.getAttribute('data-chart-type') || 'bar'; const values = container.getAttribute('data-values').split(',').map(v => parseInt(v)); switch(type) { case 'bar': create3DBarChart(container, values); break; case 'pie': create3DPieChart(container, values); break; default: create3DBarChart(container, values); } }); } // 创建3D柱状图 function create3DBarChart(container, values) { const maxValue = Math.max(...values); const chart = document.createElement('div'); chart.className = 'chart-bars'; values.forEach((value, index) => { const bar = document.createElement('div'); bar.className = 'chart-bar'; const height = (value / maxValue) * 100; bar.style.height = `${height}%`; // 3D 效果 const barFront = document.createElement('div'); barFront.className = 'bar-front'; const barTop = document.createElement('div'); barTop.className = 'bar-top'; const barSide = document.createElement('div'); barSide.className = 'bar-side'; // 随机色调(保持蓝绿色系) const hue = 180 + Math.random() * 40; barFront.style.backgroundColor = `hsla(${hue}, 100%, 50%, 0.7)`; barTop.style.backgroundColor = `hsla(${hue}, 100%, 60%, 0.7)`; barSide.style.backgroundColor = `hsla(${hue}, 100%, 40%, 0.7)`; bar.appendChild(barFront); bar.appendChild(barTop); bar.appendChild(barSide); // 添加数值标签 const label = document.createElement('div'); label.className = 'bar-label'; label.textContent = value; bar.appendChild(label); chart.appendChild(bar); }); container.appendChild(chart); } // 创建3D饼图 function create3DPieChart(container, values) { const chart = document.createElement('div'); chart.className = 'pie-chart'; const total = values.reduce((acc, val) => acc + val, 0); let startAngle = 0; values.forEach((value, index) => { const slice = document.createElement('div'); slice.className = 'pie-slice'; const angle = (value / total) * 360; const endAngle = startAngle + angle; // 随机色调(保持蓝绿色系) const hue = 180 + Math.random() * 40; slice.style.background = `conic-gradient(hsla(${hue}, 100%, 50%, 0.7) ${startAngle}deg, hsla(${hue}, 100%, 50%, 0.7) ${endAngle}deg, transparent ${endAngle}deg)`; chart.appendChild(slice); startAngle = endAngle; }); container.appendChild(chart); }