// ==UserScript== // @name 全局粒子特效开关 // @namespace http://tampermonkey.net/ // @version 1.0 // @description 页面顶部悬浮开关,一键开启/关闭全屏粒子特效 // @author You // @match *://*/* // @grant GM_addStyle // ==/UserScript== (function() { 'use strict'; // 样式 GM_addStyle(` #particleToggleBox { position: fixed; top: 12px; left: 50%; transform: translateX(-50%); z-index: 999999; background: rgba(0,0,0,0.65); padding: 6px 14px; border-radius: 99px; display: flex; align-items: center; gap: 10px; } #particleToggleBox span { color: #fff; font-size: 13px; } #particleSwitch { width: 42px; height: 22px; background: #666; border-radius: 22px; position: relative; cursor: pointer; transition: 0.3s; } #particleSwitch::after { content: ''; width: 18px; height: 18px; background: white; border-radius: 50%; position: absolute; top: 2px; left: 2px; transition: 0.3s; } #particleSwitch.active { background: #40a9ff; } #particleSwitch.active::after { left: 22px; } #particlesCanvas { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; pointer-events: none; z-index: -1; display: none; } `); // 插入开关DOM const box = document.createElement('div'); box.id = 'particleToggleBox'; box.innerHTML = ` 粒子特效
`; document.body.appendChild(box); // 画布 const canvas = document.createElement('canvas'); canvas.id = 'particlesCanvas'; document.body.appendChild(canvas); const ctx = canvas.getContext('2d'); let w, h; let particles = []; let animateId = null; const switchEl = document.getElementById('particleSwitch'); // 窗口尺寸适配 function resize() { w = canvas.width = window.innerWidth; h = canvas.height = window.innerHeight; } resize(); window.addEventListener('resize', resize); // 粒子类 class Particle { constructor() { this.x = Math.random() * w; this.y = Math.random() * h; this.r = Math.random() * 1.2 + 0.3; this.speedX = Math.random() * 0.6 - 0.3; this.speedY = Math.random() * 0.6 - 0.3; this.alpha = Math.random() * 0.5 + 0.2; } update() { this.x += this.speedX; this.y += this.speedY; if (this.x < 0) this.x = w; if (this.x > w) this.x = 0; if (this.y < 0) this.y = h; if (this.y > h) this.y = 0; } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2); ctx.fillStyle = `rgba(130, 190, 255, ${this.alpha})`; ctx.fill(); } } // 初始化粒子 function initParticles(count = 120) { particles = []; for (let i = 0; i < count; i++) { particles.push(new Particle()); } } // 渲染动画 function render() { ctx.clearRect(0, 0, w, h); particles.forEach(p => { p.update(); p.draw(); }); animateId = requestAnimationFrame(render); } // 开关点击事件 switchEl.onclick = () => { const isOn = switchEl.classList.contains('active'); if (!isOn) { // 开启粒子 switchEl.classList.add('active'); canvas.style.display = 'block'; initParticles(); render(); } else { // 关闭粒子 switchEl.classList.remove('active'); canvas.style.display = 'none'; cancelAnimationFrame(animateId); } }; })();