Display live chat while watching YouTube videos in fullscreen mode
当前为
// ==UserScript==
// @name YouTube Live Chat in Fullscreen
// @namespace https://greasyfork.org/en/users/781396
// @version 1.5
// @description Display live chat while watching YouTube videos in fullscreen mode
// @author YAD
// @license MIT
// @icon https://www.iconpacks.net/icons/1/free-icon-video-837.png
// @match *://*.youtube.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Load settings from localStorage or set defaults
let chatboxWidth = localStorage.getItem('chatboxWidth') || 350;
let chatboxHeight = localStorage.getItem('chatboxHeight') || 600;
let chatboxOpacity = localStorage.getItem('chatboxOpacity') || 0.5;
let chatboxPosX = localStorage.getItem('chatboxPosX') || 0;
let chatboxPosY = localStorage.getItem('chatboxPosY') || -150;
let backgroundColor = localStorage.getItem('backgroundColor') || '#000000'; // Default to black
let backgroundOpacity = localStorage.getItem('backgroundOpacity') || 0.5; // Default opacity
// CSS styles for transparency
function getStyles() {
return `
yt-live-chat-header-renderer,
yt-live-chat-message-input-renderer,
#container.yt-live-chat-restricted-participation-renderer,
yt-live-chat-renderer {
background: rgba(${hexToRgb(backgroundColor)}, ${backgroundOpacity}) !important; // Adjust background color
overflow: hidden;
}
.draggable {
cursor: move;
}
`;
}
// Convert hex color to RGB
function hexToRgb(hex) {
const bigint = parseInt(hex.slice(1), 16);
const r = (bigint >> 16) & 255;
const g = (bigint >> 8) & 255;
const b = bigint & 255;
return `${r}, ${g}, ${b}`;
}
// Function to apply styles to the iframe document
function applyStylesToIframe(iframeDoc) {
const styleTag = iframeDoc.createElement('style');
styleTag.textContent = getStyles();
iframeDoc.head.appendChild(styleTag);
}
// Function to apply styles to the chatbox on load
function applyStylesOnLoad() {
const iframe = document.querySelector('iframe#chatframe');
if (iframe) {
iframe.onload = () => {
applyStylesToIframe(iframe.contentDocument || iframe.contentWindow.document);
};
}
}
// Create settings modal
const settingsModal = document.createElement('div');
settingsModal.style.position = 'fixed';
settingsModal.style.top = '50%';
settingsModal.style.left = '50%';
settingsModal.style.transform = 'translate(-50%, -50%)';
settingsModal.style.backgroundColor = 'rgba(0, 0, 0, 0.8)';
settingsModal.style.color = 'white';
settingsModal.style.padding = '20px';
settingsModal.style.borderRadius = '10px';
settingsModal.style.zIndex = '10001';
settingsModal.style.display = 'none';
// Create the title
const title = document.createElement('h3');
title.innerText = 'Chatbox Settings';
settingsModal.appendChild(title);
// Create width input
const widthLabel = document.createElement('label');
widthLabel.innerText = 'Width: ';
const widthInput = document.createElement('input');
widthInput.type = 'number';
widthInput.id = 'chatWidth';
widthInput.value = chatboxWidth;
widthInput.style.width = '80px';
widthLabel.appendChild(widthInput);
widthLabel.appendChild(document.createTextNode(' px'));
settingsModal.appendChild(widthLabel);
settingsModal.appendChild(document.createElement('br'));
// Create height input
const heightLabel = document.createElement('label');
heightLabel.innerText = 'Height: ';
const heightInput = document.createElement('input');
heightInput.type = 'number';
heightInput.id = 'chatHeight';
heightInput.value = chatboxHeight;
heightInput.style.width = '80px';
heightLabel.appendChild(heightInput);
heightLabel.appendChild(document.createTextNode(' px'));
settingsModal.appendChild(heightLabel);
settingsModal.appendChild(document.createElement('br'));
// Create opacity slider
const opacityLabel = document.createElement('label');
opacityLabel.innerText = 'Chat Opacity: ';
const opacitySlider = document.createElement('input');
opacitySlider.type = 'range';
opacitySlider.id = 'chatOpacity';
opacitySlider.min = '0';
opacitySlider.max = '1';
opacitySlider.step = '0.1';
opacitySlider.value = chatboxOpacity;
opacityLabel.appendChild(opacitySlider);
settingsModal.appendChild(opacityLabel);
settingsModal.appendChild(document.createElement('br'));
// Create background color input
const bgColorLabel = document.createElement('label');
bgColorLabel.innerText = 'Background Color: ';
const bgColorInput = document.createElement('input');
bgColorInput.type = 'color';
bgColorInput.value = backgroundColor;
bgColorLabel.appendChild(bgColorInput);
settingsModal.appendChild(bgColorLabel);
settingsModal.appendChild(document.createElement('br'));
// Create background opacity slider
const bgOpacityLabel = document.createElement('label');
bgOpacityLabel.innerText = 'Background Transparency: ';
const bgOpacitySlider = document.createElement('input');
bgOpacitySlider.type = 'range';
bgOpacitySlider.id = 'bgOpacity';
bgOpacitySlider.min = '0';
bgOpacitySlider.max = '1';
bgOpacitySlider.step = '0.1';
bgOpacitySlider.value = backgroundOpacity;
bgOpacityLabel.appendChild(bgOpacitySlider);
settingsModal.appendChild(bgOpacityLabel);
settingsModal.appendChild(document.createElement('br'));
// Create X position slider
const posXLabel = document.createElement('label');
posXLabel.innerText = 'X Position: ';
const posXSlider = document.createElement('input');
posXSlider.type = 'range';
posXSlider.id = 'chatPosX';
posXSlider.min = `-${window.innerWidth}`; // Allow negative positioning
posXSlider.max = `${window.innerWidth}`; // Allow positive positioning
posXSlider.value = chatboxPosX;
posXLabel.appendChild(posXSlider);
settingsModal.appendChild(posXLabel);
settingsModal.appendChild(document.createElement('br'));
// Create Y position slider
const posYLabel = document.createElement('label');
posYLabel.innerText = 'Y Position: ';
const posYSlider = document.createElement('input');
posYSlider.type = 'range';
posYSlider.id = 'chatPosY';
posYSlider.min = `-${window.innerHeight}`; // Allow negative positioning
posYSlider.max = `${window.innerHeight}`; // Allow positive positioning
posYSlider.value = chatboxPosY;
posYLabel.appendChild(posYSlider);
settingsModal.appendChild(posYLabel);
settingsModal.appendChild(document.createElement('br'));
// Create apply button
const applyButton = document.createElement('button');
applyButton.innerText = 'Apply';
applyButton.id = 'applySettings';
settingsModal.appendChild(applyButton);
// Create reset button
const resetButton = document.createElement('button');
resetButton.innerText = 'Reset';
resetButton.id = 'resetSettings';
settingsModal.appendChild(resetButton);
document.body.appendChild(settingsModal);
// Handle settings button click (open modal)
const settingsButton = document.createElement('button');
settingsButton.innerText = '⚙';
settingsButton.style.position = 'fixed';
settingsButton.style.top = '2%'; // Default position
settingsButton.style.right = '2%'; // Default position
settingsButton.style.zIndex = '10000';
settingsButton.style.display = 'none'; // Hidden by default
settingsButton.addEventListener('click', () => {
settingsModal.style.display = 'block';
});
document.body.appendChild(settingsButton);
// Update iframe settings in real-time
function updateChatbox() {
const iframe = document.querySelector('iframe#chatframe');
if (iframe) {
iframe.style.width = `${chatboxWidth}px`;
iframe.style.height = `${chatboxHeight}px`;
iframe.style.position = 'fixed'; // Ensure position is fixed
iframe.style.left = `${(window.innerWidth / 2) + parseInt(chatboxPosX)}px`; // Center X position
iframe.style.top = `${(window.innerHeight / 2) + parseInt(chatboxPosY)}px`; // Center Y position
iframe.style.opacity = chatboxOpacity; // Set opacity
applyStylesToIframe(iframe.contentDocument || iframe.contentWindow.document); // Apply styles to iframe document
}
}
// Handle apply button click
applyButton.addEventListener('click', () => {
// Update settings
chatboxWidth = widthInput.value;
chatboxHeight = heightInput.value;
chatboxOpacity = opacitySlider.value;
backgroundColor = bgColorInput.value;
backgroundOpacity = bgOpacitySlider.value;
chatboxPosX = posXSlider.value;
chatboxPosY = posYSlider.value;
// Save settings to localStorage
localStorage.setItem('chatboxWidth', chatboxWidth);
localStorage.setItem('chatboxHeight', chatboxHeight);
localStorage.setItem('chatboxOpacity', chatboxOpacity);
localStorage.setItem('backgroundColor', backgroundColor);
localStorage.setItem('backgroundOpacity', backgroundOpacity);
localStorage.setItem('chatboxPosX', chatboxPosX);
localStorage.setItem('chatboxPosY', chatboxPosY);
settingsModal.style.display = 'none';
updateChatbox(); // Apply new settings
});
// Handle reset settings
resetButton.addEventListener('click', () => {
localStorage.removeItem('chatboxWidth');
localStorage.removeItem('chatboxHeight');
localStorage.removeItem('chatboxOpacity');
localStorage.removeItem('backgroundColor');
localStorage.removeItem('backgroundOpacity');
localStorage.removeItem('chatboxPosX');
localStorage.removeItem('chatboxPosY');
// Reset to defaults
chatboxWidth = 350;
chatboxHeight = 600;
chatboxOpacity = 0.5;
backgroundColor = '#000000';
backgroundOpacity = 0.5;
chatboxPosX = 0;
chatboxPosY = -150;
// Update UI elements
widthInput.value = chatboxWidth;
heightInput.value = chatboxHeight;
opacitySlider.value = chatboxOpacity;
bgColorInput.value = backgroundColor;
bgOpacitySlider.value = backgroundOpacity;
posXSlider.value = chatboxPosX;
posYSlider.value = chatboxPosY;
updateChatbox(); // Apply reset settings
});
// Handle slider inputs for real-time updates
opacitySlider.addEventListener('input', () => {
chatboxOpacity = opacitySlider.value;
updateChatbox();
});
bgOpacitySlider.addEventListener('input', () => {
backgroundOpacity = bgOpacitySlider.value;
updateChatbox();
});
bgColorInput.addEventListener('input', () => {
backgroundColor = bgColorInput.value;
updateChatbox();
});
widthInput.addEventListener('input', () => {
chatboxWidth = widthInput.value;
updateChatbox();
});
heightInput.addEventListener('input', () => {
chatboxHeight = heightInput.value;
updateChatbox();
});
posXSlider.addEventListener('input', () => {
chatboxPosX = posXSlider.value;
updateChatbox();
});
posYSlider.addEventListener('input', () => {
chatboxPosY = posYSlider.value;
updateChatbox();
});
// Handle fullscreen changes
function handleFullscreenChange() {
const iframe = document.querySelector('iframe#chatframe'); // Correct chat iframe selector
if (!iframe) return;
const isFullscreen = document.fullscreenElement;
if (isFullscreen) {
updateChatbox(); // Update chatbox on fullscreen
settingsButton.style.display = 'block'; // Show settings button only in fullscreen
} else {
settingsButton.style.display = 'none'; // Hide settings button when not in fullscreen
settingsModal.style.display = 'none'; // Close settings modal when exiting fullscreen
// Reset to default values (do not remove saved settings)
iframe.style.width = ''; // Reset width
iframe.style.height = ''; // Reset height
iframe.style.position = ''; // Reset position
iframe.style.left = ''; // Reset left position
iframe.style.top = ''; // Reset top position
iframe.style.opacity = ''; // Reset opacity
}
}
// Listen for fullscreen changes
document.addEventListener('fullscreenchange', handleFullscreenChange);
// Initial chatbox update
updateChatbox();
applyStylesOnLoad();
})();