跳转到主要内容

扩展 @spindeck/vinyl-ui

@spindeck/vinyl-ui 是 SpinDeck 的模块化黑胶唱片播放器 UI 库。它将 结构(布局、动画、交互)与 装饰(颜色、纹路、高光)分离,让你可以仅用 CSS 添加新的视觉风格。

特性

  • 交互唱臂 — 拖动唱臂到唱片上播放,抬起暂停。
  • 播放反馈 — 旋转动画与光晕效果随播放状态同步。
  • 自适应布局 — 通过 CSS 变量根据视口计算尺寸与位置。
  • 可扩展样式 — Base + Theme 的 CSS 架构,便于新增黑胶外观。

安装

在工作区包中添加依赖:

json
{
  "dependencies": {
    "@spindeck/vinyl-ui": "workspace:*"
  }
}

或在 monorepo 根目录执行:

bash
pnpm add @spindeck/vinyl-ui --workspace

基本用法

1. 导入样式

在全局 CSS 中导入基础结构与至少一种风格主题:

css
@import "@spindeck/vinyl-ui/styles/base.css";
@import "@spindeck/vinyl-ui/styles/classic.css";
@import "@spindeck/vinyl-ui/styles/modern.css";

2. 渲染组件

tsx
import { SongVinylOverlay } from "@spindeck/vinyl-ui";

function PlayerPage() {
  return (
    <SongVinylOverlay
      song={currentSong}
      platform="QQMusic"
      visible={true}
      pageSessionId="unique-session-id"
      styleName="classic"
      theme="dark"
      tonearmTitle={t("vinyl.tonearm_title")}
      playLabel={t("vinyl.play")}
      pauseLabel={t("vinyl.pause")}
    />
  );
}

共享包不依赖 i18next,请在应用层通过 props 传入已翻译的文案。

组件 API

SongVinylOverlay

Prop类型默认值说明
songSongInfo必填歌曲元数据(名称、艺术家、封面)。
platformPlatformType必填用于播放控制的音乐平台。
visibleboolean必填控制可见性与入场动画。
pageSessionIdstring必填当前页面会话的唯一 ID。
theme"dark" | "light""dark"用于推导光晕颜色。
styleNamestring"classic"对应 .sd-vinyl-style-${styleName}
tonearmPortalRefRefObject可选,将唱臂 portal 到指定层。
tonearmTitlestring唱臂 tooltip(传入翻译后的文本)。
playLabel / pauseLabelstring播放操作的无障碍标签。
vinylColor / labelColorstring覆盖从专辑封面推导的颜色。

其他导出

  • VinylStylePreview — 风格选择器中的迷你预览。
  • Tonearm — 独立的唱臂 SVG 组件。
  • ./lib/vinyl-layout./lib/colors 中的布局与颜色工具函数。

CSS 架构

基础层(base.css

负责定位、层级、旋转动画、唱臂交互与响应式尺寸。主要 class:

Class作用
.sd-vinyl-stage主 overlay 容器
.sd-vinyl-disc黑胶碟片元素
.sd-vinyl-grooves / .sd-vinyl-grooves--fine纹路纹理层
.sd-vinyl-sheen高光 / 反射层
.sd-vinyl-center标签区域(歌名、艺术家)
.sd-vinyl-arm-wrap / .sd-vinyl-arm唱臂容器与 SVG
.sd-vinyl-stage--playing / --pending / --interactive状态修饰符

布局 CSS 变量(由 computeVinylLayout 设置):

  • --vinyl-size — 碟片直径(像素)
  • --vinyl-offset-x — 相对中心的水平偏移
  • --tonearm-height-ratio — 唱臂高度相对碟片的比例

风格层(classic.cssmodern.css 等)

每种风格使用 .sd-vinyl-style-<name> 前缀,装饰基础元素。内置风格:

风格特点
classic丰富纹路、暖色渐变、细腻高光
modern扁平、高对比、极简纹理

创建新黑胶风格

步骤 1 — 添加风格 CSS 文件

创建 packages/vinyl-ui/src/styles/retro.css

css
.sd-vinyl-style-retro .sd-vinyl-disc {
  --vinyl-color: #c62828;
  --vinyl-label-color: #ffeb3b;
  background:
    radial-gradient(circle at 50% 50%, transparent 18%, rgba(255, 255, 255, 0.08) 19%, transparent 20%),
    radial-gradient(circle, color-mix(in srgb, var(--vinyl-color) 60%, #000) 0%, var(--vinyl-color) 100%);
  border: 4px solid color-mix(in srgb, var(--vinyl-color) 50%, white);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
}

.sd-vinyl-style-retro .sd-vinyl-grooves {
  background: repeating-radial-gradient(
    circle at 50% 50%,
    rgba(255, 255, 255, 0.12) 0 0.5px,
    transparent 0.5px 2px
  );
  opacity: 0.8;
}

.sd-vinyl-style-retro .sd-vinyl-center {
  border: 2px solid rgba(255, 255, 255, 0.2);
}

使用 --vinyl-color--vinyl-label-color,以便组件在运行时从专辑封面注入颜色。

步骤 2 — 在 Web 应用中导入

apps/web/app/app.css 中添加:

css
@import "@spindeck/vinyl-ui/styles/retro.css";

步骤 3 — 在设置中暴露

在风格选择器列表中注册新 style ID。SpinDeck 中需更新 SettingsModal.tsx

tsx
{["classic", "modern", "retro"].map((styleId) => (
  // ...
  <VinylStylePreview styleName={styleId} /* ... */ />
))}

选中的 styleId 保存在 VisualSettings.vinylStyle 中,并作为 styleName 传给 SongVinylOverlay

步骤 4 — 使用新风格

tsx
<SongVinylOverlay
  styleName="retro"
  song={song}
  platform={platform}
  visible={visible}
  pageSessionId={pageSessionId}
/>

设计规范

  • 装饰,不重构 — 在 .sd-vinyl-style-<name> 下覆盖颜色、渐变、边框与阴影;不要在风格文件中修改 positionwidth 或动画关键帧。
  • 尊重状态 class — 在 --playing--pending--interactive 等状态下测试效果。
  • 专辑色驱动 — 优先使用 var(--vinyl-color),以支持封面取色。
  • 预览组件 — 选择器中使用相同 styleNameVinylStylePreview,保持缩略图一致。

包开发命令

bash
pnpm --filter @spindeck/vinyl-ui dev    # 监听构建
pnpm --filter @spindeck/vinyl-ui build  # 生产构建
pnpm --filter @spindeck/vinyl-ui lint   # 代码检查

CSS 通过以下路径导出:

  • @spindeck/vinyl-ui/styles/base.css
  • @spindeck/vinyl-ui/styles/<name>.css

另请参阅 扩展 @spindeck/ui,了解应用级主题族与材质契约。

贡献者

The avatar of contributor named as dongguacute dongguacute

页面历史

基于 Apache License 2.0 发布。