Bilibili-Evolved/registry/lib/components/style/player-on-top-new/index.ts
ZiuChen 6dd3e79543 fix: 修正marginTop计算规则 增加resize的监听
- 之前是通过获取`#danmukuBox`原始`marginTop`来设置UP主信息的`marginTop`的
- 现在可以通过实时计算 获得目标`marginTop`值
- 用于计算的代码来自B站混淆后的内联JS 做了一些适应性修改
2023-05-10 16:07:28 +08:00

122 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { defineComponentMetadata } from '@/components/define'
import { playerModeChange } from '@/components/video/player-adaptor'
import { getComponentSettings, addComponentListener } from '@/core/settings'
import { playerReady, getNumberValidator } from '@/core/utils'
import { videoUrls } from '@/core/utils/urls'
/**
* 将 element 移动到 after 后面
* @param element 要移动的元素
* @param after 目标元素
*/
function moveElementAfter(element: Element, after: Element) {
const parent = element.parentElement
if (!parent) {
return
}
parent.removeChild(element)
parent.insertBefore(element, after.nextSibling)
}
/**
* 处理屏幕尺寸变化
* 实时获取到`#danmukuBox`的`marginTop`值
* 修改自B站内联的JS代码请确保此函数在播放器宽屏模式下被调用
*/
function calcMarginTop() {
const e = window.innerHeight
const t = Math.max((document.body && document.body.clientWidth) || window.innerWidth, 1100)
const n = innerWidth > 1680 ? 411 : 350
const o = parseInt(String((16 * (e - (window.innerWidth > 1690 ? 318 : 308))) / 9))
const r = t - 112 - n
const d = r < o ? r : o
const a = Math.round((d + n) * (9 / 16)) + (innerWidth > 1680 ? 56 : 46)
return `${a}px`
}
/**
* 统一添加副作用处理
* 处理播放器宽屏切换后的UP信息与弹幕列表样式
*/
function sideEffect() {
const author = document.querySelector('.up-panel-container') as HTMLDivElement
const danmuku = document.querySelector('#danmukuBox') as HTMLDivElement
// 缓存当前播放器模式 用于判断是否为宽屏模式
let currentMode = 'normal'
// 监听播放器宽屏模式 调整UP信息与弹幕列表样式
window.addEventListener('playerModeChange', (ev: ReturnType<typeof playerModeChange>) => {
const { mode } = ev.detail
currentMode = mode
if (mode === 'wide') {
danmuku.style.marginTop = '0px'
author.style.marginTop = calcMarginTop()
} else {
// 恢复原始样式
author.style.marginTop = '0px'
}
})
// 监听屏幕尺寸变化
window.addEventListener('resize', () => {
// 播放器宽屏模式
if (currentMode === 'wide') {
author.style.marginTop = calcMarginTop()
}
})
}
/**
* 播放器置顶
* 从设置中获取顶部留白的高度
*/
async function playerOnTop({ settings: { options: opt }, metadata }) {
await playerReady()
const title = document.querySelector('#viewbox_report')
const toolbar = document.querySelector('#arc_toolbar_report')
moveElementAfter(title, toolbar)
const player = document.querySelector('#playerWrap') as HTMLDivElement
player.style.marginTop = `${opt.marginTop}px`
// 监听设置变化 实时更新到页面
addComponentListener(`${metadata.name}.marginTop`, (value: number) => {
player.style.marginTop = `${value}px`
})
sideEffect()
}
export const component = defineComponentMetadata({
name: 'playerOnTopNew',
author: [
{
name: 'RieN7',
link: 'https://github.com/rien7',
},
{
name: 'ZiuChen',
link: 'https://github.com/ZiuChen',
},
],
tags: [componentsTags.style, componentsTags.video],
options: {
marginTop: {
displayName: '顶部留白 (px)',
defaultValue: 20,
validator: getNumberValidator(0, Infinity),
},
},
urlInclude: videoUrls,
displayName: '播放器置顶(新)',
description:
'原来的播放器置顶插件,现在已经不可用了,这是一个新的版本,可以在视频页面中将播放器放在页面最上方.',
entry: playerOnTop,
reload: () =>
playerOnTop({ settings: getComponentSettings('playerOnTopNew'), metadata: component }),
})