@sakitam-gis/sprite-cli
v1.0.2
Published
A modern TypeScript CLI tool for generating sprite sheets from SVG and PNG files with advanced optimization and metadata support
Readme
@sakitam-gis/sprite-cli
一个现代化的、功能强大的雪碧图生成工具,用于从 SVG 和 PNG 文件生成优化的雪碧图(sprite sheets)。使用 TypeScript 编写,具有完善的工程化配置和高级优化功能。
本项目基于 @mapbox/spritezero 核心功能,完全使用 TypeScript 重写,无需外部依赖,并添加了更多高级特性。
✨ 特性
🎨 图像支持
- ✅ SVG 支持 - 原生支持矢量图形,自动优化
- ✅ PNG 支持 - 支持光栅图像输入
- ✅ 多种像素比率 - 支持 1x、2x、3x 等 Retina 显示屏
- ✅ 智能去重 - unique 模式,自动识别相同图像
⚡️ 性能优化
- 🚀 高效布局算法 - Shelf Best Height Fit,空间利用率 80-95%
- 🔥 并发处理 - 多图像并行处理,提升性能
- 💾 智能缓存 - SVG 解析缓存,避免重复计算
- 🗜️ PNG 优化 - 使用 Sharp 进行颜色量化和压缩优化
📋 元数据支持
- 📐 9-patch 元数据 - 支持 stretchX/Y 区域定义
- 📄 内容区域 - 支持 content 区域定义
- 📝 文本占位符 - 支持 placeholder 区域定义
- 🏷️ 自动提取 - 基于 Mapbox 规范自动提取元数据
🛠️ 开发体验
- 💪 TypeScript 编写 - 完整的类型支持和 IDE 智能提示
- ⚙️ 现代化工具链 - ESLint、Prettier、Husky、Vitest
- 📦 零配置使用 - 开箱即用的 CLI 工具
- ✅ 完善测试 - 50+ 测试用例,覆盖核心功能
📦 安装
全局安装
npm install -g @sakitam-gis/sprite-cli
# 或
pnpm add -g @sakitam-gis/sprite-cli
# 或
yarn global add @sakitam-gis/sprite-cli本地安装
npm install --save-dev @sakitam-gis/sprite-cli
# 或
pnpm add -D @sakitam-gis/sprite-cli
# 或
yarn add -D @sakitam-gis/sprite-cli🚀 快速开始
安装
# npm
npm install -g @sakitam-gis/sprite-cli
# pnpm (推荐)
pnpm add -g @sakitam-gis/sprite-cli
# yarn
yarn global add @sakitam-gis/sprite-cli基本用法
sprite-maker [output] [input] [options]示例
1️⃣ 生成标准雪碧图(1x)
sprite-maker output/sprite icons/生成:
output/sprite.png- 雪碧图图片output/sprite.json- 布局信息(包含位置和元数据)
2️⃣ 生成 Retina 雪碧图(2x)
sprite-maker output/sprite@2x icons/ --retina
# 或
sprite-maker output/sprite@2x icons/ --ratio=23️⃣ 生成多种分辨率
sprite-maker output/sprite icons/ # 1x
sprite-maker output/sprite@2x icons/ --ratio=2 # 2x
sprite-maker output/sprite@3x icons/ --ratio=3 # 3x4️⃣ 使用 unique 模式(去重)
sprite-maker output/sprite icons/ --unique5️⃣ PNG 优化选项
# 调色板模式(减小文件大小)
sprite-maker output/sprite icons/ --palette --colors=128
# 自定义质量
sprite-maker output/sprite icons/ --quality=90📖 详细文档
查看 快速开始指南 获取更多详细示例和高级用法。
🔧 CLI 选项
| 选项 | 说明 | 默认值 |
|------|------|--------|
| --retina | 生成 2x 像素比率(等同于 --ratio=2) | false |
| --ratio=<n> | 指定像素比率(1x, 2x, 3x 等) | 1 |
| --unique | 去重模式,相同图像只存储一次 | false |
| --colors=<n> | PNG 颜色数量(2-256) | 256 |
| --quality=<n> | PNG 质量(0-100) | 80 |
| --palette | 使用调色板模式压缩 PNG | false |
| --help, -h | 显示帮助信息 | - |
🛠️ 开发
环境要求
- Node.js >= 18.0.0
- pnpm(推荐)或 npm / yarn
克隆项目
git clone <repository-url>
cd icon-cli安装依赖
pnpm install
# 或
npm install开发命令
# 开发模式(监听文件变化)
pnpm dev
# 构建
pnpm build
# 类型检查
pnpm type-check
# 代码检查
pnpm lint
# 修复代码问题
pnpm lint:fix
# 格式化代码
pnpm format
# 检查代码格式
pnpm format:check
# 运行测试
pnpm test
# 监听模式运行测试
pnpm test:watch
# 测试覆盖率
pnpm test:coverage🏗️ 项目结构
.
├── src/
│ ├── cli.ts # CLI 入口文件
│ ├── types.ts # TypeScript 类型定义
│ ├── utils.ts # 工具函数
│ └── core/
│ ├── index.ts # 核心模块导出
│ ├── layout.ts # 布局算法(Shelf Best Height Fit)
│ ├── image.ts # 图像渲染和 PNG 优化
│ ├── metadata.ts # SVG 元数据提取
│ └── shelf-pack.ts # ShelfPack 打包算法
├── test/
│ ├── cli.test.ts # CLI 端到端测试
│ ├── layout-efficiency.test.ts # 布局效率测试
│ ├── sorting.test.ts # 排序稳定性测试
│ ├── metadata.test.ts # 元数据提取测试
│ ├── performance.test.ts # 性能优化测试
│ ├── shelf-pack.test.ts # ShelfPack 算法测试
│ ├── error-handling.test.ts # 错误处理测试
│ └── fixture/ # 测试 fixtures
├── dist/ # 编译输出目录
├── tsconfig.json # TypeScript 配置
├── tsup.config.ts # 构建配置(tsup)
├── vitest.config.ts # 测试配置(vitest)
├── .eslintrc.cjs # ESLint 配置
├── .prettierrc.json # Prettier 配置
└── commitlint.config.cjs # Commitlint 配置🔧 工程化配置
本项目采用了现代化的工程化工具链:
代码质量
- TypeScript - 类型安全
- ESLint - 代码检查
- Prettier - 代码格式化
- lint-staged - Git 暂存区文件检查
Git 规范
- Husky - Git hooks 管理
- commitlint - Commit 信息规范检查
Commit 信息格式:
<type>(<scope>): <subject>
type: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert示例:
git commit -m "feat: 添加新的命令行选项"
git commit -m "fix: 修复文件路径解析问题"
git commit -m "docs: 更新 README 文档"构建和测试
- tsup - 快速的 TypeScript 构建工具
- Vitest - 现代化的单元测试框架
📝 输出格式
JSON 布局文件
生成的 JSON 文件包含每个图标的位置、尺寸和元数据信息:
{
"icon-name": {
"width": 24,
"height": 24,
"x": 0,
"y": 0,
"pixelRatio": 1,
"metadata": {
"stretchX": [[8, 16]],
"stretchY": [[8, 16]],
"content": [4, 4, 20, 20],
"placeholder": [6, 6, 18, 18]
}
}
}元数据说明
stretchX: 水平拉伸区域(9-patch)stretchY: 垂直拉伸区域(9-patch)content: 内容区域边界[left, top, right, bottom]placeholder: 文本占位符区域[left, top, right, bottom]
SVG 元数据标记
在 SVG 文件中使用特殊的 ID 来定义元数据:
<svg width="24" height="24">
<!-- 定义水平拉伸区域 -->
<path id="mapbox-stretch-x" d="M 8 0 L 16 0 L 16 24 L 8 24 Z"/>
<!-- 定义垂直拉伸区域 -->
<path id="mapbox-stretch-y" d="M 0 8 L 24 8 L 24 16 L 0 16 Z"/>
<!-- 定义内容区域 -->
<path id="mapbox-content" d="M 4 4 L 20 4 L 20 20 L 4 20 Z"/>
<!-- 定义文本占位符 -->
<path id="mapbox-text-placeholder" d="M 6 6 L 18 6 L 18 18 L 6 18 Z"/>
</svg>PNG 雪碧图
生成的 PNG 文件是一个包含所有图标的合成图片,经过高级优化:
- ✅ 自动颜色量化(可配置)
- ✅ 最大压缩级别(level 9)
- ✅ 自适应滤波
- ✅ 可选调色板模式
🤝 贡献
欢迎贡献代码!请确保:
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'feat: 添加某个特性') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
提交代码前,请确保:
- 通过所有测试 (
pnpm test) - 代码符合规范 (
pnpm lint) - 代码格式正确 (
pnpm format:check)
📄 许可证
ISC License
🔍 核心算法
Shelf Best Height Fit
本项目使用 Shelf Best Height Fit 算法进行 2D 矩形打包:
- 排序优化 - 按高度降序 + ID 字母序排序
- 智能打包 - 选择最合适的货架(shelf)放置图像
- 空间复用 - 自动复用释放的空闲区域
- 自动扩展 - 根据需要动态调整画布大小
- 空间利用率 - 达到 80-95%(比简单算法提升 10-20%)
性能优化
- SVG 缓存 - 缓存解析结果,避免重复计算
- 并发处理 - 使用
Promise.all并行处理多个图像 - 惰性计算 - 按需提取元数据和优化
📊 性能测试
基准测试结果(361 个 SVG 图标):
✓ 布局算法效率 > 80%
✓ SVG 缓存加速 > 2x
✓ 并发处理加速 > 3x
✓ 大批量处理 (361 icons) < 5s🙏 致谢
- 原项目:spritezero-cli
- 核心库:@mapbox/spritezero
- 打包算法:ShelfPack
- 图像处理:Sharp
- SVG 优化:SVGO
📮 联系
- Issues: GitHub Issues
- Pull Requests: GitHub PRs
- NPM: @sakitam-gis/sprite-cli
📜 更新日志
查看 CHANGELOG.md 了解版本更新历史。
