npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@rainlotus97/ui

v1.0.0

Published

仙侠风游戏 UI 组件库

Readme

Xianxia UI 仙侠风游戏组件库

基于 Atlas Sprite Sheet + 运行时裁图 + 9-slice 渲染 的 Vue3 组件库,专为仙侠风游戏 UI 设计。

核心特性

✅ 运行时从 Atlas 裁子图 — 主题仍然只维护一张 atlas,组件加载时用 canvas 裁出目标资产
✅ 自动去背 — 裁出的子图会把品红背景 key 掉,生成透明 PNG data URL
✅ 9-slice 自适应 — 容器类组件任意拉伸不变形
✅ 主题切换 — 换一张 atlas 图 + 配置即可切换整套主题
✅ 标准化项目结构 — Vite + Vue3 + TypeScript
✅ 零依赖运行时 — 纯 CSS 实现,无需额外库

✅ 线条游戏组件 — 不依赖固定尺寸的装饰图,可直接用于移动端活动入口、任务条目、头像与操作界面

线条组件

以下组件以 CSS 边线、角花和内嵌 SVG 图标构成,tone 均支持 jade、gold、rose、stone。它们默认适配窄屏;容器宽度由父级控制,不会把素材拉伸变形。

<script setup lang="ts">
import { XActivityPanel, XAvatarFrame, XCultivationPanel, XPlayerHud, XTabBar, XTaskEntry } from '@rainlotus97/ui'
</script>

<template>
  <XActivityPanel
    title="问鼎九霄"
    description="踏入云海秘境,争夺登仙榜首。"
    time-left="余 6日12时"
    reward="首通:灵石 x 300"
    icon="crown"
    tone="gold"
    @click="openActivity"
  />

  <XTaskEntry
    title="宗门悬赏"
    description="完成一次灵脉巡查"
    :progress="2"
    :progress-max="3"
    icon="mission"
    @click="openTask"
  />

  <XAvatarFrame src="/avatars/hero.webp" alt="云岫" level="42" tone="jade" />

  <XPlayerHud
    player-name="云岫"
    realm="炼气后期"
    level="42"
    :items="[
      { label: '修为', value: '12.35万', suffix: '+', icon: 'cultivation' },
      { label: '灵石', value: 2568, suffix: '枚', icon: 'spirit-stone', tone: 'gold' }
    ]"
  />

  <XCultivationPanel
    title="修炼"
    realm="炼气后期"
    current="1230"
    max="2345"
    :progress="52"
    progress-label="练气六层"
    timer="00:12:34"
    efficiency="36/5秒"
    next-breakthrough="筑基期"
    :metrics="[
      { label: '修炼增益', value: '+18%', icon: 'spark' },
      { label: '渡劫概率', value: '72%', icon: 'crown', tone: 'gold' },
      { label: '服药', value: '回春丹', icon: 'pill', tone: 'rose' },
      { label: '武器法宝', value: '青锋剑', icon: 'sword', tone: 'stone' }
    ]"
    @action="enterCultivation"
  />

  <XTabBar
    v-model="activeTab"
    :items="[
      { value: 'map', label: '云游', icon: 'map' },
      { value: 'cultivation', label: '修炼', icon: 'cultivation' },
      { value: 'sect', label: '宗门', icon: 'sect' },
      { value: 'backpack', label: '背包', icon: 'backpack' },
      { value: 'settings', label: '设置', icon: 'settings' }
    ]"
  />
</template>

| 组件 | 用途 | 关键 Props | | --- | --- | --- | | XActivityPanel | 活动入口或运营卡片 | title、description、timeLeft、reward、icon、tone | | XTaskEntry | 日常、主线、奖励领取 | state (active/ready/done/locked)、progress、progressMax、tag | | XAvatarFrame | 玩家、同道、NPC 头像框 | src、alt、level、status、shape、size | | XPlayerHud | 人物信息与资源顶部栏 | playerName、realm、level、items,支持 avatar 插槽 | | XCultivationPanel | 修炼、增益、渡劫与装备状态面板 | current、max、progress、metrics、timer | | XTabBar | 移动端底部导航入口 | modelValue、items,支持 select 事件 |

