您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Убирает кнопку "окно в окне" (PiP) в браузере Opera GX у фоновых видео профиля на AnimeStars и его зеркалах. В других браузерах просто защищает видео, оставляя его как фон.
当前为
// ==UserScript== // @name AnimeStars фикс кнопок в браузере Opera GX // @namespace https://animestars.org/ // @version 1.2 // @author Sandr // @description Убирает кнопку "окно в окне" (PiP) в браузере Opera GX у фоновых видео профиля на AnimeStars и его зеркалах. В других браузерах просто защищает видео, оставляя его как фон. // @match *://animestars.org/* // @match *://asstars.tv/* // @match *://astars.club/* // @match *://as1.astars.club/* // @match *://as1.asstars.tv/* // @match *://as2.asstars.tv/* // @match *://asstars.club/* // @match *://asstars.online/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // ==== Универсальная защита фоновых видео профиля от Opera GX ==== function protectAllProfileBgVideos() { const SELECTOR = "#profilebg"; const CANDIDATES_SELECTOR = "#detach-button-host, #video-detach-button, #skip-button, #send-by-qrcode-button, #lucid-mode-button, .button-container, .custom-button, .rgx-button-wrapper"; function applyToVideo(video) { if (!video || video.dataset._canvas_applied) return; video.dataset._canvas_applied = "1"; const poster = video.closest(".usn__poster") || video.parentElement; if (!poster) return; const src = video.querySelector("source")?.src || video.src; if (!src) return; // Скрытое видео (вне DOM) const hiddenVideo = document.createElement("video"); hiddenVideo.src = src; hiddenVideo.muted = true; hiddenVideo.loop = true; hiddenVideo.autoplay = true; hiddenVideo.playsInline = true; hiddenVideo.crossOrigin = "anonymous"; hiddenVideo.play().catch(() => {}); // Canvas const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); Object.assign(canvas.style, { position: "absolute", top: 0, left: 0, width: "100%", height: "100%", zIndex: 0, pointerEvents: "none" }); if (getComputedStyle(poster).position === "static") { poster.style.position = "relative"; } poster.insertBefore(canvas, poster.firstChild); // Убираем оригинальное видео video.remove(); // Resize canvas // Resize canvas под родительский блок function resizeCanvas() { const rect = poster.getBoundingClientRect(); const dpr = window.devicePixelRatio || 1; canvas.width = rect.width * dpr; canvas.height = rect.height * dpr; canvas.style.width = rect.width + "px"; canvas.style.height = rect.height + "px"; ctx.setTransform(dpr, 0, 0, dpr, 0, 0); } // Следим за изменением размеров контейнера const resizeObserver = new ResizeObserver(resizeCanvas); resizeObserver.observe(poster); // Рендер с object-fit: cover function render() { if (hiddenVideo.readyState >= 2) { const sw = hiddenVideo.videoWidth; const sh = hiddenVideo.videoHeight; const dw = canvas.width; const dh = canvas.height; // Масштабируем так, чтобы фон закрывал ширину и высоту const scale = Math.max(dw / sw, dh / sh); const scaledWidth = sw * scale; const scaledHeight = sh * scale; // По горизонтали оставим центрирование const dx = (dw - scaledWidth) / 2; // По вертикали — всегда от верхней границы const dy = 0; ctx.clearRect(0, 0, dw, dh); ctx.drawImage(hiddenVideo, dx, dy, scaledWidth, scaledHeight); } requestAnimationFrame(render); } render(); // MutationObserver для удаления кнопок Opera GX const overlayObserver = new MutationObserver(mutations => { mutations.forEach(m => { m.addedNodes.forEach(node => { if (!(node instanceof Element)) return; if (node.matches(CANDIDATES_SELECTOR)) { node.remove(); } const found = node.querySelector && node.querySelector(CANDIDATES_SELECTOR); if (found) found.remove(); }); }); }); overlayObserver.observe(document.body, { childList: true, subtree: true }); } // Применяем сразу document.querySelectorAll(SELECTOR).forEach(applyToVideo); // Следим за новыми const observer = new MutationObserver(mutations => { mutations.forEach(m => { m.addedNodes.forEach(node => { if (!(node instanceof Element)) return; if (node.matches && node.matches(SELECTOR)) { applyToVideo(node); } const found = node.querySelector && node.querySelector(SELECTOR); if (found) applyToVideo(found); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); } // Запускаем protectAllProfileBgVideos(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址