跳到正文

// GAME Game 实机风格

Game 实机风格

和主库的区别、怎么引入、带了哪些官方图片、风险和我们的处理

照游戏内界面复刻的一组控件,外加一个带官方图片的官网开屏页。它和本库其余的部分是两套东西,所以单独成一类、单独一个入口:

主库 Game 实机风格
依据 官网的实测,和从它延伸出来的规范 游戏内界面的样子,经社区项目 EndfieldMap、EndfieldWiki 的实现转来;开屏页是官网的实测
配色 语义令牌,随亮 / 暗主题翻转,强调色可以换 固定的灰与黄,不随主题变;只有物品卡片的背景分亮暗
样式 Tailwind 工具类 每个控件一份纯 CSS,类名以 ef- 开头
图片 不带任何图片 带 30 张官方图片,见风险与处理
入口 @endfield-ui/react @endfield-ui/react/game

主入口不导出这里的任何东西,主样式里也没有它的一条规则:不引这个入口,就和它不存在一样。

引入#

import "@endfield-ui/react/game.css";
import { AnimatedDialog, RoundedButton } from "@endfield-ui/react/game";
  • 样式是单独的一份,纯 CSS,用不用 Tailwind 都是它。和主样式一起引(tailwind.css 或 styles.css):它用到主样式里的令牌(焦点色、层叠值、字体栈)和基础重置。
  • 从脚本里 import,让打包工具去处理里面图片的相对地址。写在自己的 CSS 里 @import 也行,前提是你的构建会改写 url()(Vite 会,Tailwind CLI 不会)。
  • 规则都在 components 这一层:压得过基础重置,让得开你传进去的工具类——className、classNames 里写的 Tailwind 类能盖掉默认值。和主样式谁先谁后都一样。
  • 用到的主库的东西(Field 的上下文、局部主题)和主入口是同一份,两类控件可以混着用:RoundedSelect 放进主库的 Field 里,照样接得上标签和校验状态。

控件#

控件 是什么 文档
AnimatedDialog 分段入场的装饰弹窗 动画弹窗与圆角下拉
RoundedSelect 圆角触发器、灰色面板的下拉 动画弹窗与圆角下拉
RoundedButton、RoundedIconButton 圆角文字按钮、24px 的圆形图标按钮 圆角控件
RoundedToggle 圆角的分段选择 圆角控件
RoundedSwitch ON / OFF 两格的文字开关 圆角控件
BannerAlert 紧凑的确认卡片 确认提示
FullWidthAlert 横贯视口的确认面板 确认提示
ItemCard、ItemIcon 物品卡片(稀有度、库存)与分层图标 物品卡片
ItemTooltipCard、ItemHoverCard、ItemHoverCardLayer 物品详情卡与悬浮预览 物品悬浮卡
EndfieldSplashScreen 官网首次载入的开屏页:主入口的 SplashScreen 填上官方的标志、底图和微标 官网开屏页

主库里名字相近的控件各是各的:Dialog、Select、Button、SegmentedControl、Switch、Alert、ItemSlot、HoverCard 的接口和样子都不因为这一类而变。

预览站里,这一类的 story 在侧栏最后一组;顶上“示例”组的最后另有一页“实机风格”,把这些控件摆在一页里——三个弹窗除了能点开,还直接摆在页面上。

EndfieldSplashScreen 和别的不一样:它复刻的是官网,不是游戏内的界面,排法和动画都在主入口的 SplashScreen 里,这个入口只是替它把官方的图填上——带官方图片的东西只许放在这里。

这一类的控件用的是固定的浅色皮肤(开屏页是固定的近黑底)。弹窗和确认提示的正文区是一块局部的亮色主题:页面是暗色时,放进去的主库控件也按亮色取值。

风险与处理#

这个入口带着官方图片。用之前请读完这一节。

带了什么#

30 张图片。前 25 张取自《明日方舟:终末地》的游戏界面与物品图,经社区项目 EndfieldMap 和 EndfieldWiki 转来;开屏页的 5 张是 2026-10-14 直接从官网首页的加载页取的:

用在哪 张数 内容 随 npm 包
圆形图标按钮 1 等高线纹理 是
两种确认提示 4 横幅的斜纹装饰两张、卡片的半调底图、通栏面板的标志底图 是
物品卡片 12 物品 / 武器 / 敌人的亮暗背景六张、六档稀有度的底边六张 是
物品详情卡 3 标题纹理、详情入口的图标、正文底图 是
官网开屏页 5 横竖两张暗色底图、游戏的标志、一张微标(带框的加号、两行微文字、方点阵)、一枚三角标 是
预览站的示例 5 四件物品的图标和一张瓶内内容 否

逐张的路径、尺寸、字节数、SHA256 和来源登记在 resource-provenance.json。

另有两处不是图片:AnimatedDialog 装饰条上的 ARKNIGHTS:ENDFIELD 和 ENDFIELD 是代码画的字,是游戏的英文名;物品详情卡"获取途径"的两个图标用的是 Lucide 的路径(ISC 许可,许可文本随包带着),不是官方素材。

