主题
加班机皮肤
加班机(ElementType.OvertimeMachine)一个面板里有标题、倒计时、分割线、触发规则、触发日志,还分经典 / 简约两种版式。源码 src/components/DrawEl/el-overtime-machine.vue,内置皮肤 src/assets/data/skins/overtime-machine.ts。
规范
- 作用域前缀:
.overtime-wrapper[data-skin-id="<本皮肤 id>"],子选择器用&嵌套(如& .countdown { ... })。 data必填版式:{ displayMode: "classic" | "simple", width: 280 }。版式是结构性字段,CSS 切不动,必须在data里声明,否则套到的版式不确定。- 别写
height:加班机autoSize=true,高度由内容经ResizeObserver自适应,写死会在切换瞬间闪一下再被覆盖。统一width: 280与默认对齐。 - 慎改
--font-size-base/font-size:标题、规则、日志都按倒计时基准字号比例缩放,改基准会整体重排并触发重新测高。 - 动画:
@keyframes写在顶层(不能放进嵌套块内),名字带本皮肤前缀避免撞名。 - 版式选对类名:经典用
.rule-*、简约用.simple-*,按声明的版式写。
根节点内联了一组 CSS 变量,皮肤应直接覆盖最终属性而非重定义变量:
| 变量 | 默认作用 |
|---|---|
--font-family | .overtime-wrapper 的 font-family |
--font-size-base | 倒计时 font-size;其它文字按它比例缩放,改它会重排 |
--font-weight | 文字粗细 |
--text-color | 文字颜色 + 分割线底色 |
--bg-color | .machine-content 背景色(默认 rgba(0,0,0,0.6)) |
--stroke | 各文字 -webkit-text-stroke |
--text-shadow | 各文字 text-shadow |
DOM 结构
经典版式(displayMode: "classic")
html
<div class="overtime-wrapper">
<div class="machine-content">
<!-- 底板:背景/圆角/边框/阴影/padding 都在这层 -->
<div class="machine-title">主播加班中</div>
<div class="countdown">02:34:10</div>
<!-- 倒计时,可 order 重排 -->
<div class="divider"></div>
<!-- 分割线(共两条) -->
<div class="rules-section rules-list">
<!-- ≤4 条用 .rules-list,>4 条用 .rules-grid(3 列) -->
<div class="rule-item">
<span class="rule-keyword"
><span class="rule-keyword-text">关键词</span></span
>
<img class="rule-icon" />
<!-- 礼物/点赞规则 -->
<div class="rule-desc-wrap"><span class="rule-desc">+5分钟</span></div>
</div>
</div>
<div class="divider"></div>
<div class="log-section">
<div class="log-item">
<div class="log-line log-user">
<img class="log-avatar" /><span class="log-nickname">观众昵称</span>
</div>
<div class="log-line log-detail">送出 礼物 +5分钟</div>
</div>
<div class="log-placeholder">等待触发中...</div>
</div>
</div>
</div>| 选择器 | 含义 |
|---|---|
& .machine-content | 面板底板(背景 / 圆角 / 边框 / 阴影 / padding) |
& .machine-title | 标题文字 |
& .countdown | 倒计时(皮肤重点;可 order 重排、做发光胶囊) |
& .divider | 两条分割线 |
& .rules-section / & .rules-list / & .rules-grid | 规则区容器(列表 / 3 列网格) |
& .rule-item | 单条规则(可卡片化) |
& .rule-keyword / & .rule-keyword-text | 弹幕关键词标签 |
& .rule-icon | 礼物 / 点赞图标 |
& .rule-desc-wrap / & .rule-desc | 规则效果文字(如 +5分钟) |
& .log-section | 日志区外框 |
& .log-line / & .log-user / & .log-detail | 日志两行文字 |
& .log-avatar | 日志头像(圆形) |
& .log-nickname | 日志昵称 |
& .log-placeholder | 无日志时的占位文案 |
简约版式(displayMode: "simple")
只有倒计时 + 一条横向滚动的规则带;底板节点同样是 .machine-content,额外带 .machine-simple 类。
html
<div class="overtime-wrapper">
<div class="machine-content machine-simple">
<div class="countdown">02:34:10</div>
<div class="divider"></div>
<div class="simple-rules-section">
<!-- 内部横向滚动 -->
<span class="simple-rules-track">
<span class="simple-rule-item">
<span class="simple-keyword">关键词</span>
<img class="simple-rule-icon" />
<span class="simple-rule-desc">+5分钟</span>
</span>
</span>
</div>
</div>
</div>| 选择器 | 含义 |
|---|---|
& .machine-content / & .machine-content.machine-simple | 面板底板 |
& .countdown | 倒计时 |
& .divider | 分割线 |
& .simple-rules-section | 规则滚动区 |
& .simple-rule-item | 单条规则 |
& .simple-keyword | 弹幕关键词 |
& .simple-rule-icon | 礼物 / 点赞图标 |
& .simple-rule-desc | 规则效果文字 |
示例
基础换色(经典)
内置「暖光经典」overtime.classic-warm,data: { displayMode: "classic", width: 280 }:
css
.overtime-wrapper[data-skin-id="overtime.classic-warm"] {
& .machine-content {
background: linear-gradient(
135deg,
rgba(60, 30, 10, 0.95),
rgba(30, 15, 5, 0.95)
);
border: 1px solid rgba(255, 180, 80, 0.5);
border-radius: 18px;
box-shadow:
0 12px 36px rgba(255, 140, 60, 0.22),
inset 0 0 30px rgba(255, 180, 80, 0.08);
}
& .machine-title,
& .countdown,
& .rule-desc,
& .log-line {
-webkit-text-stroke: 0 transparent;
}
& .machine-title {
color: #ffd28a;
font-weight: bold;
text-shadow: 0 0 14px rgba(255, 180, 80, 0.7);
}
& .countdown {
color: #fff7e6;
font-weight: bold;
text-shadow: 0 0 24px rgba(255, 200, 100, 0.85);
}
& .divider {
background: linear-gradient(
90deg,
transparent,
rgba(255, 180, 80, 0.7),
transparent
);
opacity: 1;
}
& .rule-keyword {
background: rgba(255, 180, 80, 0.18);
border: 1px solid rgba(255, 180, 80, 0.4);
border-radius: 8px;
}
& .log-nickname {
color: #ffb86b;
}
}重排版式 + 动效(经典)
内置「极光脉冲」overtime.classic-aurora 节选——倒计时 order 上移成居中发光胶囊,面板背后用 ::before 旋转极光:
css
.overtime-wrapper[data-skin-id="overtime.classic-aurora"] {
& .machine-content {
position: relative;
isolation: isolate;
border-radius: 20px;
background:
radial-gradient(
130% 80% at 50% -10%,
rgba(40, 110, 140, 0.5),
transparent 70%
),
linear-gradient(168deg, #0c1a2c, #0a1422 55%, #070c15);
}
& .machine-content::before {
content: "";
position: absolute;
inset: -35%;
z-index: -1;
border-radius: 50%;
background: conic-gradient(
from 0deg,
transparent,
rgba(30, 189, 188, 0.5) 70deg,
rgba(127, 233, 255, 0.55) 120deg,
rgba(150, 110, 255, 0.5) 180deg,
transparent 250deg
);
filter: blur(26px);
animation: zbj-aurora-spin 9s linear infinite;
}
& .countdown {
order: -2;
align-self: center;
margin: 4px 0 14px;
padding: 12px 26px;
border-radius: 16px;
border: 1px solid rgba(127, 233, 255, 0.4);
color: #fff;
font-weight: 800;
letter-spacing: 6px;
-webkit-text-stroke: 0 transparent;
}
& .machine-title {
order: -1;
align-self: center;
border-radius: 999px;
}
}
/* @keyframes 写在顶层,名字带皮肤前缀避免撞名 */
@keyframes zbj-aurora-spin {
to {
transform: rotate(360deg);
}
}