尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Bilibili-Evolved v1 风格设置面板样式组件解析:从样式覆盖到实现原理

Bilibili-Evolved v1 风格设置面板样式组件解析:从样式覆盖到实现原理 Bilibili-Evolved v1 风格设置面板样式组件解析从样式覆盖到实现原理【免费下载链接】Bilibili-Evolved强大的哔哩哔哩增强脚本项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-EvolvedBilibili-Evolved哔哩哔哩增强脚本在向 v2 架构演进的过程中将设置面板重新设计为圆角卡片与弹出式布局。v1-panel组件的作用是通过一组全局 SCSS 覆盖规则让设置面板恢复 v1 时代「全屏停靠、无圆角、侧边栏悬浮」的经典外观。本文将围绕该组件的元数据定义与样式实现结合设置面板、停靠dock等源码逐段拆解其覆盖逻辑、方向适配机制与动画细节帮助读者理解样式类组件在脚本内的注册方式与写法。组件概览一个纯样式组件v1-panel在组件目录registry/lib/components/style/v1-panel/下仅由三个文件组成index.md组件说明文档内容为「使用 v1 风格的设置面板样式」index.ts组件元数据定义负责向脚本注册该组件v1-panel.scss核心样式实现约 80 行全部为对设置面板样式的覆盖规则。从目录归属看它位于registry/lib/components/style/样式类组件分类下与dark-mode、scrollbar、player-shadow等样式组件并列属于「通过注入 CSS 改变界面外观」的一类功能不包含任何业务逻辑或entry运行时代码。组件元数据instantStyles 注入机制组件的注册入口是 index.ts全文如下import { defineComponentMetadata } from /components/define export const component defineComponentMetadata({ name: v1PanelStyle, displayName: v1 风格设置面板, tags: [componentsTags.style], entry: none, instantStyles: [ { name: v1PanelStyle, style: () import(./v1-panel.scss), }, ], })关键点逐项说明name: v1PanelStyle组件在脚本内部的唯一标识也是样式注册名与设置项键名的基础displayName: v1 风格设置面板设置面板功能列表中向用户展示的名称同时也是搜索匹配的文本来源之一见下文 SettingsPanel 的搜索逻辑tags: [componentsTags.style]将组件归入「样式」标签分组便于在设置面板中按标签筛选entry: none组件没有运行时代码entry为空说明它纯粹靠样式生效instantStyles声明「即时样式」列表。与按需加载的组件样式不同instantStyles会在组件启用后立刻注入页面style: () import(./v1-panel.scss)采用动态import惰性加载 SCSS 内容编译后由脚本的样式管理模块负责挂载到文档。这种「元数据声明 惰性加载样式」的写法是 Bilibili-Evolved 样式类组件的标准范式同类组件如registry/lib/components/style/scrollbar/index.ts、registry/lib/components/style/player-shadow/index.ts均遵循同一结构读者可横向对照。样式实现逐段拆解v1-panel.scss的全部规则都挂在.be-settings容器类下。.be-settings正是设置面板入口组件SettingsContainer.vue的根节点类名见 SettingsContainer.vue它承载了左侧悬浮的「功能 / 设置」两个圆形图标按钮以及两个弹出面板widgets-panel-popup与settings-panel-popup。1. 弹窗面板贴边全屏化.be-settings { .be-popup { top: 0 !important; left: 0 !important; body.settings-panel-dock-right { left: unset !important; right: 0 !important; } transform: translateZ(0) translateY(0) translateX(calc(-101% * var(--direction))) !important; --panel-height: 100vh !important; .open { transform: translateZ(0) translateY(0) translateX(0) !important; } ...默认情况下将弹出面板固定到视口左上角top: 0; left: 0并把--panel-height强制设为100vh即面板高度撑满整个视口——这是 v1 时代「设置页全屏覆盖」的核心观感关闭状态下面板沿--direction方向平移-101%恰好完全移出屏幕外侧translateZ(0)用于强制创建独立渲染层避免位移过程中出现锯齿或闪烁当停靠在右侧body.settings-panel-dock-right时left复位、right: 0面板改从右边缘贴齐。其中--direction是停靠方向变量停靠左侧时为1停靠右侧时为-1见 src/components/settings-panel/dock/_left.scss 与 src/components/settings-panel/dock/_right.scss。所有calc(... * var(--direction))的位移都以此实现「同一套规则、左右镜像」的效果。 * { border-radius: 0 !important; border-width: 0 1px 0 0 !important; height: var(--panel-height) !important; body.settings-panel-dock-right { border-width: 0 0 0 1px !important; } }面板内部子元素即.settings-panel与.widgets-panel的圆角被清零边框改为仅保留贴边一侧的 1px 分隔线左侧停靠保留右边框右侧停靠保留左边框高度同步撑满视口逐条覆盖均带!important这是样式组件的必然选择——需要压过脚本自身 SCSS如SettingsPanel.vue中默认的border-radius: 8px以及页面既有样式。2. 侧边栏悬浮胶囊与旋转动画 .sidebar * { width: 52px !important; border-radius: 21px !important; transform: translateX(calc(-13px * var(--direction))) !important; display: flex !important; justify-content: flex-end !important; body.settings-panel-dock-right { justify-content: flex-start !important; } .be-icon { transition: 0.2s ease-out !important; } :hover { transform: translateX(calc(8px * var(--direction))) !important; .be-icon { transform: rotate(360deg) !important; } } .open { transform: translateX(calc(12px * var(--direction))) !important; } }.sidebar即SettingsContainer.vue中承载「功能 / 设置」两个图标的悬浮条。v1 风格将其从默认的圆形小按钮默认尺寸26px、圆形背景见 SettingsContainer.vue改造成拉长为胶囊宽度固定52px、圆角21px图标通过display: flex加justify-content: flex-end靠外侧对齐默认半隐藏整体向屏幕外平移-13px只露出约一半符合 v1 时代侧边栏「贴边收纳」的交互习惯悬停滑出鼠标悬停时平移到8px露出全貌同时内部图标rotate(360deg)转满一圈过渡动画0.2s ease-out激活态面板打开.open时侧边栏滑到12px的位置并保持。3. 组件标签收尾圆角修正.settings-panel-popup .component-tags .component-tags-item:last-child { border-radius: 0 !important; }设置面板左侧的标签栏ComponentTags.vue渲染的.component-tags在 v1 全屏贴边的形态下最后一个标签项的圆角被清零与全屏无圆角的面板观感保持一致避免出现「面板直角、标签圆角」的割裂感。4. 功能面板widgets-panel单列流式布局.widgets-panel { padding: 24px !important; include no-scrollbar(); -header { margin-bottom: 36px !important; } .widgets-popup { --columns: 1; --medal-columns: 1; --title-columns: 1; left: 50%; top: calc(100% 4px) !important; transform-origin: top !important; box-sizing: border-box; max-width: calc(100% 44px) !important; max-height: unset !important; transform: translateX(calc(-50% * var(--direction))) scale(0.9) !important; display: flex !important; flex-wrap: wrap !important; * { flex-grow: 1; } .open { transform: translateX(calc(-50% * var(--direction))) scale(1) !important; } body.settings-panel-dock-right { left: unset !important; right: 50% !important; } } }功能面板WidgetsPanel.vue承载着「已启用功能」的开关列表v1 样式对它的调整包括面板内边距加大到24px隐藏滚动条include no-scrollbar()该 mixin 定义于脚本共享样式强制各列数为1--columns: 1等功能项改为单列纵向排布.widgets-popup功能项分组弹出菜单以left: 50%水平居中、出现在面板头部下方未展开时scale(0.9)轻微缩小、展开时恢复scale(1)形成「自上而下放大浮现」的入场动效停靠右侧时对称切换为right: 50%定位。与设置面板源码的联动机制方向变量从何而来--direction并非由v1-panel.scss定义而是由停靠样式在body层面维护。设置面板组件在 src/components/settings-panel/index.ts 中监听「设置面板停靠」选项addComponentListener( ${metadata.name}.dockSide, (value: SettingsPanelDockSide) { document.body.classList.toggle( settings-panel-dock-right, value SettingsPanelDockSide.Right, ) }, true, )停靠侧由SettingsPanelDockSide枚举dock.ts定义取值为Left 左侧/Right 右侧。当选择右侧停靠时body获得settings-panel-dock-right类同时 dock/_right.scss 在.be-settings上设置--direction: -1左侧停靠则由 dock/_left.scss 设置--direction: 1。v1-panel.scss中的大量calc(... * var(--direction))正是依赖这层「方向变量」实现了左右镜像的同一套布局这也解释了为什么样式中会出现大量body.settings-panel-dock-right 嵌套选择器来兜底边界情况。全屏高度与默认高度的差异脚本默认的面板高度是--panel-height: calc(100vh - 120px)见 SettingsContainer.vue弹出面板垂直居中显示、带 8px 圆角见 SettingsPanel.vue。v1-panel.scss正是针对这三点高度、定位、圆角逐一覆盖把它拉回 v1 的全屏贴边形态。因此可以推断该组件的覆盖目标是 v2 重构后的设置面板 DOM 结构若未来面板 DOM 结构变化组件也需要同步适配。组件启停与样式注入作为「即时样式」组件v1PanelStyle启用后由脚本的样式管理模块立即注入v1-panel.scss编译产物关闭后随即移除无需刷新页面即可在 v1/v2 两套视觉间切换。该组件与「设置面板停靠」选项相互独立v1 样式在左、右两种停靠下均能正常工作通过--direction与settings-panel-dock-right类的组合适配。在设置面板中定位与搜索启用后用户可在脚本设置面板中通过「样式」标签tags: [componentsTags.style]筛选到「v1 风格设置面板」这一项。设置面板的搜索逻辑见 SettingsPanel.vue会将组件的name、displayName、标签名称与描述文本拼合后做小写匹配因此搜索「v1」「面板」等关键词即可命中本组件。此外ComponentTags.vue渲染的标签栏就是上文样式中被修正圆角的.component-tags区域。小结v1-panel是 Bilibili-Evolved 中一个典型的「纯样式覆盖型」组件通过defineComponentMetadata声明元数据、以instantStyles惰性注入 SCSS用约 80 行带!important的覆盖规则将 v2 圆角弹出式设置面板还原为 v1 时代的全屏贴边外观。其实现中利用--direction方向变量与settings-panel-dock-right类实现左右停靠的镜像适配并通过translateX(calc(... * var(--direction)))配合translateZ(0)完成滑入滑出与旋转动画为读者理解脚本内样式组件的注册方式、覆盖策略与停靠联动机制提供了完整可参考的范例。若需调整 v1 面板的贴边方向、胶囊宽度或动画时长直接修改 v1-panel.scss 中的对应规则即可。【免费下载链接】Bilibili-Evolved强大的哔哩哔哩增强脚本项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表