风险#

  1. 没有授权。 这些图片的著作权归鹰角网络及其权利人。本仓库没有取得授权,转来它们的两个上游仓库也没有标明许可。本仓库的 MIT 许可只覆盖代码,不覆盖这些图片——它给不了你使用这些图片的权利。
  2. 商标。 splash_logo.svg(EndfieldSplashScreen 正中偏右的那一块)就是游戏的标志「明日方舟:终末地 / ARKNIGHTS ENDFIELD」本身,而且开屏页是别人打开你的页面看到的第一样东西。deco_common_logo_bg.png(FullWidthAlert 左下的底图)里是官方的「终末地 / ENDFIELD INDUSTRIES」标志,AnimatedDialog 的装饰字是游戏的英文名。比起别的纹理,它们更容易让人把你的页面认成官方的,是这一类里风险最高的三处,开屏页的标志排第一。
  3. 可能被撤下。 权利人提出异议时,这些图片会从仓库和之后的版本里拿掉,已经发布的版本可能被标记为弃用。依赖它们的外观会跟着变。
  4. 你自己的发布。 把带这些图片的页面公开发布,尤其是用于商业用途,合不合规要由你自己判断并负责。截至撰写时,我们没有检索到针对《终末地》的官方同人创作规范原文(见 NOTICE)。
  5. 包里有这些文件。 不引这个入口,打包工具不会把任何一张图带进你的产物;但 npm 包的压缩包里仍然有它们(dist/game/assets/)。连依赖包里都不能出现官方素材的场合,这个包目前满足不了。

我们怎么处理#

  • 隔离。 图片只放在 packages/ui/src/game/<控件>/assets/;发布的包里只在 dist/game/assets/ 一处,只被 game.css 引用。主入口、主样式、令牌和母题工具类里没有它们。有测试守着:game 目录之外不许有图片,主库不许引 game 目录里的任何东西。
  • 登记。 每一张都在清单里,文件的字节和清单对不上,测试就不过;要加图,先加清单。
  • 可以关,可以换。 一个开关整类不加载官方图片,每一张也能单独换成你自己的,见下面的换掉或关掉图片。
  • 撤下的流程。 权利人通过 Issue 联系即可。我们会拿掉被指出的图片,发一个补丁版本,并把受影响的旧版本在 npm 上标记为弃用。
  • 图片不在语义化版本的承诺之内。 撤换这个入口的图片不算破坏性变更,不会为它升主版本号。控件的接口(属性、导出、类名、下面的变量和开关)照常按语义化版本走;图片拿掉之后,控件退回没有图的画法——就是关掉开关时的样子,照常能用。
  • 高对比模式下本来就不画。 系统的高对比模式(forced-colors)里,这些装饰图整个不显示。

换掉或关掉图片#

整类关掉:在祖先元素上写 data-ef-game-images="off"。弹窗和悬浮卡挂在 <body> 下,所以写在 <html> 上最省事:

<html data-ef-game-images="off">

关了之后这一类的控件不再请求任何一张官方图片,退回代码画的样子:按钮没有纹理,两种确认提示是白底,物品卡片的背景是一块跟主题的底色、稀有度是一条色带,详情卡的标题没有纹理、正文底是一段渐变、详情入口是一个画出来的箭头;开屏页没有底图和标志,微标和三角标是代码画的。预览站的"Game 实机风格 / 示例 / 关掉官方图片"就是这个样子。

单独换一张:每张图都经一个变量引用,设了就用你的,写 none 就是不画。写在 :root 上:

:root {
  --ef-game-alert-logo: url("/brand/my-mark.svg");
  --ef-game-button-texture: none;
}
变量 默认的图 用在
--ef-game-button-texture pag-button-texture.png RoundedIconButton 的纹理
--ef-game-alert-banner-left、--ef-game-alert-banner-right alert_banner_bg_left.png、alert_banner_bg_right.png 两种确认提示顶上的横幅
--ef-game-alert-background alert_bg.png BannerAlert 右下的底图
--ef-game-alert-logo deco_common_logo_bg.png(官方标志) FullWidthAlert 左下的底图
--ef-game-itemcard-bg-item、--ef-game-itemcard-bg-weapon、--ef-game-itemcard-bg-enemy 各有亮暗两张,跟着主题取 ItemCard 的背景
--ef-game-itemcard-edge-1 … --ef-game-itemcard-edge-6 icon_card_rarity_1_bottom_edge.webp … 6 ItemCard 的稀有度底边
--ef-game-item-tooltip-header header.webp ItemTooltipCard 标题的纹理
--ef-game-item-tooltip-detail detail.png ItemTooltipCard 正文的底图(九宫格)
--ef-game-item-tooltip-link-icon link.webp ItemTooltipCard 的详情入口
--ef-game-splash-bg、--ef-game-splash-bg-portrait splash_bg.jpg、splash_bg_portrait.jpg EndfieldSplashScreen 横排、竖排的底图
--ef-game-splash-deco、--ef-game-splash-mark splash_deco.svg、splash_triangles.svg EndfieldSplashScreen 的微标和三角标
--ef-game-splash-logo splash_logo.svg(官方标志) EndfieldSplashScreen 标志的形状。它是当遮罩用的:要换成自己的标志或者不要,用 logo 属性,见官网开屏页
  • 开关和变量管的都是图片。AnimatedDialog 装饰条上那两处游戏英文名是代码画的字,不受它们管;要去掉,在自己的样式里把 .ef-animated-dialog__title-deco(标题带右边的大字)和 .ef-animated-dialog__top-deco > svg:first-child(顶条上的小字)藏掉,用 visibility: hidden,位置留着。
  • 换了 ItemCard 的背景就不再分亮暗;要分,在各自的主题容器([data-theme="dark"])上各设一次。
  • 正文底图和详情入口写 none 之后没有替代的画法(文字会压在深色上、入口看不见):这两张要么换成自己的,要么用上面的总开关。
  • 名字以 -default 结尾的同名变量是库里的出厂值,不要改它们。

给使用方的建议#

  • 个人的、非商业的同人场景之外,上线前把图片换成你有权使用的,或者关掉。两张标志建议总是换掉:FullWidthAlert 的那张底图经变量换,开屏页的用 logo 属性换——或者直接用主入口不带图的 SplashScreen。
  • 不要用它做容易被认成官方产品、官方公告或官方周边的东西。
  • 完全不想沾官方素材:只用主入口。