XActivityPanel 提供 background 与 icon 插槽;当另一个项目已有角色或活动原图时,直接放入插槽即可。组件本身不生成或绑定背景图片。

XAvatarFrame 默认采用圆形边框,等级角标为圆形,关系/在线状态角标为胶囊形;只有需要装备栏、图鉴格位时再传入 shape="square"。

XTabBar 会按 items 数量自动分栏,适合固定在移动端底部;组件只负责线条容器与交互状态,入口内容由项目传入。

XCultivationPanel 使用 CSS/SVG 绘制 270° 进度环,进度从左下向右下缓动推进,环线使用玉青到鎏金的渐变;metrics 可传入修炼增益、渡劫概率、服药、武器法宝等项目数据。中心人物支持 figure 插槽替换为项目自己的透明线稿或角色素材。

<XCultivationPanel ...>
  <template #figure>
    <img src="/line-assets/cultivation-figure-line-crop.png" alt="" aria-hidden="true" />
  </template>
</XCultivationPanel>

角色与物品面板

新增的 XInventoryPanel、XEquipmentPanel、XUpgradePanel 和 XItemArt 用于组合背包、人物穿戴替换与法器升级流程。物品图不复用类型图标:每个物品都拥有独立的 id、assetKey、assetPath 和 artPrompt。

当前内置 60 件故事物品目录,分为武器、防具、饰品、丹药、药草和材料六类,位于 src/assets/items/item-catalog.ts。图像生成规范位于 ITEM_SHEET_PROMPTS.md:每张 sprite sheet 固定 5×2 个物品格,每格 256×256,总尺寸 1280×512;生成完成后可直接通过 iconSheet 与 iconFrame 接入,或切成独立 PNG。

正式物品图要求使用实体材质渲染,不使用线条图或 emoji 占位。图像尚未接入时,组件会显示语义占位字形,方便先验证布局和交互。

项目结构

xianxia-ui/
├── src/
│   ├── components/              # 组件
│   │   ├── XButton.vue
│   │   ├── XCard.vue
│   │   └── XPanel.vue
│   ├── composables/             # 组合式 API
│   │   ├── useTheme.ts         # 主题管理
│   │   └── useAtlasSprite.ts   # Atlas 样式生成
│   ├── types/                   # 类型定义
│   │   └── index.ts
│   ├── assets/                  # 资产文件
│   │   └── themes/
│   │       └── default/
│   │           └── theme.json  # 主题配置(组件在 atlas 中的坐标)
│   ├── styles/
│   │   └── global.css
│   └── index.ts                 # 入口
├── examples/                    # 演示应用
│   ├── App.vue
│   └── main.ts
├── public/
│   └── atlas-full-atlas-components-v1.png  # Atlas 图集
├── vite.config.ts
├── tsconfig.json
└── package.json

快速开始

安装依赖

pnpm install

启动开发服务器

pnpm dev

访问 http://localhost:5173/ 查看演示页面。

构建组件库

pnpm build

发布

构建会先生成 dist 中的 ESM、CommonJS、CSS 和 TypeScript 声明文件,prepack 会自动执行构建:

pnpm pack --dry-run
npm publish --access public

发布账号需要对 @xianxia scope 有权限。应用生产环境使用 semver 安装;组件库修改期间,应用可使用 pnpm dev:ui 直接读取兄弟目录源码进行 HMR。

License

MIT License,详见 LICENSE。

组件使用

1. 初始化主题

<script setup>
import { onMounted } from 'vue'
import { useTheme } from '@rainlotus97/ui'

const { loadTheme } = useTheme()

onMounted(async () => {
  await loadTheme('default')
})
</script>

