// ==UserScript== // @name 网页趣味特效大师 ✨ // @namespace http://tampermonkey.net/ // @version 1.0001 // @description 为你的网页浏览增添趣味!包含鼠标粒子特效、彩虹轨迹、元素弹跳动画和星星飘落效果,让上网变得更有趣! // @author 半竹 // @match *://*/* // @grant none // @license MIT // @icon data:image/svg+xml,🎉 // ==/UserScript== (function() { 'use strict'; // ============================================ // 🎉 网页趣味特效大师 - 让浏览更有趣! // ============================================ const CONFIG = { particleCount: 12, // 点击产生的粒子数量 trailLength: 20, // 鼠标轨迹长度 starCount: 15, // 同时显示的星星数量 floatCount: 8, // 漂浮表情数量 loadEffect: true, // 是否启用页面加载特效 timeDisplay: true, // 是否显示时间 weatherEffect: true, // 是否启用天气效果 soundEffect: true, // 是否启用音效 dynamicBackground: true, // 是否启用动态背景 hoverEffect: true, // 是否启用鼠标悬停特效 keyboardEffect: true, // 是否启用键盘特效 themeToggle: true, // 是否启用主题切换 enableParticles: true, // 是否启用粒子效果 enableTrail: true, // 是否启用彩虹轨迹 enableBounce: true, // 是否启用弹跳效果 enableStars: true, // 是否启用星星效果 enableFloat: true, // 是否启用漂浮表情 enableScroll: true // 是否启用滚动特效 }; // 创建特效容器 const container = document.createElement('div'); container.id = 'fun-effects-container'; container.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 9999999; overflow: hidden; `; document.body.appendChild(container); // ============================================ // 🎨 工具函数 // ============================================ // 随机颜色生成器 function getRandomColor() { const hue = Math.random() * 360; return `hsl(${hue}, 70%, 60%)`; } // 随机数生成器 function random(min, max) { return Math.random() * (max - min) + min; } // ============================================ // 💥 点击粒子爆炸效果 // ============================================ class Particle { constructor(x, y) { this.x = x; this.y = y; this.size = random(5, 12); this.speedX = random(-8, 8); this.speedY = random(-8, 8); this.color = getRandomColor(); this.life = 1; this.decay = random(0.015, 0.03); this.gravity = 0.2; this.element = document.createElement('div'); this.element.style.cssText = ` position: absolute; width: ${this.size}px; height: ${this.size}px; background: ${this.color}; border-radius: 50%; pointer-events: none; box-shadow: 0 0 10px ${this.color}; `; container.appendChild(this.element); } update() { this.x += this.speedX; this.y += this.speedY; this.speedY += this.gravity; this.life -= this.decay; this.size *= 0.98; this.element.style.left = this.x + 'px'; this.element.style.top = this.y + 'px'; this.element.style.transform = `scale(${this.life})`; this.element.style.opacity = this.life; return this.life > 0; } destroy() { this.element.remove(); } } let particles = []; function createExplosion(x, y) { if (!CONFIG.enableParticles) return; for (let i = 0; i < CONFIG.particleCount; i++) { particles.push(new Particle(x, y)); } } // ============================================ // 🌈 鼠标彩虹轨迹 // ============================================ class TrailDot { constructor(x, y, hue) { this.x = x; this.y = y; this.hue = hue; this.life = 1; this.element = document.createElement('div'); this.element.style.cssText = ` position: absolute; width: 8px; height: 8px; background: hsl(${hue}, 80%, 60%); border-radius: 50%; pointer-events: none; box-shadow: 0 0 15px hsl(${hue}, 80%, 60%); left: ${x}px; top: ${y}px; `; container.appendChild(this.element); } update() { this.life -= 0.05; this.element.style.opacity = this.life; this.element.style.transform = `scale(${this.life})`; return this.life > 0; } destroy() { this.element.remove(); } } let trail = []; let hue = 0; function addTrailPoint(x, y) { if (!CONFIG.enableTrail) return; trail.push(new TrailDot(x, y, hue)); hue = (hue + 10) % 360; if (trail.length > CONFIG.trailLength) { trail[0].destroy(); trail.shift(); } } // ============================================ // 🎯 元素弹跳效果 // ============================================ function addBounceEffect(element) { if (!CONFIG.enableBounce) return; element.style.animation = 'none'; element.offsetHeight; // 触发重排 element.style.animation = 'funBounce 0.6s ease'; setTimeout(() => { element.style.animation = ''; }, 600); } // 添加弹跳动画样式 const style = document.createElement('style'); style.textContent = ` @keyframes funBounce { 0%, 100% { transform: scale(1); } 25% { transform: scale(1.2) rotate(-5deg); } 50% { transform: scale(0.9) rotate(5deg); } 75% { transform: scale(1.1) rotate(-3deg); } } @keyframes twinkle { 0%, 100% { opacity: 0.3; transform: scale(1); } 50% { opacity: 1; transform: scale(1.2); } } @keyframes fall { 0% { transform: translateY(-100px) rotate(0deg); } 100% { transform: translateY(100vh) rotate(360deg); } } @keyframes float { 0%, 100% { transform: translateY(0px) rotate(0deg); } 25% { transform: translateY(-15px) rotate(5deg); } 50% { transform: translateY(5px) rotate(0deg); } 75% { transform: translateY(-10px) rotate(-5deg); } } @keyframes scrollEffect { 0% { transform: translateY(0) scale(0.8); opacity: 0; } 50% { transform: translateY(-20px) scale(1); opacity: 1; } 100% { transform: translateY(-40px) scale(1.2); opacity: 0; } } @keyframes loadEffect { 0% { transform: scale(0.3) rotate(0deg); opacity: 0; } 50% { transform: scale(1.2) rotate(180deg); opacity: 1; } 100% { transform: scale(1) rotate(360deg); opacity: 0; } } @keyframes weatherEffect { 0% { transform: translateX(-100px) translateY(-50px); opacity: 0; } 50% { transform: translateX(0) translateY(0); opacity: 1; } 100% { transform: translateX(100px) translateY(50px); opacity: 0; } } @keyframes timePulse { 0%, 100% { transform: scale(1); opacity: 0.8; } 50% { transform: scale(1.05); opacity: 1; } } @keyframes dynamicBackground { 0% { background-position: 0% 0%; } 50% { background-position: 100% 100%; } 100% { background-position: 0% 0%; } } @keyframes hoverEffect { 0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); } } @keyframes keyboardEffect { 0% { transform: translateY(0) scale(1); opacity: 1; } 100% { transform: translateY(-30px) scale(1.2); opacity: 0; } } @keyframes themeToggle { 0% { transform: rotate(0deg) scale(1); } 50% { transform: rotate(180deg) scale(1.2); } 100% { transform: rotate(360deg) scale(1); } } `; document.head.appendChild(style); // ============================================ // ⭐ 飘落星星效果 // ============================================ class Star { constructor() { this.reset(); this.element = document.createElement('div'); this.element.innerHTML = ['⭐', '✨', '🌟', '💫'][Math.floor(Math.random() * 4)]; this.element.style.cssText = ` position: absolute; font-size: ${this.size}px; left: ${this.x}px; top: ${this.y}px; opacity: ${this.opacity}; pointer-events: none; animation: fall ${this.speed}s linear infinite, twinkle 2s ease-in-out infinite; z-index: 9999998; `; container.appendChild(this.element); } reset() { this.x = random(0, window.innerWidth); this.y = -50; this.size = random(15, 30); this.speed = random(8, 20); this.opacity = random(0.4, 1); } checkReset() { const rect = this.element.getBoundingClientRect(); if (rect.top > window.innerHeight) { this.reset(); this.element.style.left = this.x + 'px'; this.element.style.top = this.y + 'px'; this.element.style.animation = `fall ${this.speed}s linear infinite, twinkle 2s ease-in-out infinite`; } } } let stars = []; function initStars() { if (!CONFIG.enableStars) return; for (let i = 0; i < CONFIG.starCount; i++) { setTimeout(() => { const star = new Star(); star.y = random(-window.innerHeight, 0); star.element.style.top = star.y + 'px'; stars.push(star); }, i * 300); } } // ============================================ // ⌨️ 打字特效 // ============================================ function createTypeEffect(x, y) { const chars = ['✦', '✧', '★', '☆', '✯', '✡', '✵', '✶']; const char = chars[Math.floor(Math.random() * chars.length)]; const el = document.createElement('div'); el.textContent = char; el.style.cssText = ` position: absolute; left: ${x}px; top: ${y}px; color: ${getRandomColor()}; font-size: 20px; pointer-events: none; animation: typeFloat 1s ease-out forwards; z-index: 9999999; `; container.appendChild(el); setTimeout(() => el.remove(), 1000); } // 添加打字浮动动画 const typeStyle = document.createElement('style'); typeStyle.textContent = ` @keyframes typeFloat { 0% { transform: translateY(0) scale(1); opacity: 1; } 100% { transform: translateY(-30px) scale(1.5); opacity: 0; } } `; document.head.appendChild(typeStyle); // ============================================ // 🎛️ 控制面板 // ============================================ function createControlPanel() { const panel = document.createElement('div'); panel.id = 'fun-effects-panel'; panel.style.cssText = ` position: fixed; top: 20px; right: 20px; background: linear-gradient(135deg, #ff6b6b 0%, #4ecdc4 100%); padding: 15px; border-radius: 15px; box-shadow: 0 10px 40px rgba(0,0,0,0.3); z-index: 10000000; font-family: 'Segoe UI', system-ui, sans-serif; color: white; min-width: 180px; backdrop-filter: blur(10px); `; panel.innerHTML = `
🎉 特效控制面板
双击任意元素试试看!
`; document.body.appendChild(panel); // 绑定控制事件 panel.querySelector('#toggle-particles').addEventListener('change', (e) => { CONFIG.enableParticles = e.target.checked; }); panel.querySelector('#toggle-trail').addEventListener('change', (e) => { CONFIG.enableTrail = e.target.checked; if (!e.target.checked) { trail.forEach(t => t.destroy()); trail = []; } }); panel.querySelector('#toggle-bounce').addEventListener('change', (e) => { CONFIG.enableBounce = e.target.checked; }); panel.querySelector('#toggle-stars').addEventListener('change', (e) => { CONFIG.enableStars = e.target.checked; stars.forEach(s => s.element.style.display = e.target.checked ? 'block' : 'none'); }); panel.querySelector('#toggle-float').addEventListener('change', (e) => { CONFIG.enableFloat = e.target.checked; floatEmojis.forEach(emoji => emoji.element.style.display = e.target.checked ? 'block' : 'none'); }); panel.querySelector('#toggle-scroll').addEventListener('change', (e) => { CONFIG.enableScroll = e.target.checked; }); panel.querySelector('#toggle-load').addEventListener('change', (e) => { CONFIG.loadEffect = e.target.checked; }); panel.querySelector('#toggle-time').addEventListener('change', (e) => { CONFIG.timeDisplay = e.target.checked; if (timeElement) { timeElement.style.display = e.target.checked ? 'block' : 'none'; } }); panel.querySelector('#toggle-weather').addEventListener('change', (e) => { CONFIG.weatherEffect = e.target.checked; }); panel.querySelector('#toggle-sound').addEventListener('change', (e) => { CONFIG.soundEffect = e.target.checked; }); panel.querySelector('#toggle-background').addEventListener('change', (e) => { CONFIG.dynamicBackground = e.target.checked; if (backgroundElement) { backgroundElement.style.display = e.target.checked ? 'block' : 'none'; } }); panel.querySelector('#toggle-hover').addEventListener('change', (e) => { CONFIG.hoverEffect = e.target.checked; }); panel.querySelector('#toggle-keyboard').addEventListener('change', (e) => { CONFIG.keyboardEffect = e.target.checked; }); panel.querySelector('#toggle-theme').addEventListener('change', (e) => { CONFIG.themeToggle = e.target.checked; const themeButton = document.getElementById('fun-effects-theme'); if (themeButton) { themeButton.style.display = e.target.checked ? 'block' : 'none'; } }); // 面板拖拽功能 let isDragging = false; let currentX, currentY, initialX, initialY; panel.addEventListener('mousedown', (e) => { if (e.target.tagName === 'INPUT') return; isDragging = true; initialX = e.clientX - panel.offsetLeft; initialY = e.clientY - panel.offsetTop; }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; e.preventDefault(); currentX = e.clientX - initialX; currentY = e.clientY - initialY; panel.style.left = currentX + 'px'; panel.style.top = currentY + 'px'; panel.style.right = 'auto'; }); document.addEventListener('mouseup', () => { isDragging = false; }); } // ============================================ // 🚀 事件监听与动画循环 // ============================================ // 鼠标点击 - 粒子爆炸 document.addEventListener('click', (e) => { createExplosion(e.clientX, e.clientY); playSound('click'); }); // 鼠标移动 - 彩虹轨迹 let lastTrailTime = 0; document.addEventListener('mousemove', (e) => { const now = Date.now(); if (now - lastTrailTime > 20) { addTrailPoint(e.clientX, e.clientY); lastTrailTime = now; } }); // 双击 - 元素弹跳 document.addEventListener('dblclick', (e) => { const target = e.target; if (target && target !== container && !target.closest('#fun-effects-panel')) { addBounceEffect(target); createExplosion(e.clientX, e.clientY); playSound('bounce'); } }); // 键盘输入 - 打字特效 document.addEventListener('keydown', (e) => { if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable) { const rect = e.target.getBoundingClientRect(); createTypeEffect( rect.left + random(0, rect.width), rect.top + random(0, rect.height) ); } }); // 滚动 - 滚动特效 window.addEventListener('scroll', createScrollEffect); // 动画循环 function animate() { // 更新粒子 particles = particles.filter(particle => { const alive = particle.update(); if (!alive) particle.destroy(); return alive; }); // 更新轨迹 trail = trail.filter(dot => { const alive = dot.update(); if (!alive) dot.destroy(); return alive; }); // 检查星星 stars.forEach(star => star.checkReset()); requestAnimationFrame(animate); } // ============================================ // 😊 漂浮表情效果 // ============================================ class FloatEmoji { constructor() { this.reset(); this.element = document.createElement('div'); this.element.innerHTML = ['😀', '😃', '😄', '😁', '😆', '😅', '🤣', '😂', '🙂', '🙃', '😉', '😊', '😇', '🥰', '😍', '🤩', '😘', '😗', '😚', '😙'][Math.floor(Math.random() * 20)]; this.element.style.cssText = ` position: absolute; font-size: ${this.size}px; left: ${this.x}px; top: ${this.y}px; pointer-events: none; animation: float ${this.speed}s ease-in-out infinite; z-index: 9999997; `; container.appendChild(this.element); } reset() { this.x = random(0, window.innerWidth); this.y = random(0, window.innerHeight); this.size = random(20, 40); this.speed = random(3, 6); } } let floatEmojis = []; function initFloatEmojis() { if (!CONFIG.enableFloat) return; for (let i = 0; i < CONFIG.floatCount; i++) { setTimeout(() => { floatEmojis.push(new FloatEmoji()); }, i * 500); } } // ============================================ // 📜 滚动特效 // ============================================ let lastScrollY = window.scrollY; function createScrollEffect() { if (!CONFIG.enableScroll) return; const scrollY = window.scrollY; if (Math.abs(scrollY - lastScrollY) > 50) { const emoji = ['🚀', '✨', '🌟', '⚡', '🎈', '🌈', '💨', '💫'][Math.floor(Math.random() * 8)]; const el = document.createElement('div'); el.innerHTML = emoji; el.style.cssText = ` position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 40px; pointer-events: none; animation: scrollEffect 1s ease-out forwards; z-index: 9999999; `; container.appendChild(el); setTimeout(() => el.remove(), 1000); lastScrollY = scrollY; playSound('scroll'); } } // ============================================ // 🎉 页面加载特效 // ============================================ function createLoadEffect() { if (!CONFIG.loadEffect) return; const loadEmojis = ['🎉', '✨', '🌟', '🚀', '🎈', '🎊', '🎯', '⚡']; const emoji = loadEmojis[Math.floor(Math.random() * loadEmojis.length)]; const loadElement = document.createElement('div'); loadElement.innerHTML = emoji; loadElement.style.cssText = ` position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 80px; pointer-events: none; animation: loadEffect 2s ease-out forwards; z-index: 99999999; `; container.appendChild(loadElement); setTimeout(() => loadElement.remove(), 2000); playSound('load'); } // ============================================ // 🕒 时间显示 // ============================================ let timeElement = null; function createTimeDisplay() { if (!CONFIG.timeDisplay) return; timeElement = document.createElement('div'); timeElement.id = 'fun-effects-time'; timeElement.style.cssText = ` position: fixed; top: 20px; left: 20px; background: rgba(0,0,0,0.7); color: white; padding: 8px 12px; border-radius: 20px; font-family: 'Segoe UI', system-ui, sans-serif; font-size: 14px; backdrop-filter: blur(10px); z-index: 9999999; animation: timePulse 2s ease-in-out infinite; `; container.appendChild(timeElement); updateTime(); setInterval(updateTime, 1000); } function updateTime() { if (!timeElement || !CONFIG.timeDisplay) return; const now = new Date(); const timeString = now.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit', second: '2-digit' }); timeElement.textContent = timeString; } // ============================================ // ☁️ 实时天气效果 // ============================================ let weatherElement = null; function getWeatherEmoji(weatherCode) { // 根据天气代码返回对应的表情 const weatherMap = { 'Clear': '☀️', 'Clouds': '☁️', 'Rain': '🌧️', 'Drizzle': '🌦️', 'Thunderstorm': '⛈️', 'Snow': '❄️', 'Mist': '🌫️', 'Smoke': '🌫️', 'Haze': '🌫️', 'Dust': '🌫️', 'Fog': '🌫️', 'Sand': '🌫️', 'Ash': '🌫️', 'Squall': '💨', 'Tornado': '🌪️' }; return weatherMap[weatherCode] || '🌈'; } function updateWeatherEffect(weatherData) { if (!CONFIG.weatherEffect) return; const weatherMain = weatherData.weather[0].main; const emoji = getWeatherEmoji(weatherMain); const temp = Math.round(weatherData.main.temp); if (!weatherElement) { weatherElement = document.createElement('div'); weatherElement.id = 'fun-effects-weather'; weatherElement.style.cssText = ` position: fixed; right: 20px; top: 100px; background: rgba(0,0,0,0.7); color: white; padding: 10px 15px; border-radius: 20px; font-family: 'Segoe UI', system-ui, sans-serif; font-size: 14px; backdrop-filter: blur(10px); z-index: 9999999; display: flex; align-items: center; gap: 8px; animation: weatherEffect 3s ease-in-out infinite; `; container.appendChild(weatherElement); } weatherElement.innerHTML = ` ${emoji}
${weatherMain}
${temp}°C
`; } function fetchWeather(lat, lon) { // 使用 OpenWeatherMap API 获取天气数据 const apiKey = 'YOUR_API_KEY'; // 这里需要替换为真实的 API Key const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&units=metric&appid=${apiKey}`; fetch(url) .then(response => response.json()) .then(data => { updateWeatherEffect(data); }) .catch(error => { console.log('天气数据获取失败:', error); // 失败时使用默认天气效果 fallbackWeatherEffect(); }); } function fallbackWeatherEffect() { if (!CONFIG.weatherEffect) return; const weatherEmojis = ['🌈', '🌤️', '☀️', '☁️', '⛅', '🌥️', '🌦️', '🌧️']; const emoji = weatherEmojis[Math.floor(Math.random() * weatherEmojis.length)]; if (!weatherElement) { weatherElement = document.createElement('div'); weatherElement.id = 'fun-effects-weather'; weatherElement.style.cssText = ` position: fixed; right: 20px; top: 100px; background: rgba(0,0,0,0.7); color: white; padding: 10px 15px; border-radius: 20px; font-family: 'Segoe UI', system-ui, sans-serif; font-size: 14px; backdrop-filter: blur(10px); z-index: 9999999; display: flex; align-items: center; gap: 8px; animation: weatherEffect 3s ease-in-out infinite; `; container.appendChild(weatherElement); } weatherElement.innerHTML = ` ${emoji}
天气服务不可用
`; } function getCurrentLocation() { if (!CONFIG.weatherEffect) return; if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( (position) => { const lat = position.coords.latitude; const lon = position.coords.longitude; fetchWeather(lat, lon); }, (error) => { console.log('位置获取失败:', error); fallbackWeatherEffect(); } ); } else { fallbackWeatherEffect(); } } function createWeatherEffect() { // 这个函数现在只用于初始化 getCurrentLocation(); } // ============================================ // 🔊 音效系统 // ============================================ function playSound(type) { if (!CONFIG.soundEffect) return; // 这里使用 Web Audio API 创建简单的音效 try { const audioContext = new (window.AudioContext || window.webkitAudioContext)(); const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); switch (type) { case 'click': oscillator.frequency.value = 800; gainNode.gain.exponentialRampToValueAtTime(0.1, audioContext.currentTime + 0.05); gainNode.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 0.2); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + 0.2); break; case 'load': oscillator.frequency.value = 600; oscillator.frequency.exponentialRampToValueAtTime(1200, audioContext.currentTime + 0.5); gainNode.gain.exponentialRampToValueAtTime(0.1, audioContext.currentTime + 0.1); gainNode.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 1); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + 1); break; case 'bounce': oscillator.frequency.value = 1000; gainNode.gain.exponentialRampToValueAtTime(0.1, audioContext.currentTime + 0.05); gainNode.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 0.15); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + 0.15); break; case 'scroll': oscillator.frequency.value = 400; oscillator.frequency.exponentialRampToValueAtTime(800, audioContext.currentTime + 0.3); gainNode.gain.exponentialRampToValueAtTime(0.05, audioContext.currentTime + 0.05); gainNode.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 0.3); oscillator.start(audioContext.currentTime); oscillator.stop(audioContext.currentTime + 0.3); break; } } catch (e) { // 音效创建失败,忽略 } } // ============================================ // � 动态背景 // ============================================ let backgroundElement = null; function createDynamicBackground() { if (!CONFIG.dynamicBackground) return; backgroundElement = document.createElement('div'); backgroundElement.id = 'fun-effects-background'; backgroundElement.style.cssText = ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: -1; background: linear-gradient(45deg, #ff9a9e 0%, #fad0c4 99%, #fad0c4 100%); background-size: 400% 400%; animation: dynamicBackground 15s ease infinite; opacity: 0.3; `; document.body.appendChild(backgroundElement); } // ============================================ // ✨ 鼠标悬停特效 // ============================================ function initHoverEffect() { if (!CONFIG.hoverEffect) return; document.addEventListener('mouseover', (e) => { const target = e.target; if (target && target !== container && !target.closest('#fun-effects-panel') && !target.closest('#fun-effects-time') && !target.closest('#fun-effects-weather')) { target.style.transition = 'transform 0.3s ease'; target.style.transform = 'scale(1.05)'; setTimeout(() => { if (target) { target.style.transform = 'scale(1)'; } }, 300); } }); } // ============================================ // ⌨️ 键盘特效 // ============================================ function initKeyboardEffect() { if (!CONFIG.keyboardEffect) return; document.addEventListener('keydown', (e) => { const key = e.key.toUpperCase(); if (key.length === 1) { const keyElement = document.createElement('div'); keyElement.textContent = key; keyElement.style.cssText = ` position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 60px; font-weight: bold; color: ${getRandomColor()}; pointer-events: none; animation: keyboardEffect 1s ease-out forwards; z-index: 9999999; `; container.appendChild(keyElement); setTimeout(() => keyElement.remove(), 1000); } }); } // ============================================ // 🎨 主题切换 // ============================================ let currentTheme = 'light'; const themes = { light: { background: 'linear-gradient(45deg, #ff9a9e 0%, #fad0c4 99%, #fad0c4 100%)', text: '#333333', panel: 'linear-gradient(135deg, #ff6b6b 0%, #4ecdc4 100%)' }, dark: { background: 'linear-gradient(45deg, #2c3e50 0%, #4b6cb7 100%)', text: '#ffffff', panel: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)' }, neon: { background: 'linear-gradient(45deg, #0f0c29 0%, #302b63 50%, #24243e 100%)', text: '#00ffff', panel: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)' }, nature: { background: 'linear-gradient(45deg, #a8edea 0%, #fed6e3 100%)', text: '#2c3e50', panel: 'linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%)' } }; function createThemeToggle() { if (!CONFIG.themeToggle) return; const themeButton = document.createElement('div'); themeButton.id = 'fun-effects-theme'; themeButton.style.cssText = ` position: fixed; bottom: 20px; left: 20px; background: rgba(0,0,0,0.7); color: white; padding: 10px; border-radius: 50%; cursor: pointer; font-size: 20px; backdrop-filter: blur(10px); z-index: 9999999; animation: themeToggle 2s ease-in-out infinite; `; themeButton.innerHTML = '🎨'; container.appendChild(themeButton); themeButton.addEventListener('click', () => { const themeKeys = Object.keys(themes); const currentIndex = themeKeys.indexOf(currentTheme); const nextIndex = (currentIndex + 1) % themeKeys.length; currentTheme = themeKeys[nextIndex]; applyTheme(currentTheme); playSound('click'); }); } function applyTheme(themeName) { const theme = themes[themeName]; if (backgroundElement) { backgroundElement.style.background = theme.background; } const panel = document.getElementById('fun-effects-panel'); if (panel) { panel.style.background = theme.panel; } } // ============================================ // 🎬 初始化 // ============================================ function init() { createControlPanel(); initStars(); initFloatEmojis(); createLoadEffect(); createTimeDisplay(); createDynamicBackground(); initHoverEffect(); initKeyboardEffect(); createThemeToggle(); if (CONFIG.weatherEffect) { createWeatherEffect(); setInterval(createWeatherEffect, 300000); // 每5分钟更新一次天气 } animate(); console.log('🎉 网页趣味特效大师已启动!'); console.log('💡 功能提示:'); console.log(' • 点击任意位置产生粒子爆炸'); console.log(' • 移动鼠标留下彩虹轨迹'); console.log(' • 双击任意元素让它弹跳'); console.log(' • 在输入框打字有特效'); console.log(' • 滚动页面触发滚动特效'); console.log(' • 页面加载时有炫酷特效'); console.log(' • 左上角显示实时时间'); console.log(' • 实时天气效果(需位置权限)'); console.log(' • 动态渐变背景'); console.log(' • 鼠标悬停元素放大效果'); console.log(' • 键盘按键特效'); console.log(' • 主题切换功能(点击左下角🎨)'); console.log(' • 各种操作有音效反馈'); console.log(' • 右上角可开关所有特效'); console.log('💡 天气功能说明:'); console.log(' • 需要位置权限才能获取实时天气'); console.log(' • 如无权限,将使用随机天气效果'); console.log(' • 天气数据每5分钟自动更新'); } // 等待页面加载完成 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();