Greasy Fork

Greasy Fork is available in English.

B站自动宽屏居中

自动宽屏播放并将播放器垂直居中视口,退出宽屏模式自动滚动页面到顶部。

当前为 2025-01-12 提交的版本,查看 最新版本

// ==UserScript==
// @name         B站自动宽屏居中
// @namespace    @ChatGPT
// @supportURL   http://greasyfork.icu/zh-CN/scripts/492413-b%E7%AB%99%E8%87%AA%E5%8A%A8%E5%AE%BD%E5%B1%8F%E5%B1%85%E4%B8%AD/feedback
// @homepageURL  http://greasyfork.icu/zh-CN/scripts/492413-b%E7%AB%99%E8%87%AA%E5%8A%A8%E5%AE%BD%E5%B1%8F%E5%B1%85%E4%B8%AD
// @version      1.5
// @description  自动宽屏播放并将播放器垂直居中视口,退出宽屏模式自动滚动页面到顶部。
// @author       ChatGPT;ChatGLM;Fittencode;DeepSeek
// @license      MIT
// @match        https://*.bilibili.com/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    const elements = {
        wideBtn: null,
        webFullBtn: null,
        fullBtn: null,
        player: null
    };

    function cacheElements() {
        elements.wideBtn = document.querySelector('.bpx-player-ctrl-wide');
        elements.webFullBtn = document.querySelector('.bpx-player-ctrl-web');
        elements.fullBtn = document.querySelector('.bpx-player-ctrl-full');
        elements.player = document.querySelector('#bilibili-player');

        if (!elements.wideBtn || !elements.webFullBtn || !elements.fullBtn || !elements.player) {
            console.warn('Some elements not found, retrying...');
            setTimeout(cacheElements, 500);
        }
    }

    function waitForElement(selector, callback) {
        const element = document.querySelector(selector);
        if (element) {
            callback(element);
            return;
        }
        const observer = new MutationObserver(() => {
            const el = document.querySelector(selector);
            if (el) {
                callback(el);
                observer.disconnect();
            }
        });
        observer.observe(document, { childList: true, subtree: true });
    }

    function scrollToPosition(topPosition) {
        window.scrollTo({ top: topPosition, behavior: 'smooth' });
    }

    function scrollToPlayer() {
        if (elements.player) {
            const playerTop = elements.player.getBoundingClientRect().top + window.scrollY;
            const newPosition = playerTop - 75;
            scrollToPosition(newPosition);
        }
    }

    function scrollToTop() {
        scrollToPosition(0);
    }

    function setWideMode(enable) {
        if (elements.wideBtn && enable && !elements.wideBtn.classList.contains('bpx-state-entered')) {
            elements.wideBtn.click();
            requestAnimationFrame(scrollToPlayer);
        }
    }

    function handleKeyPress(event) {
        if (event.key === 'Escape') {
            handlePlayerStateChange();
        }
    }

    function registerMenuCommands() {
        const isEnabled = GM_getValue('enableWideScreen', true);
        const statusText = isEnabled ? '开启' : '关闭';
        GM_registerMenuCommand(`自动宽屏(当前:${statusText})`, toggleWideScreen);
    }

    function toggleWideScreen() {
        const enableWideScreen = GM_getValue('enableWideScreen', true);
        const newState = !enableWideScreen;
        GM_setValue('enableWideScreen', newState);
        setWideMode(newState);
        alert(`宽屏模式已${newState ? '开启' : '关闭'}`);
    }

    function handlePlayerStateChange() {
        const isWideScreen = elements.wideBtn && elements.wideBtn.classList.contains('bpx-state-entered');
        const isFullScreen = document.fullscreenElement || document.webkitFullscreenElement;
        if (isWideScreen && !isFullScreen) {
            scrollToPlayer();
        } else {
            scrollToTop();
        }
    }

    function setupEventListeners() {
        const buttons = ['.bpx-player-ctrl-wide', '.bpx-player-ctrl-web', '.bpx-player-ctrl-full'];
        buttons.forEach(selector => {
            const btn = document.querySelector(selector);
            if (btn) {
                btn.addEventListener('click', handlePlayerStateChange);
            }
        });

        const videoArea = document.querySelector('.bpx-player-video-area');
        if (videoArea) {
            videoArea.addEventListener('dblclick', handlePlayerStateChange);
        }

        document.addEventListener('fullscreenchange', handlePlayerStateChange);
        document.addEventListener('webkitfullscreenchange', handlePlayerStateChange);
    }

    function init() {
        registerMenuCommands();
        waitForElement('.bpx-player-ctrl-wide', () => {
            cacheElements();
            setupEventListeners();
            setWideMode(GM_getValue('enableWideScreen', true));
        });
        document.addEventListener('keydown', handleKeyPress);

        const observer = new MutationObserver((mutationsList) => {
            mutationsList.forEach((mutation) => {
                if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
                    handlePlayerStateChange();
                }
            });
        });

        waitForElement('#bilibili-player', (element) => {
            elements.player = element;
            observer.observe(element, { attributes: true });
        });
    }

    init();
})();