您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
The script generates cool Snowflakes that fall down in your YouTube player. Editing varables: "q", "a", "w", "s". Backpace = on/off.
// ==UserScript== // @name YouTube - SnowFlakes // @namespace http://tampermonkey.net/ // @version 1.0 // @description The script generates cool Snowflakes that fall down in your YouTube player. Editing varables: "q", "a", "w", "s". Backpace = on/off. // @author Krzysztof Jarończyk // @match https://www.youtube.com/* // @grant none // @icon https://raw.githubusercontent.com/KrzysztofJaronczyk/YouTube-SnowFlakes/main/snowflake.webp // @grant none // @license MIT // ==/UserScript== (function () { 'use strict' let fontLink = document.createElement('link') fontLink.href = 'https://fonts.googleapis.com/css?family=Montserrat:400,700' fontLink.rel = 'stylesheet' document.head.appendChild(fontLink) let player = document.getElementById('movie_player') let isEnabled = localStorage.getItem('snowflakesEnabled') === null ? true : localStorage.getItem('snowflakesEnabled') === 'true' let fallSpeed = 5 // Initial falling speed const minSpeed = 1 // Minimum falling speed const maxSpeed = 10 // Maximum falling speed let respawnTime = 500 const minRespawnTime = 100 // Minimum respawn time const maxRespawnTime = 12000 // Maximum respawn time if (player) { let snowflakeInterval = setInterval(createSnowflake, respawnTime) function createSnowflake(x, y, isBig = false) { if (!isEnabled) return let snowflake = document.createElement('div') snowflake.innerHTML = '❄' snowflake.style.position = 'absolute' snowflake.style.pointerEvents = 'none' snowflake.style.zIndex = '100000' let size = isBig ? 100 : Math.random() * 24 + 10 snowflake.style.fontSize = `${size}px` let opacity = isBig ? 1 : Math.random() if (!isBig && opacity < 0.2) return snowflake.style.opacity = opacity.toString() let grayShade = Math.floor(Math.random() * 256) snowflake.style.color = `rgb(${grayShade}, ${grayShade}, ${grayShade})` let playerRect = player.getBoundingClientRect() snowflake.style.left = `${x ?? playerRect.left + Math.random() * playerRect.width}px` snowflake.style.top = `${y ?? 0}px` player.appendChild(snowflake) let windDirection = Math.random() > 0.5 ? 1 : -1 let windStrength = Math.random() * 2 let fall = setInterval(() => { if (!isEnabled) { clearInterval(fall) snowflake.remove() return } let currentTop = parseInt(snowflake.style.top, 10) if (currentTop < playerRect.height) { snowflake.style.top = `${currentTop + fallSpeed}px` snowflake.style.left = `${parseFloat(snowflake.style.left) + windDirection * windStrength}px` } else { clearInterval(fall) snowflake.remove() } }, 50) } setInterval(() => { if (!isEnabled) return createSnowflake() }, respawnTime) document.addEventListener('keydown', event => { if (event.code === 'Space') { event.preventDefault() let numberOfFlakes = Math.floor(Math.random() * 4) + 1 for (let i = 0; i < numberOfFlakes; i++) { let offsetX = Math.random() * 100 - 50 let offsetY = Math.random() * 100 - 50 let centerX = player.offsetLeft + player.offsetWidth / 2 + offsetX let centerY = player.offsetTop + player.offsetHeight / 2 + offsetY createSnowflake(centerX, centerY) } } }) let currentMessageContainer = null function showStatusMessage(message) { if (currentMessageContainer) { currentMessageContainer.remove() } let messageContainer = document.createElement('div') messageContainer.style.position = 'absolute' messageContainer.style.top = '0' messageContainer.style.left = '0' messageContainer.style.width = '100%' messageContainer.style.height = '100%' messageContainer.style.display = 'flex' messageContainer.style.justifyContent = 'center' messageContainer.style.alignItems = 'center' messageContainer.style.pointerEvents = 'none' let statusMessage = document.createElement('h3') statusMessage.innerHTML = message statusMessage.style.fontFamily = 'Montserrat, sans-serif' statusMessage.style.fontSize = '24px' statusMessage.style.color = 'white' statusMessage.style.zIndex = '100001' statusMessage.style.backgroundColor = 'rgba(0,0,0,0.7)' statusMessage.style.padding = '10px' statusMessage.style.borderRadius = '8px' statusMessage.style.boxShadow = '0 4px 6px rgba(0,0,0,0.2)' messageContainer.appendChild(statusMessage) player.appendChild(messageContainer) currentMessageContainer = messageContainer setTimeout(() => { messageContainer.remove() if (currentMessageContainer === messageContainer) { currentMessageContainer = null } }, 1500) } function adjustRespawnTime(newTime) { respawnTime = Math.max(minRespawnTime, Math.min(newTime, maxRespawnTime)) clearInterval(snowflakeInterval) snowflakeInterval = setInterval(createSnowflake, respawnTime) } document.addEventListener('keydown', event => { if (event.code === 'Backspace') { event.preventDefault() isEnabled = !isEnabled localStorage.setItem('snowflakesEnabled', isEnabled) showStatusMessage( isEnabled ? '<span>❄</span> Snowflakes enabled' : '<span>❄</span> Snowflakes disabled' ) } if (!isEnabled) return if (event.code === 'Space') { event.preventDefault() createSnowflake(player.offsetWidth / 2, 0) } else if (event.code === 'KeyQ') { fallSpeed = Math.min(fallSpeed + 1, maxSpeed) showStatusMessage(`Falling speed: ${fallSpeed}`) } else if (event.code === 'KeyA') { fallSpeed = Math.max(fallSpeed - 1, minSpeed) showStatusMessage(`Falling speed: ${fallSpeed}`) } else if (event.code === 'KeyF') { let centerX = player.offsetLeft + player.offsetWidth / 2 createSnowflake(centerX, 0, true) } else if (event.code === 'KeyW') { adjustRespawnTime(respawnTime + 100) showStatusMessage(`Respawn rate: ${respawnTime}ms`) } else if (event.code === 'KeyS') { adjustRespawnTime(respawnTime - 100) showStatusMessage(`Respawn rate: ${respawnTime}ms`) } }) if (!isEnabled) { showStatusMessage('<span>❄</span> Snowflakes disabled') } } if (!localStorage.getItem('scriptWelcomeShown6')) { isEnabled = false var modal = document.createElement('div') modal.style.position = 'fixed' modal.style.left = '0' modal.style.top = '0' modal.style.width = '100%' modal.style.height = '100vh' modal.style.backgroundColor = 'rgba(0,0,0,0.5)' modal.style.display = 'flex' modal.style.justifyContent = 'center' modal.style.alignItems = 'center' modal.style.zIndex = '10000' var modalContent = document.createElement('div') modalContent.style.backgroundColor = '#fff' modalContent.style.padding = '20px' modalContent.style.fontFamily = 'Montserrat, sans-serif' modalContent.style.fontSize = '24px' modalContent.style.borderRadius = '5px' modalContent.style.textAlign = 'center' modalContent.innerHTML = 'Welcome to <b>YouTube Snowflakes</b>! This is one time message. <br/>For control instructions, visit: <a href="https://github.com/KrzysztofJaronczyk/YouTube-SnowFlakes/blob/main/README.md" target="_blank">this link</a>.<br><br><button onclick="closeModal()">Close</button>' modal.appendChild(modalContent) document.body.appendChild(modal) window.closeModal = function () { modal.style.display = 'none' localStorage.setItem('scriptWelcomeShown6', 'true') isEnabled = true } } })()