Zero observers, minimal DOM, aggressive caching, and ultra-low CPU usage.
// ==UserScript==
// @name 💙💛 Ukrainian Flag & Flowers (Ctrl+Shift+U)
// @namespace tampermonkey.net
// @version 17.2
// @description Zero observers, minimal DOM, aggressive caching, and ultra-low CPU usage.
// @author 邢智轩 (from China)
// @match *://*/*
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 防止重复初始化
const SCRIPT_VERSION = '23.0-ultra-lite';
if (window.__UA_FLAG_SCRIPT_VER__ === SCRIPT_VERSION && window.__UA_FLAG_INSTANCED__) return;
window.__UA_FLAG_INSTANCED__ = true;
window.__UA_FLAG_SCRIPT_VER__ = SCRIPT_VERSION;
// 清理旧版本残留
const oldHost = document.getElementById('ua-waving-badge-root');
if (oldHost) oldHost.remove();
// 三叉戟 SVG(内嵌优化)
const TRIDENT_SVG = `data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAwIDMwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTAwIDAgTDg1IDQ1IEw0MCA0NSBRMjAgNDUgMjAgODAgTDIwIDE4MCBRMjAgMjIwIDUwIDIyMCBMNjUgMjIwIEw2NSAxOTAgTDUwIDE5MCBRNDAgMTkwIDQwIDE3NSBMNDAgOTAgTDc1IDkwIEw4MCAxODAgUTgyIDI1MCAxMDAgMjUwIFExMTggMjUwIDEyMCAxODAgTDEyNSA5MCBMMTYwIDkwIEwxNjAgMTc1IFExNjAgMTkwIDE1MCAxOTAgTDEzNSAxOTAgTDEzNSAyMjAgTDE1MCAyMjAgUTE4MCAyMjAgMTgwIDE4MCBMMTgwIDgwIFExODAgNDUgMTYwIDQ1IEwxMTUgNDUgWiBNMTAwIDI2MCBMOTAgMzAwIEwxMTAgMzAwIFoiIGZpbGw9IiNGRkQ3MDAiLz48L3N2Zz4=`;
// 状态管理(极简)
let isDragging = false;
let offsetX = 0;
let offsetY = 0;
let rafId = null;
let hostElement = null;
let shadowRoot = null;
let lastSavedPos = null;
let lastMoveTime = 0;
let boundHandlers = null;
let isTerminated = false;
// 配置(极致节能)
const CONFIG = {
width: 320,
height: 200,
moveThrottle: 40, // 进一步降低移动频率
resizeDebounce: 500, // 减少 resize 触发频率
colors: {
blue: '#0057B7',
yellow: '#FFD700',
poleLight: '#FDC830',
poleDark: '#8B6508',
},
// 使用压缩字符串存储配置
sunflowers: '18,0,0.6,35,L,-0.2,150|35,0,0.85,58,R,-1.5,152|48,0,0.55,28,,-2.8,150|85,0,0.7,45,L,-3.3,150|110,0,0.75,52,,-0.9,150|155,0,0.6,40,,-4.1,150|215,0,0.65,38,,-1.2,150|25,8,0.45,18,,-1.1,160|70,5,0.4,15,,-3.7,160|135,10,0.5,22,,-0.5,160|195,4,0.4,16,,-2.9,160',
kalynaBranches: '2,0,0.5,-1.0,10,148|280,2,0.6,-2.5,-15,148|55,5,0.7,-3.5,5,149|260,10,0.55,-0.8,-10,149',
wheatStalks: '5,0,0.7,55,-5,-2.0,145|25,0,0.5,40,5,-3.5,145|295,0,0.6,50,8,-1.5,145|300,0,0.4,35,-3,-4.0,145',
candles: '115,2,0.7,171|135,2,0.8,170|155,2,0.75,169',
};
// 运行环境检查
const canRun = () => window.innerWidth >= 800 && window.self === window.top;
// 存储封装(极简)
const storage = {
get: (key, def) => {
try { return localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key)) : def; }
catch { return def; }
},
set: (key, value) => {
try { localStorage.setItem(key, JSON.stringify(value)); } catch {}
},
remove: (key) => {
try { localStorage.removeItem(key); } catch {}
},
};
// 坐标获取
const getClientCoords = (e) => ({
x: e.touches?.[0]?.clientX ?? e.clientX,
y: e.touches?.[0]?.clientY ?? e.clientY,
});
// --- 拖拽系统 ---
const startDrag = (e) => {
if (!hostElement) return;
attachGlobalListeners();
if (e.type === 'touchstart') e.preventDefault();
isDragging = true;
lastMoveTime = 0;
const rect = hostElement.getBoundingClientRect();
const coords = getClientCoords(e);
offsetX = coords.x - rect.left;
offsetY = coords.y - rect.top;
hostElement.style.transition = 'none';
hostElement.style.top = `${rect.top}px`;
hostElement.style.left = `${rect.left}px`;
hostElement.style.bottom = 'auto';
};
const onMove = (e) => {
if (!isDragging || !hostElement) return;
const now = performance.now();
if (now - lastMoveTime < CONFIG.moveThrottle) return;
lastMoveTime = now;
if (e.type === 'touchmove') e.preventDefault();
if (rafId) return;
rafId = requestAnimationFrame(() => {
const coords = getClientCoords(e);
let x = Math.max(0, coords.x - offsetX);
let y = Math.max(0, coords.y - offsetY);
const maxX = window.innerWidth - CONFIG.width;
const maxY = window.innerHeight - CONFIG.height;
if (maxX > 0) x = Math.min(x, maxX);
if (maxY > 0) y = Math.min(y, maxY);
if (hostElement) {
hostElement.style.left = `${x}px`;
hostElement.style.top = `${y}px`;
}
rafId = null;
});
};
const endDrag = () => {
if (!isDragging) return;
isDragging = false;
detachGlobalListeners();
if (hostElement) {
hostElement.style.transition = 'all 0.8s cubic-bezier(0.16, 1, 0.3, 1)';
const rect = hostElement.getBoundingClientRect();
const currentPos = { left: rect.left, top: rect.top };
if (!lastSavedPos || lastSavedPos.left !== currentPos.left || lastSavedPos.top !== currentPos.top) {
storage.set('ua-flag-pos', currentPos);
lastSavedPos = currentPos;
}
}
};
// 事件监听器管理
function attachGlobalListeners() {
if (boundHandlers) return;
boundHandlers = { mouseMove: onMove, touchMove: onMove, mouseUp: endDrag, touchEnd: endDrag };
document.addEventListener('mousemove', boundHandlers.mouseMove, { passive: true });
document.addEventListener('touchmove', boundHandlers.touchMove, { passive: false });
window.addEventListener('mouseup', boundHandlers.mouseUp, { passive: true });
window.addEventListener('touchend', boundHandlers.touchEnd, { passive: true });
window.addEventListener('touchcancel', boundHandlers.touchEnd, { passive: true });
}
function detachGlobalListeners() {
if (!boundHandlers) return;
document.removeEventListener('mousemove', boundHandlers.mouseMove);
document.removeEventListener('touchmove', boundHandlers.touchMove);
window.removeEventListener('mouseup', boundHandlers.mouseUp);
window.removeEventListener('touchend', boundHandlers.touchEnd);
window.removeEventListener('touchcancel', boundHandlers.touchEnd);
boundHandlers = null;
}
// 边界校正
const ensureInBounds = () => {
if (!hostElement || !lastSavedPos || hostElement.style.top === 'auto') return;
const maxX = window.innerWidth - CONFIG.width;
const maxY = window.innerHeight - CONFIG.height;
let { left, top } = lastSavedPos;
let updated = false;
if (left > maxX) { left = Math.max(0, maxX); updated = true; }
if (top > maxY) { top = Math.max(0, maxY); updated = true; }
if (updated) {
hostElement.style.left = `${left}px`;
hostElement.style.top = `${top}px`;
storage.set('ua-flag-pos', { left, top });
lastSavedPos = { left, top };
}
};
// 复位位置
const resetBadgePosition = () => {
storage.remove('ua-flag-pos');
lastSavedPos = null;
if (hostElement) {
hostElement.style.bottom = '60px';
hostElement.style.left = '60px';
hostElement.style.top = 'auto';
hostElement.style.transform = 'translateX(0) scale(0.95)';
setTimeout(() => {
if (hostElement) hostElement.style.transform = 'translateX(0) scale(1)';
}, 150);
}
};
// HTML 生成(极简字符串模板)
function generateBadgeHTML() {
// 解析配置字符串
const parseConfig = (str, template) => {
return str.split('|').map((item, idx) => {
const params = item.split(',');
return template(...params, idx);
}).join('');
};
const sunflowersHtml = parseConfig(CONFIG.sunflowers, (l, b, s, h, leaf, d, z) =>
`<div class="sunflower" style="left:${l}px;bottom:${b}px;transform:scale(${s});animation-delay:${d}s;z-index:${z}"><div class="flower-head"><div class="petals"></div><div class="core"></div></div><div class="stem" style="height:${h}px">${leaf ? `<div class="sf-leaf leaf-${leaf}"></div>` : ''}</div></div>`
);
const kalynaHtml = parseConfig(CONFIG.kalynaBranches, (l, b, s, d, rot, z, idx) => {
const greenVar = idx % 2 === 0 ? '#2E7D32' : '#43A047';
return `<div class="kalyna-branch" style="left:${l}px;bottom:${b}px;transform:scale(${s}) rotate(${rot}deg);animation-delay:${d}s;z-index:${z}"><div class="k-cluster"><div class="k-berry" style="background:radial-gradient(circle at 30% 30%,#ff5252,#b71c1c)"></div><div class="k-berry" style="background:radial-gradient(circle at 30% 30%,#ef5350,#c62828);width:8px;height:8px;left:12px;top:5px"></div><div class="k-berry" style="background:radial-gradient(circle at 30% 30%,#e53935,#c62828);width:7px;height:7px;left:6px;top:-4px"></div></div><div class="k-leaf k-l1" style="background-color:${greenVar}"></div><div class="k-leaf k-l2" style="background-color:${greenVar}"></div><div class="k-stem"></div></div>`;
});
const wheatHtml = parseConfig(CONFIG.wheatStalks, (l, b, s, h, rot, d, z) =>
`<div class="wheat-stalk" style="left:${l}px;bottom:${b}px;transform:scale(${s}) rotate(${rot}deg);animation-delay:${d}s;z-index:${z}"><div class="w-head"><div class="w-grain r1"></div><div class="w-grain r2"></div><div class="w-grain r3"></div><div class="w-grain r4"></div><div class="w-grain r5"></div></div><div class="w-stem" style="height:${h}px"></div><div class="w-leaf"></div></div>`
);
const candleHtml = parseConfig(CONFIG.candles, (l, b, s, z) =>
`<div class="candle-setup" style="left:${l}px;bottom:${b}px;transform:scale(${s});z-index:${z}"><div class="c-flame"><div class="f-inner"></div></div><div class="c-wick"></div><div class="c-wax"></div><div class="c-glow"></div></div>`
);
return `<style>:host{display:block;--ua-blue:${CONFIG.colors.blue};--ua-yellow:${CONFIG.colors.yellow};--pole-l:${CONFIG.colors.poleLight};--pole-d:${CONFIG.colors.poleDark}}.container{position:relative;width:100%;height:100%;display:flex;align-items:flex-end;user-select:none;overflow:hidden;pointer-events:none;-webkit-user-select:none}.drag-handle{position:absolute;left:25px;top:20px;width:45px;height:160px;z-index:999;pointer-events:auto;cursor:move;touch-action:none}.pole-system{position:absolute;left:40px;bottom:20px;height:160px;display:flex;flex-direction:column;align-items:center;z-index:100;pointer-events:none}.pole-top{width:14px;height:14px;background:radial-gradient(circle at 35% 35%,#FFFACD 0%,var(--ua-yellow) 45%,#C5A059 100%);border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.4);margin-bottom:-2px}.pole-body{width:8px;height:100%;background:linear-gradient(to right,var(--pole-d) 0%,#B8860B 15%,var(--pole-l) 40%,#FFF8E1 55%,var(--pole-l) 70%,#B8860B 85%,var(--pole-d) 100%);border-radius:0 0 4px 4px}.flag-wrapper{position:absolute;left:44px;top:32px;width:150px;height:90px;perspective:1200px;z-index:50;pointer-events:none}.flag{width:100%;height:100%;transform-style:preserve-3d;transform-origin:left center;animation:cinematic-wave 6s infinite ease-in-out;transform:translate3d(0,0,0)}.fabric{position:absolute;inset:0;background:linear-gradient(to bottom,var(--ua-blue) 50%,var(--ua-yellow) 50%);border-radius:0 4px 4px 0;overflow:hidden;display:flex;align-items:center;justify-content:center;box-shadow:inset 12px 0 15px rgba(0,0,0,.5);backface-visibility:hidden}.shading{position:absolute;inset:0;background:linear-gradient(90deg,rgba(0,0,0,.05) 0%,rgba(255,255,255,.15) 25%,rgba(0,0,0,.1) 50%,rgba(255,255,255,.15) 75%,rgba(0,0,0,.05) 100%);background-size:200% 100%;animation:move-shade 4s infinite linear;pointer-events:none}.trident{width:30px;filter:drop-shadow(0 4px 8px rgba(0,0,0,.4));transform:translateZ(10px)}.garden{position:absolute;left:0;bottom:0;width:100%;height:85px;pointer-events:none;contain:layout style paint}.sunflower,.kalyna-branch,.wheat-stalk{position:absolute;display:flex;flex-direction:column;align-items:center;transform-origin:bottom center}.sunflower{animation:flower-sway 5s infinite ease-in-out}.kalyna-branch{animation:flower-sway 6s infinite ease-in-out}.wheat-stalk{animation:flower-sway 7s infinite ease-in-out}.flower-head{width:24px;height:24px;position:relative}.petals{position:absolute;inset:0;background:radial-gradient(ellipse at center,#FFD700 35%,transparent 75%),repeating-conic-gradient(from 0deg,#FFC107 0deg 20deg,#F57F17 20deg 40deg);border-radius:50%}.petals::before{content:'';position:absolute;inset:-3px;background:repeating-conic-gradient(from 10deg,transparent 0deg 15deg,#FFD700 15deg 35deg,transparent 35deg 40deg);border-radius:50%;mask:radial-gradient(circle,black 40%,transparent 85%);-webkit-mask:radial-gradient(circle,black 40%,transparent 85%)}.core{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:8px;height:8px;background:#3E2723;border-radius:50%;box-shadow:inset 0 0 3px #000;z-index:2}.stem{width:2.5px;background:linear-gradient(to right,#1B5E20,#388E3C,#1B5E20);border-radius:2px;position:relative}.sf-leaf{position:absolute;width:9px;height:6px;background:radial-gradient(at 20% 20%,#66BB6A,#1B5E20);border-radius:1px 80% 1px 80%}.leaf-L{left:-8px;top:12px;transform:rotate(-20deg)}.leaf-R{right:-8px;top:18px;transform:scaleX(-1) rotate(-20deg)}.k-cluster{position:relative;top:-4px;left:-2px}.k-berry{width:10px;height:10px;border-radius:50%;position:absolute;top:0;left:0;box-shadow:1px 1px 2px rgba(0,0,0,.2)}.k-leaf{position:absolute;width:12px;height:6px;border-radius:50% 0 50% 0;clip-path:polygon(0% 100%,50% 0%,100% 100%)}.k-l1{bottom:4px;left:-8px;transform:rotate(-20deg)}.k-l2{bottom:6px;left:6px;transform:scaleX(-1) rotate(-25deg)}.k-stem{width:2px;height:35px;background:linear-gradient(to right,#2E7D32,#66BB6A);transform-origin:top center}.w-head{position:relative;width:10px;height:25px;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;margin-bottom:-2px}.w-grain{width:6px;height:8px;background:radial-gradient(circle at 30% 30%,#FFECB3,#FFB300);border-radius:50% 50% 50% 50% / 60% 60% 40% 40%;position:absolute;box-shadow:1px 1px 2px rgba(0,0,0,.2)}.r1{transform:rotate(-15deg) translateX(-4px);top:0}.r2{transform:rotate(15deg) translateX(4px);top:2px}.r3{top:5px;z-index:2;width:7px;height:9px}.r4{transform:rotate(-10deg) translateX(-3px);top:9px}.r5{transform:rotate(10deg) translateX(3px);top:11px}.w-stem{width:2px;background:linear-gradient(to right,#E6EE9C,#CDDC39);position:relative}.w-leaf{position:absolute;width:12px;height:3px;background:#CDDC39;bottom:10px;left:-10px;transform:rotate(-20deg);border-radius:50% 0 50% 0}.candle-setup{position:absolute;display:flex;flex-direction:column;align-items:center}.c-wax{width:14px;height:20px;background:linear-gradient(to right,#fafafa,#e0e0e0,#bdbdbd);border-radius:2px;box-shadow:inset -2px 0 5px rgba(0,0,0,.1)}.c-wick{width:2px;height:6px;background:#333;margin-bottom:-2px}.c-flame{width:10px;height:18px;background:radial-gradient(ellipse at 50% 85%,#FFFFFF 10%,#ffeb3b 40%,#ff9800 90%,#bf360c 100%);border-radius:50% 50% 50% 50% / 60% 60% 40% 40%;transform-origin:center bottom;animation:flicker .15s infinite alternate;position:relative;top:-2px;transform:translate3d(0,0,0)}.f-inner{position:absolute;bottom:2px;left:3px;width:4px;height:6px;background:rgba(255,255,255,.9);border-radius:50%;filter:blur(1px)}.c-glow{position:absolute;top:-50px;left:-30px;width:70px;height:70px;background:radial-gradient(circle,rgba(255,235,59,.35) 0%,transparent 60%);animation:glow-pulse 3s infinite ease-in-out;pointer-events:none;mix-blend-mode:screen}.ua-paused *{animation-play-state:paused !important}@keyframes cinematic-wave{0%,100%{transform:rotateY(12deg) rotateX(2deg) translate3d(0,0,0)}50%{transform:rotateY(26deg) rotateX(-2deg) translate3d(0,0,0)}}@keyframes flower-sway{0%,100%{transform:rotate(-3deg) translate3d(0,0,0)}50%{transform:rotate(3deg) translate3d(0,0,0)}}@keyframes move-shade{from{background-position:0 0}to{background-position:200% 0}}@keyframes flicker{0%{transform:scale(1) rotate(-2deg) translate3d(0,0,0)}100%{transform:scale(1.02) rotate(2deg) translate3d(0,0,0)}}@keyframes glow-pulse{0%,100%{opacity:.5;transform:scale(1) translate3d(0,0,0)}50%{opacity:.8;transform:scale(1.1) translate3d(0,0,0)}}</style>
<div class="container">
<div class="drag-handle" title="拖动移动,双击复位"></div>
<div class="pole-system">
<div class="pole-top"></div>
<div class="pole-body"></div>
</div>
<div class="flag-wrapper">
<div class="flag">
<div class="fabric">
<div class="shading"></div>
<img src="${TRIDENT_SVG}" class="trident">
</div>
</div>
</div>
<div class="garden">
${wheatHtml}${kalynaHtml}${sunflowersHtml}${candleHtml}
</div>
</div>`;
}
// 注入徽章
function injectBadge() {
if (!canRun()) return;
if (hostElement?.isConnected) return;
const existingHost = document.getElementById('ua-waving-badge-root');
if (existingHost) {
hostElement = existingHost;
shadowRoot = existingHost.shadowRoot;
return;
}
const host = document.createElement('div');
host.id = 'ua-waving-badge-root';
host.setAttribute('aria-hidden', 'true');
host.lang = 'uk';
host.title = '🇺🇦 Ukraine - Слава Україні!';
lastSavedPos = storage.get('ua-flag-pos', null);
const styles = {
position: 'fixed',
zIndex: '2147483647',
pointerEvents: 'none',
transition: 'all 0.8s cubic-bezier(0.16,1,0.3,1)',
opacity: '0',
transform: 'translateX(-20px) scale(0.9)',
width: `${CONFIG.width}px`,
height: `${CONFIG.height}px`,
contain: 'layout style paint',
};
if (lastSavedPos && lastSavedPos.left >= 0 && lastSavedPos.left < window.innerWidth) {
styles.top = `${lastSavedPos.top}px`;
styles.left = `${lastSavedPos.left}px`;
} else {
styles.bottom = '60px';
styles.left = '60px';
}
Object.assign(host.style, styles);
document.documentElement.appendChild(host);
hostElement = host;
const shadow = host.attachShadow({ mode: 'closed' });
shadowRoot = shadow;
shadow.innerHTML = generateBadgeHTML();
const dragHandle = shadow.querySelector('.drag-handle');
if (dragHandle) {
dragHandle.addEventListener('mousedown', startDrag);
dragHandle.addEventListener('touchstart', startDrag, { passive: false });
dragHandle.addEventListener('dblclick', resetBadgePosition);
}
requestAnimationFrame(() => {
if (hostElement) {
hostElement.style.opacity = '1';
hostElement.style.transform = 'translateX(0) scale(1)';
}
});
}
// 销毁
function destroyBadge() {
if (rafId) cancelAnimationFrame(rafId);
if (hostElement) {
hostElement.remove();
hostElement = null;
}
shadowRoot = null;
detachGlobalListeners();
isTerminated = true;
}
// 视口可见性检测(极简)
let lastScrollTime = 0;
let scrollRafId = null;
const checkVisibility = () => {
if (!hostElement) return;
const rect = hostElement.getBoundingClientRect();
const isVisible = rect.right > 0 && rect.left < window.innerWidth && rect.bottom > 0 && rect.top < window.innerHeight;
hostElement.classList.toggle('ua-paused', !isVisible);
};
const onScrollOrResize = () => {
const now = performance.now();
if (now - lastScrollTime < 200) return;
lastScrollTime = now;
if (scrollRafId) return;
scrollRafId = requestAnimationFrame(() => {
checkVisibility();
ensureInBounds();
scrollRafId = null;
});
};
// 全局快捷键
window.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.shiftKey && e.code === 'KeyU') {
e.preventDefault();
hostElement ? destroyBadge() : canRun() && (isTerminated = false, injectBadge());
}
}, { passive: false, capture: true });
// 初始化
if (document.readyState === 'loading') {
window.addEventListener('DOMContentLoaded', () => {
injectBadge();
window.addEventListener('scroll', onScrollOrResize, { passive: true });
window.addEventListener('resize', onScrollOrResize, { passive: true });
}, { once: true, passive: true });
} else {
injectBadge();
window.addEventListener('scroll', onScrollOrResize, { passive: true });
window.addEventListener('resize', onScrollOrResize, { passive: true });
}
})();