Skip to content

加班机皮肤

加班机(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-wrapperfont-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-warmdata: { 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);
  }
}