2. 使用组件

<template>
  <!-- 按钮 -->
  <XButton token="button.primary" @click="handleClick">
    开始修仙
  </XButton>

  <!-- 自定义尺寸 -->
  <XButton token="button.primary" size="20rem">
    大按钮
  </XButton>

  <!-- 卡片 -->
  <XCard token="card.feature" size="28rem">
    <template #title>历练</template>
    <template #content>游历四方<br>获取资源</template>
  </XCard>

  <!-- 面板 -->
  <XPanel token="panel.announcement" size="36rem">
    <div>自定义内容</div>
  </XPanel>
</template>

<script setup>
import { XButton, XCard, XPanel } from '@rainlotus97/ui'

const handleClick = () => {
  console.log('按钮被点击')
}
</script>

主题配置说明

主题配置文件 src/assets/themes/default/theme.json 定义了每个组件在 atlas 中的位置:

{
  "name": "default",
  "version": "1.0.0",
  "atlasPath": "/atlas-full-atlas-components-v1.png",
  "atlasSize": {
    "width": 1024,
    "height": 1024
  },
  "assets": {
    "button.primary": {
      "type": "9slice",
      "sprite": {
        "x": 20,        // 在 atlas 中的 x 坐标
        "y": 20,        // 在 atlas 中的 y 坐标
        "width": 680,   // 组件宽度
        "height": 180   // 组件高度
      },
      "slice": {
        "top": 60,      // 9-slice 上边距(边角装饰区域)
        "right": 120,
        "bottom": 60,
        "left": 120
      },
      "defaultSize": "16rem",
      "category": "button"
    }
  }
}

调整组件位置和 9-slice 边距

如果组件显示不正确(边角被拉伸、位置偏移),只需编辑 theme.json:

  1. 调整坐标 — 修改 sprite.x/y 定位到正确位置
  2. 调整尺寸 — 修改 sprite.width/height 裁切正确区域
  3. 调整 9-slice — 修改 slice 值,增大/减小边角装饰区域

刷新页面即可看到效果,无需重新生成图片。

切换主题

创建新主题:

  1. 准备新的 atlas 图集(保持组件布局一致)
  2. 复制 src/assets/themes/default/ 为 src/assets/themes/dark/
  3. 替换 atlasPath 指向新图集
  4. 调整各组件的坐标(如果布局变化)

加载新主题:

await loadTheme('dark')

技术原理

为什么运行时裁子图?

  • 浏览器原生 border-image 不能从 atlas 子区域取图:它只能接收整张图片作为 source。
  • 主题仍然是一张图:组件通过 theme.json 的坐标裁出子图,不需要手工导出多张 PNG。
  • 9-slice 作用在裁出的透明子图上:这样四角固定、边和中心可伸缩,和验证 01 的结论一致。

9-slice 原理

组件先用 canvas 从 atlas 裁出某个区域并去掉品红背景,再把裁出的透明 PNG 作为 border-image-source:

border-image-source: url(cropped-transparent-sprite.png);
border-image-slice: 60 120 60 120;  /* 定义边角区域 */
border-image-width: 60px 120px 60px 120px;

组件拉伸时,四个边角固定,四条边单向拉伸,中心区域双向拉伸。

当前组件

  • ✅ XButton — 按钮(横向胶囊 + 小方形)
  • ✅ XCard — 功能卡片
  • ✅ XPanel — 面板容器(公告横幅 + 方形面板)
  • ⏸️ 装饰元素 — 鹤装饰(已生成,未封装组件)

下一步

  • [ ] 完善演示页面(展示更多尺寸变化、交互状态)
  • [ ] 添加更多组件(对话框、进度条、角色卡)
  • [ ] 优化 9-slice 配置(可视化调整工具)
  • [ ] 生成更多风格的 atlas(暗黑主题、节日主题)
  • [ ] 响应式适配方案(rem 基准计算)

许可

ISC