您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Таймер с топом, онлайн-статусом и премиум дизайном
// ==UserScript== // @name Drawaria Time Tracker // @namespace http://tampermonkey.net/ // @author лазер дмитрий прайм // @version 6.3 // @description Таймер с топом, онлайн-статусом и премиум дизайном // @match https://drawaria.online/* // @grant none // @author GothbreachHelper // @license MIT // ==/UserScript== (function() { // Конфигурация const TOP_SIZE = 100; const TOP_KEY = 'drawariaGlobalTop'; const ONLINE_KEY = 'drawariaOnlineUsers'; const USER_ID = Math.random().toString(36).substr(2, 9); const USER_NAME = `Player${Math.floor(Math.random() * 1000)}`; const COLORS = { primary: '#4cc9f0', secondary: '#4361ee', accent: '#f72585', success: '#4ade80', danger: '#ff6b6b', warning: '#ffcc00', dark: '#1a1a2e' }; // Стили с анимациями const style = document.createElement('style'); style.textContent = ` @keyframes fadeIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } @keyframes glow { 0% { box-shadow: 0 0 5px ${COLORS.primary}; } 50% { box-shadow: 0 0 20px ${COLORS.primary}; } 100% { box-shadow: 0 0 5px ${COLORS.primary}; } } .timer-container { position: fixed; top: 100px; right: 20px; background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); color: white; padding: 20px; border-radius: 15px; z-index: 9999; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; border: 2px solid ${COLORS.primary}; box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37); backdrop-filter: blur(4px); min-width: 300px; opacity: 0; transform: translateY(-20px); transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); animation: glow 3s infinite; } .timer-container.visible { opacity: 1; transform: translateY(0); } .drag-header { cursor: move; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid rgba(76, 201, 240, 0.3); text-align: center; font-weight: bold; color: ${COLORS.primary}; font-size: 20px; text-shadow: 0 0 10px ${COLORS.primary}; letter-spacing: 1px; display: flex; justify-content: center; align-items: center; } .drag-header::before, .drag-header::after { content: '✦'; margin: 0 10px; color: ${COLORS.accent}; animation: pulse 2s infinite; } .time-display { font-size: 32px; text-align: center; margin: 20px 0; font-family: 'Courier New', monospace; background: rgba(0, 0, 0, 0.3); padding: 15px; border-radius: 12px; border: 1px solid rgba(76, 201, 240, 0.2); color: #f8f9fa; text-shadow: 0 0 10px ${COLORS.primary}; letter-spacing: 3px; position: relative; overflow: hidden; } .time-display::after { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient(transparent, rgba(76, 201, 240, 0.1), transparent); transform: rotate(30deg); animation: shine 6s infinite; } @keyframes shine { 0% { transform: rotate(30deg) translate(-10%, -10%); } 100% { transform: rotate(30deg) translate(90%, 90%); } } .controls-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 20px; } .timer-btn { background: linear-gradient(to right, ${COLORS.secondary}, #3a0ca3); color: white; border: none; padding: 12px 5px; border-radius: 10px; cursor: pointer; font-weight: 600; transition: all 0.3s ease; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); outline: none; position: relative; overflow: hidden; } .timer-btn::after { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: rgba(255,255,255,0.1); transform: rotate(30deg); transition: all 0.6s; } .timer-btn:hover { transform: translateY(-5px) scale(1.05); box-shadow: 0 8px 15px rgba(0, 0, 0, 0.3); background: linear-gradient(to right, #4895ef, ${COLORS.secondary}); } .timer-btn:hover::after { transform: rotate(30deg) translate(10%, 10%); } .timer-btn:active { transform: translateY(2px); } .menu-btn { position: fixed; top: 15px; right: 15px; background: linear-gradient(135deg, ${COLORS.secondary} 0%, #3a0ca3 100%); color: white; border: none; padding: 14px 24px; border-radius: 30px; cursor: pointer; z-index: 9998; font-family: 'Segoe UI', sans-serif; font-weight: bold; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3); transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); letter-spacing: 1px; text-shadow: 0 1px 2px rgba(0,0,0,0.5); animation: pulse 3s infinite; } .menu-btn:hover { transform: translateY(-5px) scale(1.1); box-shadow: 0 12px 25px rgba(0, 0, 0, 0.4); } .saves-container, .top-container, .online-container { max-height: 250px; overflow-y: auto; margin-top: 20px; border-top: 1px solid rgba(76, 201, 240, 0.3); padding-top: 15px; display: none; border-radius: 8px; background: rgba(0, 0, 0, 0.2); padding: 15px; } .container-header { text-align: center; font-weight: bold; margin-bottom: 15px; color: ${COLORS.primary}; font-size: 18px; position: relative; padding-bottom: 10px; } .container-header::after { content: ''; position: absolute; bottom: 0; left: 25%; width: 50%; height: 2px; background: linear-gradient(to right, transparent, ${COLORS.primary}, transparent); } .save-item { display: flex; justify-content: space-between; align-items: center; padding: 12px; margin: 8px 0; background: rgba(76, 201, 240, 0.15); border-radius: 8px; cursor: pointer; transition: all 0.3s; border-left: 3px solid ${COLORS.primary}; } .save-item:hover { background: rgba(76, 201, 240, 0.3); transform: translateX(10px); box-shadow: 0 5px 15px rgba(0,0,0,0.2); } .delete-btn { background: ${COLORS.danger}; color: white; border: none; border-radius: 50%; width: 26px; height: 26px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-weight: bold; transition: all 0.3s; box-shadow: 0 2px 5px rgba(0,0,0,0.2); } .delete-btn:hover { background: #ff4c4c; transform: scale(1.2) rotate(90deg); } .top-item { display: flex; align-items: center; padding: 10px 15px; margin: 8px 0; background: rgba(28, 58, 128, 0.3); border-radius: 8px; font-size: 14px; transition: all 0.3s; border-left: 3px solid ${COLORS.accent}; } .top-item:hover { transform: translateY(-3px); box-shadow: 0 5px 15px rgba(0,0,0,0.2); } .top-position { background: ${COLORS.primary}; color: #16213e; border-radius: 50%; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; font-weight: bold; margin-right: 15px; font-size: 14px; box-shadow: 0 0 10px ${COLORS.primary}; } .top-you { background: ${COLORS.warning}; color: #000; box-shadow: 0 0 10px ${COLORS.warning}; } .top-name { flex-grow: 1; font-weight: bold; } .online-item { display: flex; justify-content: space-between; align-items: center; padding: 12px 15px; margin: 8px 0; background: rgba(76, 201, 240, 0.15); border-radius: 8px; animation: pulse 2s infinite; border-left: 3px solid ${COLORS.success}; transition: all 0.3s; } .online-item:hover { transform: scale(1.02); box-shadow: 0 0 15px rgba(76, 201, 240, 0.5); } .online-you { background: rgba(255, 204, 0, 0.25); border-left: 3px solid ${COLORS.warning}; } .online-time { font-family: 'Courier New', monospace; font-weight: bold; font-size: 16px; color: ${COLORS.primary}; text-shadow: 0 0 5px ${COLORS.primary}; } .delete-top-btn { background: ${COLORS.danger}; color: white; border: none; border-radius: 5px; padding: 5px 10px; margin-left: 10px; font-size: 12px; cursor: pointer; transition: all 0.3s; } .delete-top-btn:hover { background: #ff4c4c; transform: scale(1.1); } /* Стили для скроллбара */ *::-webkit-scrollbar { width: 8px; } *::-webkit-scrollbar-track { background: rgba(0,0,0,0.1); border-radius: 4px; } *::-webkit-scrollbar-thumb { background: ${COLORS.primary}; border-radius: 4px; } *::-webkit-scrollbar-thumb:hover { background: ${COLORS.accent}; } `; document.head.appendChild(style); // Создание элементов интерфейса const menuButton = document.createElement('button'); menuButton.className = 'menu-btn'; menuButton.innerHTML = '⏱️ ТАЙМЕР <span class="pulse-dot"></span>'; menuButton.style.opacity = '0'; const timerContainer = document.createElement('div'); timerContainer.className = 'timer-container'; const dragHeader = document.createElement('div'); dragHeader.className = 'drag-header'; dragHeader.textContent = 'ULTIMATE TIME TRACKER'; const timeDisplay = document.createElement('div'); timeDisplay.className = 'time-display'; timeDisplay.textContent = '00:00:00'; const controls = document.createElement('div'); controls.className = 'controls-grid'; // Функция создания кнопок с иконками const createButton = (text, icon) => { const btn = document.createElement('button'); btn.className = 'timer-btn'; btn.innerHTML = `${icon} ${text}`; return btn; }; // Создаем кнопки с иконками const btnStart = createButton('СТАРТ', '▶️'); const btnPause = createButton('ПАУЗА', '⏸️'); const btnReset = createButton('СБРОС', '⏹️'); const btnSave = createButton('СОХРАНИТЬ', '💾'); const btnLoad = createButton('ЗАГРУЗИТЬ', '📂'); const btnTop = createButton('ТОП', '🏆'); const btnOnline = createButton('ОНЛАЙН', '👥'); const btnClose = createButton('ЗАКРЫТЬ', '✖️'); // Собираем интерфейс controls.appendChild(btnStart); controls.appendChild(btnPause); controls.appendChild(btnReset); controls.appendChild(btnSave); controls.appendChild(btnLoad); controls.appendChild(btnTop); controls.appendChild(btnOnline); controls.appendChild(btnClose); timerContainer.appendChild(dragHeader); timerContainer.appendChild(timeDisplay); timerContainer.appendChild(controls); // Контейнеры const savesContainer = document.createElement('div'); savesContainer.className = 'saves-container'; timerContainer.appendChild(savesContainer); const topContainer = document.createElement('div'); topContainer.className = 'top-container'; timerContainer.appendChild(topContainer); const onlineContainer = document.createElement('div'); onlineContainer.className = 'online-container'; timerContainer.appendChild(onlineContainer); document.body.appendChild(timerContainer); document.body.appendChild(menuButton); // Анимация появления setTimeout(() => { menuButton.style.transition = 'opacity 0.6s ease-out, transform 0.6s ease-out'; menuButton.style.opacity = '1'; menuButton.animate([ { transform: 'translateY(-20px)', opacity: 0 }, { transform: 'translateY(0)', opacity: 1 } ], { duration: 800, easing: 'ease-out' }); }, 300); // Логика таймера let startTime = 0; let elapsedTime = 0; let timerInterval = null; let isRunning = false; let onlineStatusInterval = null; function formatTime(ms) { if (isNaN(ms)) ms = 0; const totalSec = Math.floor(ms / 1000); const hours = Math.floor(totalSec / 3600).toString().padStart(2, '0'); const minutes = Math.floor((totalSec % 3600) / 60).toString().padStart(2, '0'); const seconds = (totalSec % 60).toString().padStart(2, '0'); return `${hours}:${minutes}:${seconds}`; } function updateTimer() { elapsedTime = Date.now() - startTime; timeDisplay.textContent = formatTime(elapsedTime); // Анимация обновления времени timeDisplay.animate([ { opacity: 0.7, transform: 'scale(0.95)' }, { opacity: 1, transform: 'scale(1)' } ], { duration: 300, easing: 'ease-out' }); // Анимация для цифр const digits = timeDisplay.textContent.split(''); timeDisplay.innerHTML = digits.map(d => `<span style="display:inline-block; transition: all 0.3s;">${d}</span>` ).join(''); setTimeout(() => { timeDisplay.querySelectorAll('span').forEach((span, i) => { span.animate([ { transform: 'translateY(0)', textShadow: '0 0 5px #4cc9f0' }, { transform: 'translateY(-10px)', textShadow: '0 0 15px #4cc9f0' }, { transform: 'translateY(0)', textShadow: '0 0 5px #4cc9f0' } ], { duration: 500, delay: i * 100, easing: 'ease-out' }); }); }, 50); } // Функции для работы с топом function updateGlobalTop() { const topData = JSON.parse(localStorage.getItem(TOP_KEY)) || []; topContainer.innerHTML = ''; if (topData.length === 0) { topContainer.innerHTML = '<div class="container-header">Топ пуст</div>'; return; } const header = document.createElement('div'); header.className = 'container-header'; header.textContent = `ГЛОБАЛЬНЫЙ ТОП • ${Math.min(topData.length, TOP_SIZE)}/${TOP_SIZE}`; topContainer.appendChild(header); topData.slice(0, 10).forEach((entry, index) => { const item = document.createElement('div'); item.className = 'top-item'; const position = document.createElement('div'); position.className = `top-position ${entry.you ? 'top-you' : ''}`; position.textContent = index + 1; const name = document.createElement('div'); name.className = 'top-name'; name.textContent = entry.name; const time = document.createElement('div'); time.textContent = formatTime(entry.time); item.appendChild(position); item.appendChild(name); item.appendChild(time); if (entry.you) { const deleteBtn = document.createElement('button'); deleteBtn.className = 'delete-top-btn'; deleteBtn.textContent = 'Удалить'; deleteBtn.title = 'Удалить из топа'; deleteBtn.addEventListener('click', (e) => { e.stopPropagation(); item.animate([ { opacity: 1, transform: 'scale(1) rotate(0deg)' }, { opacity: 0, transform: 'scale(0.8) rotate(10deg)' } ], { duration: 500, easing: 'ease-out' }); setTimeout(() => { const updatedTop = topData.filter(e => !(e.time === entry.time && e.date === entry.date) ); localStorage.setItem(TOP_KEY, JSON.stringify(updatedTop)); updateGlobalTop(); }, 500); }); item.appendChild(deleteBtn); } topContainer.appendChild(item); }); } function saveToGlobalTop() { const playerName = prompt('Введите ваше имя для топа:', USER_NAME); if (!playerName) return; const topData = JSON.parse(localStorage.getItem(TOP_KEY)) || []; const newEntry = { id: USER_ID, name: playerName, time: elapsedTime, date: Date.now(), you: true }; topData.push(newEntry); topData.sort((a, b) => b.time - a.time); if (topData.length > TOP_SIZE) { topData.length = TOP_SIZE; } localStorage.setItem(TOP_KEY, JSON.stringify(topData)); updateGlobalTop(); // Эффектная анимация сохранения timeDisplay.animate([ { textShadow: '0 0 5px #ffcc00' }, { textShadow: '0 0 30px #ffcc00' }, { textShadow: '0 0 5px #ffcc00' } ], { duration: 2000, easing: 'ease-in-out' }); timerContainer.animate([ { boxShadow: '0 0 10px #ffcc00' }, { boxShadow: '0 0 30px #ffcc00' }, { boxShadow: '0 0 10px #4cc9f0' } ], { duration: 2000, easing: 'ease-in-out' }); } // Функции для онлайн-статуса function updateOnlineStatus() { const onlineUsers = JSON.parse(localStorage.getItem(ONLINE_KEY)) || {}; onlineUsers[USER_ID] = { name: USER_NAME, time: elapsedTime, lastUpdate: Date.now(), you: true }; localStorage.setItem(ONLINE_KEY, JSON.stringify(onlineUsers)); } function updateOnlineList() { onlineContainer.innerHTML = ''; const onlineUsers = JSON.parse(localStorage.getItem(ONLINE_KEY)) || {}; // Удаляем неактивных Object.keys(onlineUsers).forEach(id => { if (Date.now() - onlineUsers[id].lastUpdate > 10000) { delete onlineUsers[id]; } }); localStorage.setItem(ONLINE_KEY, JSON.stringify(onlineUsers)); if (Object.keys(onlineUsers).length === 0) { onlineContainer.innerHTML = '<div class="container-header">Нет активных пользователей</div>'; return; } const header = document.createElement('div'); header.className = 'container-header'; header.textContent = `ОНЛАЙН • ${Object.keys(onlineUsers).length} ПОЛЬЗОВАТЕЛЕЙ`; onlineContainer.appendChild(header); Object.values(onlineUsers).forEach(user => { const item = document.createElement('div'); item.className = `online-item ${user.you ? 'online-you' : ''}`; const name = document.createElement('div'); name.textContent = user.you ? `Вы (${user.name})` : user.name; name.style.fontWeight = 'bold'; const time = document.createElement('div'); time.className = 'online-time'; time.textContent = formatTime(user.time); item.appendChild(name); item.appendChild(time); onlineContainer.appendChild(item); // Анимация для новых пользователей if (Date.now() - user.lastUpdate < 3000) { item.animate([ { opacity: 0, transform: 'scale(0.8)' }, { opacity: 1, transform: 'scale(1)' } ], { duration: 500, easing: 'ease-out' }); } }); } // Обработчики кнопок с анимациями btnStart.addEventListener('click', () => { if (!isRunning) { startTime = Date.now() - elapsedTime; timerInterval = setInterval(updateTimer, 1000); isRunning = true; onlineStatusInterval = setInterval(updateOnlineStatus, 3000); updateOnlineStatus(); // Анимация кнопки btnStart.animate([ { transform: 'scale(1)' }, { transform: 'scale(1.3)' }, { transform: 'scale(1)' } ], { duration: 600, easing: 'ease-out' }); // Эффект пульсации timerContainer.animate([ { boxShadow: '0 0 10px #4cc9f0' }, { boxShadow: '0 0 25px #4cc9f0' }, { boxShadow: '0 0 10px #4cc9f0' } ], { duration: 1500, easing: 'ease-in-out' }); } }); btnPause.addEventListener('click', () => { if (isRunning) { clearInterval(timerInterval); clearInterval(onlineStatusInterval); isRunning = false; updateOnlineStatus(); // Анимация заморозки timeDisplay.animate([ { textShadow: '0 0 10px rgba(76, 201, 240, 0.8)' }, { textShadow: '0 0 2px rgba(76, 201, 240, 0.2)' } ], { duration: 1000, easing: 'ease-out' }); } }); btnReset.addEventListener('click', () => { clearInterval(timerInterval); clearInterval(onlineStatusInterval); elapsedTime = 0; timeDisplay.textContent = '00:00:00'; isRunning = false; updateOnlineStatus(); // Анимация сброса timeDisplay.animate([ { transform: 'rotate(0deg) scale(1)' }, { transform: 'rotate(15deg) scale(1.2)' }, { transform: 'rotate(-15deg) scale(1.2)' }, { transform: 'rotate(0deg) scale(1)' } ], { duration: 800, easing: 'ease-in-out' }); }); btnSave.addEventListener('click', () => { const saveToTop = confirm('Сохранить в глобальный топ? (OK - да, Отмена - локальное сохранение)'); if (saveToTop) { saveToGlobalTop(); } else { const saveName = prompt('Введите имя сохранения:', `Сессия ${new Date().toLocaleDateString()}`); if (saveName) { const saves = JSON.parse(localStorage.getItem('drawariaTimeSaves')) || {}; saves[saveName] = elapsedTime; localStorage.setItem('drawariaTimeSaves', JSON.stringify(saves)); // Анимация сохранения btnSave.animate([ { transform: 'scale(1)' }, { transform: 'scale(1.2) rotate(10deg)' }, { transform: 'scale(1) rotate(0deg)' } ], { duration: 600, easing: 'ease-out' }); } } }); btnOnline.addEventListener('click', () => { onlineContainer.style.display = onlineContainer.style.display === 'none' ? 'block' : 'none'; savesContainer.style.display = 'none'; topContainer.style.display = 'none'; if (onlineContainer.style.display === 'block') { updateOnlineList(); } }); // Обработчики остальных кнопок btnLoad.addEventListener('click', () => { savesContainer.style.display = savesContainer.style.display === 'none' ? 'block' : 'none'; topContainer.style.display = 'none'; onlineContainer.style.display = 'none'; }); btnTop.addEventListener('click', () => { topContainer.style.display = topContainer.style.display === 'none' ? 'block' : 'none'; savesContainer.style.display = 'none'; onlineContainer.style.display = 'none'; }); btnClose.addEventListener('click', () => { timerContainer.classList.remove('visible'); setTimeout(() => { timerContainer.style.display = 'none'; }, 500); }); menuButton.addEventListener('click', () => { if (timerContainer.style.display === 'none' || !timerContainer.style.display) { timerContainer.style.display = 'block'; setTimeout(() => { timerContainer.classList.add('visible'); }, 10); } else { timerContainer.classList.remove('visible'); setTimeout(() => { timerContainer.style.display = 'none'; }, 500); } }); // Перетаскивание окна let isDragging = false; let offsetX, offsetY; dragHeader.addEventListener('mousedown', (e) => { isDragging = true; offsetX = e.clientX - timerContainer.getBoundingClientRect().left; offsetY = e.clientY - timerContainer.getBoundingClientRect().top; timerContainer.style.cursor = 'grabbing'; timerContainer.animate([ { transform: 'scale(1)' }, { transform: 'scale(0.98)' } ], { duration: 200, fill: 'forwards' }); }); document.addEventListener('mousemove', (e) => { if (isRunning) { updateOnlineStatus(); } if (isDragging) { timerContainer.style.left = (e.clientX - offsetX) + 'px'; timerContainer.style.top = (e.clientY - offsetY) + 'px'; timerContainer.style.right = 'unset'; } }); document.addEventListener('mouseup', () => { if (isDragging) { isDragging = false; timerContainer.style.cursor = 'default'; timerContainer.animate([ { transform: 'scale(0.98)' }, { transform: 'scale(1)' } ], { duration: 300, easing: 'ease-out' }); } }); // Инициализация window.addEventListener('load', () => { // Создание демо-топа if (!localStorage.getItem(TOP_KEY)) { const demoTop = []; const names = ['Alex', 'Mia', 'Max', 'Luna', 'Leo', 'Zoe', 'Finn', 'Ruby']; for (let i = 0; i < 15; i++) { demoTop.push({ id: Math.random().toString(36).substr(2, 9), name: names[Math.floor(Math.random() * names.length)] + Math.floor(Math.random() * 100), time: 3600000 + Math.floor(Math.random() * 36000000), date: Date.now() - Math.floor(Math.random() * 30 * 24 * 3600000), you: false }); } demoTop.sort((a, b) => b.time - a.time); localStorage.setItem(TOP_KEY, JSON.stringify(demoTop)); } // Анимация приветствия setTimeout(() => { timeDisplay.animate([ { textShadow: '0 0 5px #4cc9f0' }, { textShadow: '0 0 30px #4cc9f0' }, { textShadow: '0 0 5px #4cc9f0' } ], { duration: 2500, easing: 'ease-in-out' }); menuButton.animate([ { transform: 'scale(1)' }, { transform: 'scale(1.1)' }, { transform: 'scale(1)' } ], { duration: 2000, iterations: Infinity, easing: 'ease-in-out' }); }, 1000); // Периодическое обновление онлайн-статуса setInterval(() => { if (onlineContainer.style.display === 'block') { updateOnlineList(); } }, 5000); }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址