From 8424ee109b7131e924753c55113699d69d718c42 Mon Sep 17 00:00:00 2001 From: festoney8 Date: Sun, 23 Jun 2024 21:07:46 +0800 Subject: [PATCH] feat: fullscreen scrollable --- CHANGELOG.md | 1 + src/rules/bangumi.ts | 108 ++++++++++++++++++++++++++++++++ src/rules/video.ts | 143 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 252 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 727cdda..af7e6f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 3.7.4 - 修复:动态页 隐藏动态右侧饰品 +- 新增:播放页/番剧页 全屏时页面可滚动 ## 3.7.3 diff --git a/src/rules/bangumi.ts b/src/rules/bangumi.ts index d869a38..a36af4d 100644 --- a/src/rules/bangumi.ts +++ b/src/rules/bangumi.ts @@ -112,6 +112,114 @@ if (isPageBangumi()) { enableFuncRunAt: 'document-end', disableFunc: async () => document.removeEventListener('wheel', disableAdjustVolume), }), + // 全屏时 页面可滚动 + new CheckboxItem({ + itemID: 'fullscreen-scrollable', + description: '全屏时 页面可滚动 滚轮调音量失效\n(实验功能,Firefox 不适用)', + itemCSS: ` + body:has(#bilibili-player-wrap[class*='video_playerFullScreen']) { + overflow: auto !important; + position: relative !important; + } + body:has(#bilibili-player-wrap[class*='video_playerFullScreen']) .home-container { + background-color: white; + } + body:has(#bilibili-player-wrap[class*='video_playerFullScreen']) #bilibili-player-wrap { + position: absolute !important; + width: 100vw !important; + height: 100vh !important; + } + body:has(#bilibili-player-wrap[class*='video_playerFullScreen']) .main-container { + position: static !important; + margin: 0 auto !important; + padding-top: calc(100vh + 15px) !important; + } + body:has(#bilibili-player-wrap[class*='video_playerFullScreen']) .bpx-player-video-area { + flex: unset !important; + } + body:has(#bilibili-player-wrap[class*='video_playerFullScreen'])::-webkit-scrollbar { + display: none !important; + } + /* firefox */ + @-moz-document url-prefix() { + :is(html, body):has(#bilibili-player-wrap[class*='video_playerFullScreen']) { + scrollbar-width: none !important; + } + } + `, + enableFunc: async () => { + // 在Chrome上可以神奇的禁用滚轮调节音量,Firefox不生效 + document.removeEventListener('wheel', disableAdjustVolume) + document.addEventListener('wheel', disableAdjustVolume) + + let cnt = 0 + const id = setInterval(() => { + const webBtn = document.body.querySelector( + '.bpx-player-ctrl-btn.bpx-player-ctrl-web', + ) as HTMLElement + const fullBtn = document.body.querySelector( + '.bpx-player-ctrl-btn.bpx-player-ctrl-full', + ) as HTMLElement + if (webBtn && fullBtn) { + clearInterval(id) + + const isFullScreen = (): 'ele' | 'f11' | 'not' => { + if (document.fullscreenElement) { + // 由元素申请的全屏 + return 'ele' + } else if (window.innerWidth === screen.width && window.innerHeight === screen.height) { + // 用户F11的全屏 + return 'f11' + } else { + // 非全屏 + return 'not' + } + } + + const isWebScreen = (): boolean => { + return webBtn.classList.contains('bpx-state-entered') + } + + // 全屏可滚动 = 网页全屏功能 + html/body元素申请全屏 + const newFullBtn = fullBtn.cloneNode(true) + newFullBtn.addEventListener('click', () => { + switch (isFullScreen()) { + case 'ele': + if (isWebScreen()) { + // 退出网页全屏,自动退出全屏 + webBtn.click() + } else { + document.exitFullscreen().then().catch() + } + break + case 'f11': + // f11全屏模式 + if (isWebScreen()) { + webBtn.click() + } else { + webBtn.click() + } + break + case 'not': + // 申请可滚动全屏 + document.body.requestFullscreen().then().catch() + if (!isWebScreen()) { + webBtn.click() + } + window.scrollTo(0, 0) + break + } + }) + fullBtn.parentElement?.replaceChild(newFullBtn, fullBtn) + } else { + cnt++ + cnt > 100 && clearInterval(id) + } + }, 100) + }, + enableFuncRunAt: 'document-end', + disableFunc: async () => document.removeEventListener('wheel', disableAdjustVolume), + }), // 普通播放 视频宽度调节 new NumberItem({ itemID: 'normalscreen-width', diff --git a/src/rules/video.ts b/src/rules/video.ts index 08f2cc8..500ed08 100644 --- a/src/rules/video.ts +++ b/src/rules/video.ts @@ -259,6 +259,7 @@ if (isPageVideo() || isPagePlaylist()) { `, enableFunc: async () => { // 在Chrome上可以神奇的禁用滚轮调节音量,Firefox不生效 + document.removeEventListener('wheel', disableAdjustVolume) document.addEventListener('wheel', disableAdjustVolume) // 监听网页全屏按钮出现 @@ -277,6 +278,148 @@ if (isPageVideo() || isPagePlaylist()) { enableFuncRunAt: 'document-end', disableFunc: async () => document.removeEventListener('wheel', disableAdjustVolume), }), + // 全屏时 页面可滚动 + new CheckboxItem({ + itemID: 'fullscreen-scrollable', + description: '全屏时 页面可滚动 滚轮调音量失效\n(实验功能,Firefox 不适用)', + itemCSS: ` + .webscreen-fix { + position: unset; + top: unset; + left: unset; + margin: unset; + padding: unset; + width: unset; + height: unset; + } + .webscreen-fix #biliMainHeader { + display: none; + } + .webscreen-fix #mirror-vdcon { + box-sizing: content-box; + position: relative; + } + .webscreen-fix #danmukuBox { + margin-top: 0 !important; + } + .webscreen-fix :is(.left-container, .playlist-container--left) { + position: static !important; + padding-top: 100vh; + min-width: 56vw !important; + } + .webscreen-fix :is(.left-container, .playlist-container--left) .video-info-container { + height: fit-content; + } + .webscreen-fix :is(.left-container, .playlist-container--left) #bilibili-player.mode-webscreen { + position: static; + border-radius: unset; + z-index: unset; + left: unset; + top: unset; + width: 100%; + height: 100%; + } + .webscreen-fix :is(.left-container, .playlist-container--left) #playerWrap { + position: absolute; + left: 0; + right: 0; + top: 0; + height: 100vh; + width: 100vw; + padding-right: 0; + } + .webscreen-fix :is(.right-container, .playlist-container--right) { + padding-top: 100vh; + } + /* 隐藏小窗 */ + .webscreen-fix .float-nav-exp .nav-menu .item.mini, + .webscreen-fix .fixed-sidenav-storage .mini-player-window { + display: none !important; + } + /* 滚动条 */ + .webscreen-fix::-webkit-scrollbar { + display: none !important; + } + /* firefox滚动条 */ + @-moz-document url-prefix() { + html:has(.webscreen-fix), body.webscreen-fix { + scrollbar-width: none !important; + } + } + `, + enableFunc: async () => { + // 在Chrome上可以神奇的禁用滚轮调节音量,Firefox不生效 + document.removeEventListener('wheel', disableAdjustVolume) + document.addEventListener('wheel', disableAdjustVolume) + + let cnt = 0 + const id = setInterval(() => { + const webBtn = document.body.querySelector( + '.bpx-player-ctrl-btn.bpx-player-ctrl-web', + ) as HTMLElement + const fullBtn = document.body.querySelector( + '.bpx-player-ctrl-btn.bpx-player-ctrl-full', + ) as HTMLElement + if (webBtn && fullBtn) { + clearInterval(id) + + const isFullScreen = (): 'ele' | 'f11' | 'not' => { + if (document.fullscreenElement) { + // 由元素申请的全屏 + return 'ele' + } else if (window.innerWidth === screen.width && window.innerHeight === screen.height) { + // 用户F11的全屏 + return 'f11' + } else { + // 非全屏 + return 'not' + } + } + + const isWebScreen = (): boolean => { + return webBtn.classList.contains('bpx-state-entered') + } + + // 全屏可滚动 = 网页全屏功能 + html/body元素申请全屏 + const newFullBtn = fullBtn.cloneNode(true) + newFullBtn.addEventListener('click', () => { + switch (isFullScreen()) { + case 'ele': + if (isWebScreen()) { + // 退出网页全屏,自动退出全屏 + webBtn.click() + } else { + document.exitFullscreen().then().catch() + } + break + case 'f11': + // f11全屏模式 + if (isWebScreen()) { + webBtn.click() + } else { + webBtn.click() + } + break + case 'not': + // 申请可滚动全屏 + document.body.requestFullscreen().then().catch() + if (!isWebScreen()) { + webBtn.click() + } + window.scrollTo(0, 0) + break + } + }) + fullBtn.parentElement?.replaceChild(newFullBtn, fullBtn) + } else { + cnt++ + cnt > 100 && clearInterval(id) + } + }, 100) + }, + enableFuncRunAt: 'document-end', + disableFunc: async () => document.removeEventListener('wheel', disableAdjustVolume), + }), // 播放器和视频标题 交换位置 new CheckboxItem({ itemID: 'video-page-exchange-player-position',