// ==UserScript== // @name 春节灯笼完全增强版 // @namespace none // @version 2.0.1 // @description 给所有网站增加春节灯笼效果,全功能控制面板(修复版) // @grant none // @author AI Assistant // @include *://* // @updateURL https://github.com/yourusername/spring-lantern-enhanced/raw/main/spring-lantern-fixed.user.js // @downloadURL https://github.com/yourusername/spring-lantern-enhanced/raw/main/spring-lantern-fixed.user.js // ==/UserScript== (function() { 'use strict'; // 在iframe中不渲染灯笼 if(window.top !== window) return; // ========== 颜色主题定义 ========== const colorThemes = { traditional: { name: '传统红', suiLight: '#dc8f03', suiDark: '#ffa500', deng_box_shadow: 'rgba(250, 108, 0, 1)', r1: 'rgba(216, 0, 15, 0.8)', r2: 'rgba(216, 0, 15, 0.1)', bgGradient: 'linear-gradient(135deg, #d8000f 0%, #ff4d4d 100%)', }, gold: { name: '金色年华', suiLight: '#ffd700', suiDark: '#daa520', deng_box_shadow: 'rgba(255, 215, 0, 1)', r1: 'rgba(218, 165, 32, 0.8)', r2: 'rgba(218, 165, 32, 0.1)', bgGradient: 'linear-gradient(135deg, #ffd700 0%, #daa520 100%)', }, purple: { name: '紫气东来', suiLight: '#e6b3ff', suiDark: '#9932cc', deng_box_shadow: 'rgba(153, 50, 204, 1)', r1: 'rgba(138, 43, 226, 0.8)', r2: 'rgba(138, 43, 226, 0.1)', bgGradient: 'linear-gradient(135deg, #9932cc 0%, #8a2be2 100%)', }, blue: { name: '碧波荡漾', suiLight: '#87ceeb', suiDark: '#4682b4', deng_box_shadow: 'rgba(70, 130, 180, 1)', r1: 'rgba(30, 144, 255, 0.8)', r2: 'rgba(30, 144, 255, 0.1)', bgGradient: 'linear-gradient(135deg, #1e90ff 0%, #4682b4 100%)', }, rainbow: { name: '彩虹渐变', suiLight: '#ff69b4', suiDark: '#ff1493', deng_box_shadow: 'rgba(255, 105, 180, 1)', r1: 'rgba(255, 99, 71, 0.8)', r2: 'rgba(255, 99, 71, 0.1)', bgGradient: 'linear-gradient(90deg, #ff0000 0%, #ff7f00 16%, #ffff00 33%, #00ff00 50%, #0000ff 66%, #8b00ff 83%, #ff0000 100%)', } }; // ========== 摆动模式定义 ========== const swingModes = { gentle: { name: '轻轻摇摆', duration: 5, amplitude: 10 }, breeze: { name: '微风拂面', duration: 3.5, amplitude: 15 }, windy: { name: '狂风大作', duration: 2, amplitude: 25 }, static: { name: '静止不动', duration: 0, amplitude: 0 } }; // ========== 预设文字模板 ========== const textTemplates = [ '迎春', '福', '喜', '财源', '吉祥', '如意', '平安', '团圆', '安康', '快乐', '幸福', '顺遂' ]; // ========== 默认配置 ========== const defaultConfig = { showLanterns: true, enableLight: true, enableSwing: true, enableFlicker: false, customText: '迎春', lanternCount: 2, lanternScale: 1.0, lanternOffsetY: 0, lanternOffsetX: 0, colorTheme: 'traditional', swingMode: 'gentle', swingSpeed: 1.0, swingAmplitude: 1.0, mouseDistance: 180, enableDoubleClick: true, enableCountdown: false, blacklist: [], autoTheme: false, timeMode: 'all', customStartTime: '06:00', customEndTime: '18:00', enableKeyboard: true, enableLazyLoad: true }; // 从localStorage加载配置 let config = { ...defaultConfig }; const savedConfig = localStorage.getItem('spring_lantern_config_v2'); if (savedConfig) { try { config = { ...defaultConfig, ...JSON.parse(savedConfig) }; } catch (e) { console.error('Failed to load lantern config:', e); } } // 保存配置到localStorage function saveConfig() { localStorage.setItem('spring_lantern_config_v2', JSON.stringify(config)); } // 获取当前颜色主题 function getCurrentTheme() { return colorThemes[config.colorTheme] || colorThemes.traditional; } // 检测当前是否在黑名单中 function isBlacklisted() { const hostname = window.location.hostname; return config.blacklist.some(domain => { if (domain.startsWith('*.')) { return hostname.endsWith(domain.slice(2)); } return hostname === domain || hostname === 'www.' + domain; }); } // 检测时间段 function isInActiveTime() { if (config.timeMode === 'all') return true; const now = new Date(); const currentHour = now.getHours(); const currentMinute = now.getMinutes(); const currentTime = currentHour * 60 + currentMinute; if (config.timeMode === 'day') { return currentTime >= 360 && currentTime < 1080; } else if (config.timeMode === 'night') { return currentTime < 360 || currentTime >= 1080; } else if (config.timeMode === 'custom') { const [startH, startM] = config.customStartTime.split(':').map(Number); const [endH, endM] = config.customEndTime.split(':').map(Number); const startTime = startH * 60 + startM; const endTime = endH * 60 + endM; return currentTime >= startTime && currentTime < endTime; } return true; } // 节日自动检测 function getFestivalText() { if (!config.autoTheme) return config.customText; const now = new Date(); const month = now.getMonth() + 1; const day = now.getDate(); if (month === 1 && day >= 1 && day <= 15) return '迎春'; if (month === 1 && day === 15) return '汤圆'; if (month === 6 && day >= 18 && day <= 25) return '安康'; if (month === 9 && day >= 8 && day <= 15) return '团圆'; if (month === 10 && day >= 1 && day <= 7) return '国泰'; return config.customText; } // 计算春节倒计时 function getSpringCountdown() { const now = new Date(); const year = now.getFullYear(); const springFestivals = { 2025: '2025-01-29', 2026: '2026-02-17', 2027: '2027-02-06', 2028: '2028-01-26', 2029: '2029-02-13', }; const springDate = new Date(springFestivals[year] || `${year}-02-01`); if (now > springDate) { springDate.setFullYear(year + 1); } const diff = springDate - now; const days = Math.ceil(diff / (1000 * 60 * 60 * 24)); return days; } // ========== 创建样式 ========== const style = document.createElement('style'); function generateStyles() { const theme = getCurrentTheme(); const swingMode = swingModes[config.swingMode] || swingModes.gentle; const duration = config.enableSwing ? (swingMode.duration / config.swingSpeed) : 0; const amplitude = swingMode.amplitude * config.swingAmplitude; return ` /* 灯笼容器 */ .spring_lantern__container { position: fixed; top: ${-20 + config.lanternOffsetY}px; left: 0; right: 0; width: 100%; height: 0; z-index: 99999; pointer-events: none; } /* 左侧灯笼 */ .spring_lantern__deng-box1 { position: absolute; left: ${10 + config.lanternOffsetX}px; top: 0; opacity: 1; transform: scale(${config.lanternScale}); transform-origin: top center; transition: opacity 0.4s ease-out, transform 0.4s ease-out; } /* 右侧灯笼 */ .spring_lantern__deng-box { position: absolute; right: ${-20 + config.lanternOffsetX}px; top: 0; opacity: 1; transform: scale(${config.lanternScale}); transform-origin: top center; transition: opacity 0.4s ease-out, transform 0.4s ease-out; } /* 中间灯笼1 */ .spring_lantern__deng-box2 { position: absolute; left: calc(50% - 60px); top: 10px; opacity: 1; transform: scale(${config.lanternScale}); transform-origin: top center; transition: opacity 0.4s ease-out, transform 0.4s ease-out; } /* 中间灯笼2 */ .spring_lantern__deng-box3 { position: absolute; left: calc(50% + 50px); top: 10px; opacity: 1; transform: scale(${config.lanternScale}); transform-origin: top center; transition: opacity 0.4s ease-out, transform 0.4s ease-out; } /* 灯笼隐藏状态 */ .spring_lantern__fade-out { opacity: 0 !important; transform: scale(${config.lanternScale * 0.8}) translateY(-20px) !important; } /* 灯笼主体 */ .spring_lantern__deng { position: relative; width: 120px; height: 90px; margin: 50px; background: ${theme.r1}; border-radius: 50% 50%; -webkit-transform-origin: 50% -100px; transform-origin: 50% -100px; ${config.enableSwing && duration > 0 ? ` -webkit-animation: swing ${duration}s infinite ease-in-out; animation: swing ${duration}s infinite ease-in-out; ` : ''} box-shadow: -5px 5px 50px 4px ${theme.deng_box_shadow}; transition: box-shadow 0.3s ease; will-change: transform; ${config.enableFlicker ? 'animation: swing ${duration}s infinite ease-in-out, flicker 0.1s infinite alternate;' : ''} } /* 不同灯笼的动画时长差异 */ .spring_lantern__deng-box1 .spring_lantern__deng { ${config.enableSwing && duration > 0 ? ` -webkit-animation: swing ${duration * 1.3}s infinite ease-in-out; animation: swing ${duration * 1.3}s infinite ease-in-out; ` : ''} box-shadow: -5px 5px 30px 4px ${theme.deng_box_shadow}; } .spring_lantern__deng-box2 .spring_lantern__deng, .spring_lantern__deng-box3 .spring_lantern__deng { ${config.enableSwing && duration > 0 ? ` -webkit-animation: swing ${duration * 1.6}s infinite ease-in-out; animation: swing ${duration * 1.6}s infinite ease-in-out; ` : ''} box-shadow: -5px 5px 40px 4px ${theme.deng_box_shadow}; } /* 灯笼内部 */ .spring_lantern__deng-a { width: 100px; height: 90px; background: ${theme.r2}; margin: 12px 8px 8px 8px; border-radius: 50% 50%; border: 2px solid ${theme.suiLight}; } .spring_lantern__deng-b { width: 45px; height: 90px; background: ${theme.r2}; margin: -4px 8px 8px 26px; border-radius: 50% 50%; border: 2px solid ${theme.suiLight}; } /* 灯笼悬挂线 */ .spring_lantern__xian { position: absolute; top: -40px; left: 60px; width: 2px; height: 40px; background: ${theme.suiLight}; } /* 灯笼穗子 */ .spring_lantern__shui-a { position: relative; width: 5px; height: 20px; margin: -5px 0 0 59px; ${config.enableSwing && duration > 0 ? ` -webkit-animation: swing ${duration * 1.2}s infinite ease-in-out; animation: swing ${duration * 1.2}s infinite ease-in-out; ` : ''} -webkit-transform-origin: 50% -45px; transform-origin: 50% -45px; background: ${theme.suiDark}; border-radius: 0 0 5px 5px; will-change: transform; } .spring_lantern__shui-b { position: absolute; top: 14px; left: -2px; width: 10px; height: 10px; background: ${theme.suiLight}; border-radius: 50%; } .spring_lantern__shui-c { position: absolute; top: 18px; left: -2px; width: 10px; height: 35px; background: ${theme.suiDark}; border-radius: 0 0 0 5px; } /* 灯笼上下装饰 */ .spring_lantern__deng:before { position: absolute; top: -7px; left: 29px; height: 12px; width: 60px; content: " "; display: block; z-index: 999; border-radius: 5px 5px 0 0; border: solid 1px ${theme.suiLight}; background: ${theme.suiDark}; background: linear-gradient(to right, ${theme.suiLight}, ${theme.suiDark}, ${theme.suiLight}, ${theme.suiDark}, ${theme.suiLight}); } .spring_lantern__deng:after { position: absolute; bottom: -7px; left: 10px; height: 12px; width: 60px; content: " "; display: block; margin-left: 20px; border-radius: 0 0 5px 5px; border: solid 1px ${theme.suiLight}; background: ${theme.suiDark}; background: linear-gradient(to right, ${theme.suiLight}, ${theme.suiDark}, ${theme.suiLight}, ${theme.suiDark}, ${theme.suiLight}); } /* 灯笼文字 */ .spring_lantern__deng-t { font-family: 华文行楷,华文楷体,Arial,Lucida Grande,Tahoma,sans-serif; font-size: 53px !important; color: ${theme.suiLight}; font-weight: bold; line-height: 85px; text-align: center; user-select: none; } /* 摆动动画 */ @-moz-keyframes swing { 0% { -moz-transform: rotate(-${amplitude}deg) } 50% { -moz-transform: rotate(${amplitude}deg) } 100% { -moz-transform: rotate(-${amplitude}deg) } } @-webkit-keyframes swing { 0% { -webkit-transform: rotate(-${amplitude}deg) } 50% { -webkit-transform: rotate(${amplitude}deg) } 100% { -webkit-transform: rotate(-${amplitude}deg) } } @keyframes swing { 0% { transform: rotate(-${amplitude}deg) } 50% { transform: rotate(${amplitude}deg) } 100% { transform: rotate(-${amplitude}deg) } } /* 灯光闪烁动画 */ @keyframes flicker { 0% { opacity: 1; } 100% { opacity: 0.85; } } /* 灯笼完全隐藏 */ .spring_lantern__hidden { display: none !important; } /* 关闭灯光 */ .spring_lantern__no-light .spring_lantern__deng { box-shadow: none !important; opacity: 0.7; } /* 停止摆动 */ .spring_lantern__no-swing .spring_lantern__deng, .spring_lantern__no-swing .spring_lantern__shui-a { -webkit-animation-play-state: paused !important; animation-play-state: paused !important; } /* 倒计时样式 */ .spring_lantern__countdown { position: fixed; top: 120px; right: 20px; background: rgba(255, 255, 255, 0.95); padding: 10px 15px; border-radius: 10px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); font-size: 14px; z-index: 99998; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; border: 2px solid ${theme.suiDark}; transition: all 0.3s ease; } .spring_lantern__countdown-text { color: #d8000f; font-weight: bold; font-size: 16px; } .spring_lantern__countdown.hidden { opacity: 0; transform: translateY(-10px); pointer-events: none; } /* ========== 控制面板样式 ========== */ .spring_lantern__control-btn { position: fixed; bottom: 20px; right: 20px; width: 52px; height: 52px; background: ${theme.bgGradient}; border-radius: 50%; cursor: pointer; z-index: 999999; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35); display: flex; align-items: center; justify-content: center; font-size: 22px; color: #ffd700; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); user-select: none; border: 2px solid rgba(255, 215, 0, 0.3); } .spring_lantern__control-btn:hover { transform: scale(1.08); box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5); border-color: rgba(255, 215, 0, 0.5); } .spring_lantern__control-btn:active { transform: scale(0.96); } .spring_lantern__panel { position: fixed; bottom: 85px; right: 20px; width: 300px; max-height: 70vh; background: linear-gradient(145deg, #ffffff 0%, #fafafa 100%); border-radius: 16px; box-shadow: 0 10px 40px rgba(0, 0, 0, 0.15), 0 2px 8px rgba(0, 0, 0, 0.08); z-index: 999999; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif; transform: scale(0.92) translateY(10px); opacity: 0; pointer-events: none; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); overflow: hidden; border: 1px solid rgba(0, 0, 0, 0.1); } .spring_lantern__panel.spring_lantern__panel-open { transform: scale(1) translateY(0); opacity: 1; pointer-events: auto; } .spring_lantern__panel-header { background: ${theme.bgGradient}; padding: 14px 16px; display: flex; align-items: center; justify-content: space-between; } .spring_lantern__panel-title { font-size: 15px; font-weight: 600; color: #ffffff; margin: 0; letter-spacing: 0.5px; } .spring_lantern__panel-close { color: white; cursor: pointer; font-size: 20px; opacity: 0.8; transition: opacity 0.2s; line-height: 1; } .spring_lantern__panel-close:hover { opacity: 1; } .spring_lantern__panel-body { padding: 14px 16px 16px; overflow-y: auto; max-height: calc(70vh - 60px); } .spring_lantern__panel-body::-webkit-scrollbar { width: 6px; } .spring_lantern__panel-body::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.2); border-radius: 3px; } .spring_lantern__panel-section { margin-bottom: 16px; } .spring_lantern__panel-section:last-child { margin-bottom: 0; } .spring_lantern__section-title { font-size: 11px; color: #888; text-transform: uppercase; letter-spacing: 0.8px; margin-bottom: 8px; font-weight: 600; } .spring_lantern__panel-item { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; background: linear-gradient(145deg, #f8f8f8 0%, #f3f3f3 100%); border-radius: 10px; transition: all 0.2s ease; margin-bottom: 8px; border: 1px solid transparent; } .spring_lantern__panel-item:hover { background: linear-gradient(145deg, #efefef 0%, #eaeaea 100%); border-color: rgba(0, 0, 0, 0.08); transform: translateY(-1px); } .spring_lantern__panel-item:last-child { margin-bottom: 0; } .spring_lantern__panel-label { font-size: 13px; color: #333; font-weight: 500; flex-shrink: 0; display: flex; align-items: center; gap: 6px; } .spring_lantern__panel-label-icon { font-size: 14px; } /* 开关样式 */ .spring_lantern__switch { position: relative; width: 44px; height: 22px; background: #d0d0d0; border-radius: 11px; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); flex-shrink: 0; box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.15); } .spring_lantern__switch.spring_lantern__switch-on { background: ${theme.bgGradient}; box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2), 0 0 8px rgba(0, 0, 0, 0.2); } .spring_lantern__switch-handle { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; background: white; border-radius: 50%; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.1); } .spring_lantern__switch.spring_lantern__switch-on .spring_lantern__switch-handle { transform: translateX(22px); } /* 滑块样式 */ .spring_lantern__slider-group { padding: 10px 12px; background: linear-gradient(145deg, #f8f8f8 0%, #f3f3f3 100%); border-radius: 10px; margin-bottom: 8px; } .spring_lantern__slider-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; } .spring_lantern__slider-label { font-size: 13px; color: #333; font-weight: 500; } .spring_lantern__slider-value { font-size: 12px; color: #666; background: white; padding: 2px 8px; border-radius: 4px; } .spring_lantern__slider { width: 100%; height: 6px; border-radius: 3px; background: #e0e0e0; outline: none; -webkit-appearance: none; } .spring_lantern__slider::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%; background: ${theme.bgGradient}; cursor: pointer; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .spring_lantern__slider::-moz-range-thumb { width: 18px; height: 18px; border-radius: 50%; background: ${theme.bgGradient}; cursor: pointer; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); border: none; } /* 下拉选择框 */ .spring_lantern__select-group { padding: 10px 12px; background: linear-gradient(145deg, #f8f8f8 0%, #f3f3f3 100%); border-radius: 10px; margin-bottom: 8px; } .spring_lantern__select { width: 100%; padding: 8px 10px; border: 2px solid #e0e0e0; border-radius: 6px; font-size: 13px; font-family: inherit; background: white; color: #333; cursor: pointer; transition: all 0.2s ease; } .spring_lantern__select:focus { outline: none; border-color: #666; box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.08); } /* 文字输入框 */ .spring_lantern__text-input-wrapper { padding: 10px 12px; background: linear-gradient(145deg, #f8f8f8 0%, #f3f3f3 100%); border-radius: 10px; margin-bottom: 8px; } .spring_lantern__text-input-row { display: flex; align-items: center; gap: 8px; } .spring_lantern__text-input { flex: 1; min-width: 0; max-width: 120px; padding: 10px 12px; border: 2px solid #e0e0e0; border-radius: 8px; font-size: 15px; font-family: inherit; text-align: center; transition: all 0.2s ease; background: white; color: #333; font-weight: 500; } .spring_lantern__text-input:focus { outline: none; border-color: #666; box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.08); } .spring_lantern__text-btn { padding: 10px 16px; background: ${theme.bgGradient}; color: white; border: none; border-radius: 8px; font-size: 13px; font-weight: 600; cursor: pointer; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); white-space: nowrap; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25); flex-shrink: 0; } .spring_lantern__text-btn:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35); } .spring_lantern__text-btn:active { transform: translateY(0); } .spring_lantern__text-hint { font-size: 11px; color: #999; text-align: center; margin-top: 8px; font-weight: 500; } /* 预设文字网格 */ .spring_lantern__template-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; padding: 10px 12px; background: linear-gradient(145deg, #f8f8f8 0%, #f3f3f3 100%); border-radius: 10px; } .spring_lantern__template-item { padding: 8px 4px; background: white; border: 2px solid #e0e0e0; border-radius: 6px; text-align: center; font-size: 14px; cursor: pointer; transition: all 0.2s ease; color: #333; font-weight: 500; } .spring_lantern__template-item:hover { background: ${theme.bgGradient}; color: white; border-color: transparent; transform: scale(1.05); } .spring_lantern__template-item.active { background: ${theme.bgGradient}; color: white; border-color: transparent; } /* 黑名单样式 - 重新设计 */ .spring_lantern__blacklist-section { padding: 12px; background: linear-gradient(145deg, #fff5f5 0%, #ffe8e8 100%); border-radius: 10px; border: 1px solid rgba(216, 0, 15, 0.1); } .spring_lantern__blacklist-title { font-size: 12px; font-weight: 600; color: #d8000f; margin-bottom: 10px; display: flex; align-items: center; gap: 6px; } .spring_lantern__blacklist-input-row { display: flex; gap: 8px; margin-bottom: 10px; } .spring_lantern__blacklist-input { flex: 1; padding: 8px 12px; border: 2px solid #ffcdd2; border-radius: 6px; font-size: 13px; font-family: inherit; background: white; color: #333; transition: all 0.2s ease; } .spring_lantern__blacklist-input:focus { outline: none; border-color: #d8000f; box-shadow: 0 0 0 3px rgba(216, 0, 15, 0.1); } .spring_lantern__blacklist-input::placeholder { color: #e57373; } .spring_lantern__blacklist-add-btn { padding: 8px 16px; background: linear-gradient(135deg, #d8000f 0%, #ff4d4d 100%); color: white; border: none; border-radius: 6px; font-size: 13px; font-weight: 600; cursor: pointer; white-space: nowrap; transition: all 0.2s ease; } .spring_lantern__blacklist-add-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(216, 0, 15, 0.3); } .spring_lantern__blacklist-items { max-height: 150px; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; } .spring_lantern__blacklist-items::-webkit-scrollbar { width: 4px; } .spring_lantern__blacklist-items::-webkit-scrollbar-thumb { background: rgba(216, 0, 15, 0.3); border-radius: 2px; } .spring_lantern__blacklist-item { display: flex; justify-content: space-between; align-items: center; padding: 10px 12px; background: white; border-radius: 8px; font-size: 13px; border: 1px solid #ffcdd2; transition: all 0.2s ease; } .spring_lantern__blacklist-item:hover { border-color: #d8000f; box-shadow: 0 2px 8px rgba(216, 0, 15, 0.1); } .spring_lantern__blacklist-domain { color: #333; font-weight: 500; word-break: break-all; flex: 1; } .spring_lantern__blacklist-remove { color: #d8000f; cursor: pointer; font-weight: bold; padding: 4px 8px; border-radius: 4px; transition: all 0.2s ease; flex-shrink: 0; font-size: 16px; line-height: 1; } .spring_lantern__blacklist-remove:hover { background: rgba(216, 0, 15, 0.1); transform: scale(1.1); } .spring_lantern__blacklist-empty { text-align: center; padding: 20px; color: #999; font-size: 13px; } .spring_lantern__blacklist-hint { font-size: 11px; color: #e57373; margin-top: 8px; line-height: 1.4; } `; } style.innerHTML = generateStyles(); (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(style); // ========== 检查是否应该显示灯笼 ========== if (isBlacklisted() || !isInActiveTime()) { console.log('Lantern hidden: blacklisted or not in active time'); return; } // ========== 创建灯笼 ========== function createLanterns() { const displayText = getFestivalText(); const chars = displayText.split(''); // 根据灯笼数量创建 const lanternConfigs = [ { id: 'left', class: 'deng-box1', text: chars[0] || '迎', defaultPos: 'left' }, { id: 'right', class: 'deng-box', text: chars[1] || '春', defaultPos: 'right' }, ]; if (config.lanternCount >= 3) { lanternConfigs.push({ id: 'center1', class: 'deng-box2', text: chars[2] || '福', defaultPos: 'center' }); } if (config.lanternCount >= 4) { lanternConfigs.push({ id: 'center2', class: 'deng-box3', text: chars[3] || '寿', defaultPos: 'center' }); } const container = document.createElement('div'); container.className = 'spring_lantern__container'; container.id = 'spring_lantern__container'; lanternConfigs.forEach((lc, index) => { const lanternDiv = document.createElement('div'); lanternDiv.innerHTML = `
${lc.text}
`; container.appendChild(lanternDiv); }); (document.getElementsByTagName('body')[0] || document.getElementsByTagName('div')[0]).appendChild(container); } createLanterns(); // ========== 创建倒计时 ========== let countdownEl = null; function createCountdown() { if (!config.enableCountdown) return; countdownEl = document.createElement('div'); countdownEl.className = 'spring_lantern__countdown'; countdownEl.innerHTML = ` 🧧 距离春节还有 ${getSpringCountdown()} 天 `; document.body.appendChild(countdownEl); } if (config.enableCountdown) { createCountdown(); } // ========== 创建控制按钮 ========== const controlBtn = document.createElement('div'); controlBtn.className = 'spring_lantern__control-btn'; controlBtn.innerHTML = '🏮'; controlBtn.title = '灯笼设置 (Ctrl+Shift+M)'; document.body.appendChild(controlBtn); // ========== 创建控制面板 ========== const panel = document.createElement('div'); panel.className = 'spring_lantern__panel'; panel.innerHTML = `
🏮 灯笼设置
×
`; document.body.appendChild(panel); // ========== 生成面板内容 ========== function renderPanel() { const theme = getCurrentTheme(); const panelBody = document.getElementById('spring_lantern__panel-body'); if (!panelBody) return; panelBody.innerHTML = `
基础设置
👁 显示灯笼
💡 灯光效果
灯光闪烁
🎭 摆动动画
🎯 双击切换
视觉外观
灯笼大小 ${config.lanternScale.toFixed(1)}x
上下位置 ${config.lanternOffsetY}
左右位置 ${config.lanternOffsetX}
动画控制
摆动速度 ${config.swingSpeed.toFixed(1)}x
摆动幅度 ${config.swingAmplitude.toFixed(1)}x
内容设置
输入 1-4 个汉字,从左到右显示
${textTemplates.map(text => `
${text}
`).join('')}
📅 春节倒计时
🎊 节日自动切换
交互设置
鼠标触发距离 ${config.mouseDistance}px
⌨️ 键盘快捷键
高级设置
${config.timeMode === 'custom' ? `
开始时间
结束时间
` : ''}
🚫 网站黑名单
${config.blacklist.length === 0 ? `
暂无黑名单网站
` : config.blacklist.map(domain => `
${domain}
`).join('')}
💡 提示:添加域名后,该网站将不再显示灯笼
`; } renderPanel(); // ========== 更新灯笼 ========== function updateLanterns() { const container = document.getElementById('spring_lantern__container'); if (container) { container.remove(); } createLanterns(); applyConfig(); } // ========== 更新倒计时 ========== function updateCountdown() { if (countdownEl) { countdownEl.remove(); countdownEl = null; } if (config.enableCountdown) { createCountdown(); } } // ========== 应用配置 ========== function applyConfig() { const lanternItems = document.querySelectorAll('.spring_lantern__lantern-item'); lanternItems.forEach(item => { if (config.showLanterns) { item.classList.remove('spring_lantern__hidden'); } else { item.classList.add('spring_lantern__hidden'); } if (config.enableLight) { item.classList.remove('spring_lantern__no-light'); } else { item.classList.add('spring_lantern__no-light'); } if (config.enableSwing) { item.classList.remove('spring_lantern__no-swing'); } else { item.classList.add('spring_lantern__no-swing'); } }); if (countdownEl) { if (config.showLanterns) { countdownEl.classList.remove('hidden'); } else { countdownEl.classList.add('hidden'); } } saveConfig(); } applyConfig(); // ========== 更新样式(主题/动画变化时)========== function updateStyles() { style.innerHTML = generateStyles(); } // ========== 事件监听 ========== // 面板开关 controlBtn.addEventListener('click', (e) => { e.stopPropagation(); panel.classList.toggle('spring_lantern__panel-open'); }); document.getElementById('spring_lantern__close').addEventListener('click', () => { panel.classList.remove('spring_lantern__panel-open'); }); document.addEventListener('click', (e) => { if (!panel.contains(e.target) && e.target !== controlBtn) { panel.classList.remove('spring_lantern__panel-open'); } }); // 开关事件 - 使用事件委托,动态绑定 panel.addEventListener('click', (e) => { const switchEl = e.target.closest('.spring_lantern__switch'); if (!switchEl) return; const configKey = switchEl.dataset.config; if (!configKey) return; // 切换配置 config[configKey] = !config[configKey]; // 特殊处理 if (configKey === 'enableFlicker') { updateStyles(); } else if (configKey === 'enableCountdown') { updateCountdown(); } else if (configKey === 'autoTheme') { updateLanterns(); } applyConfig(); // 更新开关状态 setTimeout(() => { const updatedSwitch = panel.querySelector(`[data-config="${configKey}"]`); if (updatedSwitch) { updatedSwitch.classList.toggle('spring_lantern__switch-on', config[configKey]); } }, 0); }); // 滑块事件 panel.addEventListener('input', (e) => { if (e.target.id === 'spring_lantern__scale') { config.lanternScale = parseFloat(e.target.value); const valueEl = document.getElementById('spring_lantern__scale-value'); if (valueEl) valueEl.textContent = config.lanternScale.toFixed(1) + 'x'; updateStyles(); saveConfig(); } else if (e.target.id === 'spring_lantern__offsety') { config.lanternOffsetY = parseInt(e.target.value); const valueEl = document.getElementById('spring_lantern__offsety-value'); if (valueEl) valueEl.textContent = config.lanternOffsetY; updateStyles(); saveConfig(); } else if (e.target.id === 'spring_lantern__offsetx') { config.lanternOffsetX = parseInt(e.target.value); const valueEl = document.getElementById('spring_lantern__offsetx-value'); if (valueEl) valueEl.textContent = config.lanternOffsetX; updateStyles(); saveConfig(); } else if (e.target.id === 'spring_lantern__swing-speed') { config.swingSpeed = parseFloat(e.target.value); const valueEl = document.getElementById('spring_lantern__swing-speed-value'); if (valueEl) valueEl.textContent = config.swingSpeed.toFixed(1) + 'x'; updateStyles(); saveConfig(); } else if (e.target.id === 'spring_lantern__swing-amplitude') { config.swingAmplitude = parseFloat(e.target.value); const valueEl = document.getElementById('spring_lantern__swing-amplitude-value'); if (valueEl) valueEl.textContent = config.swingAmplitude.toFixed(1) + 'x'; updateStyles(); saveConfig(); } else if (e.target.id === 'spring_lantern__distance') { config.mouseDistance = parseInt(e.target.value); const valueEl = document.getElementById('spring_lantern__distance-value'); if (valueEl) valueEl.textContent = config.mouseDistance + 'px'; saveConfig(); } }); // 下拉选择事件 panel.addEventListener('change', (e) => { if (e.target.id === 'spring_lantern__theme') { config.colorTheme = e.target.value; updateStyles(); renderPanel(); } else if (e.target.id === 'spring_lantern__swing-mode') { config.swingMode = e.target.value; updateStyles(); saveConfig(); } else if (e.target.id === 'spring_lantern__count') { config.lanternCount = parseInt(e.target.value); updateLanterns(); renderPanel(); } else if (e.target.id === 'spring_lantern__time-mode') { config.timeMode = e.target.value; saveConfig(); renderPanel(); } else if (e.target.id === 'spring_lantern__start-time') { config.customStartTime = e.target.value; saveConfig(); } else if (e.target.id === 'spring_lantern__end-time') { config.customEndTime = e.target.value; saveConfig(); } }); // 文字输入 const textInput = document.getElementById('spring_lantern__text-input'); const textBtn = document.getElementById('spring_lantern__text-btn'); textBtn.addEventListener('click', () => { const text = textInput.value.trim(); if (text && text.length > 0) { config.customText = text; updateLanterns(); renderPanel(); textBtn.textContent = '✓ 已应用'; setTimeout(() => { textBtn.textContent = '应用'; }, 1000); } }); textInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') { textBtn.click(); } }); // 预设文字点击 panel.addEventListener('click', (e) => { if (e.target.classList.contains('spring_lantern__template-item')) { const text = e.target.dataset.text; config.customText = text; updateLanterns(); renderPanel(); } }); // 黑名单操作 const blacklistInput = document.getElementById('spring_lantern__blacklist-input'); const blacklistAddBtn = document.getElementById('spring_lantern__blacklist-add'); blacklistAddBtn.addEventListener('click', () => { const domain = blacklistInput.value.trim(); if (domain && !config.blacklist.includes(domain)) { config.blacklist.push(domain); saveConfig(); renderPanel(); } }); panel.addEventListener('click', (e) => { if (e.target.classList.contains('spring_lantern__blacklist-remove')) { const domain = e.target.dataset.domain; config.blacklist = config.blacklist.filter(d => d !== domain); saveConfig(); renderPanel(); } }); // ========== 鼠标交互 ========== let mouseX = 0; let mouseY = 0; let isNearLantern = false; function isMouseNearLantern(x, y) { const distance = config.mouseDistance; const leftLanternArea = { x: 0, y: 0, width: 200, height: distance }; const rightLanternArea = { x: window.innerWidth - 200, y: 0, width: 200, height: distance }; const inLeftArea = x >= leftLanternArea.x && x <= leftLanternArea.x + leftLanternArea.width && y >= leftLanternArea.y && y <= leftLanternArea.y + leftLanternArea.height; const inRightArea = x >= rightLanternArea.x && x <= rightLanternArea.x + rightLanternArea.width && y >= rightLanternArea.y && y <= rightLanternArea.y + rightLanternArea.height; return inLeftArea || inRightArea; } document.addEventListener('mousemove', (e) => { mouseX = e.clientX; mouseY = e.clientY; const near = isMouseNearLantern(mouseX, mouseY); if (near !== isNearLantern && config.showLanterns) { isNearLantern = near; const lanternItems = document.querySelectorAll('.spring_lantern__lantern-item'); if (isNearLantern) { lanternItems.forEach(item => item.classList.add('spring_lantern__fade-out')); } else { lanternItems.forEach(item => item.classList.remove('spring_lantern__fade-out')); } } }); // ========== 双击切换 ========== if (config.enableDoubleClick) { document.addEventListener('dblclick', (e) => { const lanternItem = e.target.closest('.spring_lantern__lantern-item'); if (lanternItem) { config.showLanterns = !config.showLanterns; applyConfig(); renderPanel(); } }); } // ========== 键盘快捷键 ========== if (config.enableKeyboard) { document.addEventListener('keydown', (e) => { if (e.ctrlKey && e.shiftKey) { if (e.key === 'L') { e.preventDefault(); config.showLanterns = !config.showLanterns; applyConfig(); renderPanel(); } else if (e.key === 'S') { e.preventDefault(); config.enableSwing = !config.enableSwing; applyConfig(); renderPanel(); } else if (e.key === 'M') { e.preventDefault(); panel.classList.toggle('spring_lantern__panel-open'); } } }); } // ========== 窗口大小改变 ========== window.addEventListener('resize', () => { // 可选:添加响应式处理 }); // ========== 懒加载支持 ========== if (config.enableLazyLoad) { let lanternsVisible = false; function checkScroll() { const scrollY = window.scrollY || window.pageYOffset; if (!lanternsVisible && scrollY < 300) { lanternsVisible = true; } } window.addEventListener('scroll', checkScroll); checkScroll(); } console.log('🏮 春节灯笼脚本已加载 - 完全增强版 v2.0.1 (修复版)'); console.log('快捷键: Ctrl+Shift+L (显示/隐藏), Ctrl+Shift+S (摆动), Ctrl+Shift+M (菜单)'); })();