// ==UserScript==
// @name 视频字幕遮罩条
// @namespace http://tampermonkey.net/
// @version 1.5
// @description 创建一个磨砂半透明遮罩条来遮挡视频字幕
// @author Aaron Hu
// @match *://*/*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_addStyle
// @grant GM_registerMenuCommand
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// Create container for the mask
const container = document.createElement('div');
Object.assign(container.style, {
position: 'fixed',
top: '0',
left: '0',
width: '100%',
height: '100%',
zIndex: '2147483647',
pointerEvents: 'none',
display: 'none',
});
document.body.appendChild(container);
function createMask() {
const newMask = document.createElement('div');
Object.assign(newMask.style, {
position: 'fixed',
bottom: '30px',
left: '50%',
transform: 'translateX(-50%)',
width: '80%',
height: '80px',
backgroundColor: 'rgba(255, 255, 255, 0.2)',
backdropFilter: 'blur(8px)',
zIndex: '2147483647',
cursor: 'move',
border: '1px solid rgba(255, 255, 255, 0.1)',
borderRadius: '4px',
pointerEvents: 'auto',
userSelect: 'none',
});
// Add resizers
const leftResizer = document.createElement('div');
const rightResizer = document.createElement('div');
const topResizer = document.createElement('div');
// Style for horizontal resizers
const horizontalResizerStyle = {
position: 'absolute',
top: '0',
width: '10px',
height: '100%',
cursor: 'ew-resize',
backgroundColor: 'rgba(255, 255, 255, 0.3)',
borderRadius: '4px',
};
Object.assign(leftResizer.style, {
...horizontalResizerStyle,
left: '-5px',
});
Object.assign(rightResizer.style, {
...horizontalResizerStyle,
right: '-5px',
});
// Style for vertical resizer
Object.assign(topResizer.style, {
position: 'absolute',
top: '-5px',
left: '50%',
transform: 'translateX(-50%)',
width: '40px',
height: '10px',
backgroundColor: 'rgba(255, 255, 255, 0.3)',
cursor: 'ns-resize',
borderRadius: '4px',
});
// Add resize functionality
let isResizing = false;
let currentResizer = null;
let initialWidth, initialHeight, initialX, initialY, initialBottom, initialTop;
function startResize(e, resizer) {
isResizing = true;
currentResizer = resizer;
const rect = newMask.getBoundingClientRect();
initialWidth = rect.width;
initialHeight = rect.height;
initialX = e.clientX;
initialY = e.clientY;
initialBottom = rect.bottom;
initialTop = rect.top;
e.stopPropagation();
}
function resize(e) {
if (!isResizing) return;
e.preventDefault();
if (currentResizer === leftResizer || currentResizer === rightResizer) {
// 计算鼠标移动距离
const deltaX = e.clientX - initialX;
// 从中心点同时调整两侧
const widthChange = deltaX * 2;
const newWidth = initialWidth + widthChange;
if (newWidth > 100) {
newMask.style.width = `${newWidth}px`;
// 保持中心点不变
const centerX = window.innerWidth / 2;
newMask.style.left = '50%';
newMask.style.transform = 'translateX(-50%)';
}
} else if (currentResizer === topResizer) {
const mouseY = e.clientY;
const deltaY = mouseY - initialY;
// 跟随鼠标移动方向自然变化
if (deltaY > 0) { // 向下移动,增加高度
const newHeight = initialHeight + deltaY;
if (newHeight > 20) {
newMask.style.height = `${newHeight}px`;
newMask.style.bottom = `${initialBottom - window.innerHeight}px`;
}
} else { // 向上移动,减少高度
const newHeight = initialHeight - Math.abs(deltaY);
if (newHeight > 20) {
newMask.style.height = `${newHeight}px`;
newMask.style.bottom = `${initialBottom - window.innerHeight}px`;
}
}
}
}
function stopResize() {
isResizing = false;
currentResizer = null;
}
leftResizer.addEventListener('mousedown', (e) => startResize(e, leftResizer));
rightResizer.addEventListener('mousedown', (e) => startResize(e, rightResizer));
topResizer.addEventListener('mousedown', (e) => startResize(e, topResizer));
document.addEventListener('mousemove', resize);
document.addEventListener('mouseup', stopResize);
// Add close button
const closeButton = document.createElement('div');
Object.assign(closeButton.style, {
position: 'absolute',
top: '5px',
right: '5px',
width: '20px',
height: '20px',
backgroundColor: 'red',
color: 'white',
textAlign: 'center',
lineHeight: '20px',
borderRadius: '50%',
cursor: 'pointer',
zIndex: '2147483648',
});
closeButton.textContent = '×';
closeButton.addEventListener('click', () => {
container.removeChild(newMask);
});
// Append all elements
newMask.appendChild(closeButton);
newMask.appendChild(leftResizer);
newMask.appendChild(rightResizer);
newMask.appendChild(topResizer);
// Add drag functionality
let isDragging = false;
let initialDragX, initialDragY;
newMask.addEventListener('mousedown', (e) => {
if (e.target !== newMask) return;
const rect = newMask.getBoundingClientRect();
initialDragX = e.clientX - rect.left;
initialDragY = e.clientY - rect.top;
isDragging = true;
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
e.preventDefault();
const x = e.clientX - initialDragX;
const y = e.clientY - initialDragY;
newMask.style.left = `${x}px`;
newMask.style.top = `${y}px`;
newMask.style.transform = 'none';
});
document.addEventListener('mouseup', () => {
isDragging = false;
});
return newMask;
}
// 切换显示状态的函数
function toggleMask() {
const isVisible = container.style.display === 'none';
container.style.display = isVisible ? 'block' : 'none';
// 如果切换为显示状态且容器内没有遮罩条,则创建一个
if (isVisible && container.children.length === 0) {
const newMask = createMask();
container.appendChild(newMask);
}
}
function addNewMask() {
container.style.display = 'block'; // 确保容器可见
const newMask = createMask();
container.appendChild(newMask);
}
function clearAllMasks() {
while (container.firstChild) {
container.removeChild(container.firstChild);
}
container.style.display = 'none'; // 清空后隐藏容器
}
// Register Tampermonkey menu commands
GM_registerMenuCommand('切换显示', toggleMask);
GM_registerMenuCommand('新增遮罩条', addNewMask);
GM_registerMenuCommand('一键清空', clearAllMasks);
// 处理全屏
function handleFullscreen() {
const fullscreenElement = document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement;
if (fullscreenElement) {
fullscreenElement.appendChild(container);
container.style.position = 'absolute';
} else {
document.body.appendChild(container);
container.style.position = 'fixed';
}
}
document.addEventListener('fullscreenchange', handleFullscreen);
document.addEventListener('webkitfullscreenchange', handleFullscreen);
document.addEventListener('mozfullscreenchange', handleFullscreen);
document.addEventListener('MSFullscreenChange', handleFullscreen);
})();