主题
组件皮肤
主播酱的「组件皮肤」(Skin)让设计师 / 前端开发者用 一段 CSS(可选附带少量结构字段)就能改写内置组件的外观——背景、颜色、描边、阴影、动效乃至重排版式,做出一套套可在画布上一键切换的皮肤。
这与创意工坊是两套独立机制:
- 创意工坊挂件:你自带
manifest.json+index.html,在 iframe 里渲染全新的元素。- 组件皮肤:你不写 DOM,只写 CSS,给主播酱已有的内置组件换皮。组件的 DOM 结构、类名、id 由客户端固定提供,你照着它写选择器即可。
想加一个全新玩法 → 看创意工坊;想给加班机 / 礼物菜单 / 弹幕姬换个好看的样式 → 就在这里。
哪些组件支持皮肤
当前开放皮肤的内置组件有三个(由 config/index.vue 的 SKIN_SUPPORTED_TYPES 决定):
| 组件 | 元素类型(ElementType) | 包裹层类名 | 皮肤机制 |
|---|---|---|---|
| 加班机 | OvertimeMachine | .overtime-wrapper | 作用域注入(data-skin-id) |
| 礼物菜单 | GiftMenu | .gift-menu | 作用域注入(data-skin-id) |
| 弹幕姬 | ChatRenderer | yt-live-chat-renderer 子树 | 整表主题(<link>,blivechat 风格) |
加班机与礼物菜单走同一套作用域注入机制,是最典型的皮肤写法;弹幕姬因为要兼容海量现成的 blivechat 主题,走的是整表主题机制,两者写法不同,分别见各自章节。
工作原理速览
- 每个支持皮肤的元素根节点上都有
:data-skin-id="data.skinId"。用户在「样式」面板选了某张皮肤,元素的skinId就被写成该皮肤 id。 - 皮肤的 CSS 被注入
<style>,并自动作用域到.{包裹层类名}[data-skin-id="{皮肤 id}"]之下。这个前缀的特异性是(0,3,0),稳定高于组件自身 Vue scoped 样式的(0,2,0),所以无需!important就能覆盖默认外观。 - 皮肤还可以带一个
data字段,里面的键值会被合并进元素数据——用于切换那些决定 DOM 结构的字段(如加班机的displayMode)。 - 内置皮肤打包进客户端(
css字符串);商城皮肤走远端(cssUrl+skinData),应用前由客户端 fetch 下来同样经过作用域处理。
完整机制见 皮肤机制。
我想…
| 想做的事 | 从这里开始 |
|---|---|
| 5 分钟做出第一张皮肤(礼物菜单) | 快速开始 |
搞清 data-skin-id / 特异性 / CSS 变量 / data 字段到底怎么回事 | 皮肤机制 |
| 查礼物菜单的完整 DOM 结构与可用钩子 | 礼物菜单皮肤 |
| 查加班机(经典 / 简约两种版式)的 DOM | 加班机皮肤 |
| 给弹幕姬套 / 写一套 blivechat 风格主题 | 弹幕姬主题 |
| 把做好的皮肤上架商城 | 上架与分发 |
关键约定
写任何一张皮肤前,先记住四件事:
- 所有规则都包在
.包裹层[data-skin-id="本皮肤 id"]之下(内置皮肤用 CSS 原生嵌套 +&)。客户端会对没写包裹层的远端皮肤自动补一层,但内置皮肤请按约定手写。 @keyframes写在顶层(不能放进嵌套块内),名字带皮肤前缀(如zbj-overtime-classic-aurora-spin)避免多张皮肤全局撞名。- 谨慎改
font-size——它会影响布局尺寸(加班机是autoSize,会触发重新测高)。皮肤优先改色彩、描边、阴影、背景、装饰。 - 背景按需透明——皮肤会叠加在画布上,礼物菜单 / 弹幕姬通常保持透明,只有加班机这类「面板」才需要不透明底板。
术语
| 术语 | 含义 |
|---|---|
| 皮肤(Skin) | 一段作用于某个内置组件的 CSS(+ 可选 data),见 src/types/skin.ts |
| 包裹层(Wrapper) | 元素根节点的类名,皮肤选择器的作用域前缀,如 .overtime-wrapper |
data-skin-id | 绑在元素根节点上的属性,值为当前皮肤 id,作用域选择器靠它命中 |
skinData / data | 应用皮肤时合并进元素数据的字段(结构性字段,如 displayMode) |
| 整表主题 | 弹幕姬专用:一整张 blivechat 样式表,用 <link> 全局加载 |