Skip to main content

ice-web-components · Canvas 原生 UI 组件库(当前 v1.19.1)

🧩 应用层 · 基于 ice-render 引擎 v2.14.1 封装(当前 v1.19.1)

本页属于 ice-render 家族的应用层产品:所有 UI 像素都由引擎绘制,组件库只在其上收敛出 Swing 风格 Canvas 组件 API。想了解底层引擎本身,请看左侧「ice-render 引擎」分组。

ice-web-components 是构建在 ice-render 引擎之上的 Swing 风格 Canvas UI 组件库(当前 ice-web-components v1.19.1)。 它把所有 UI 像素——按钮、输入框、表格、弹窗、乃至焦点环与阴影——全部画在一个 <canvas>:没有 DOM widget,没有 CSS 框架,每一像素都由引擎绘制。

组件库直接采用 Bootstrap 5 的设计令牌(调色板、--bs-border-radius、字体等),并自带一套深色主题,换肤只需一次调用。目前落地 84 个 UI 组件类(另有 20 个纯逻辑模型、5 个管理器、2 个基类,合计 111 个导出类),覆盖按钮 / 输入 / 选择 / 表格 / 树 / 菜单 / 模态 / 抽屉 / 通知 / 上传 / 日期时间 / 级联 / 穿梭 / 轮播 / 取色等。

MIT License · 作者:大漠穷秋(damoqiongqiu@126.com

⚠️ Just for fun:作者明确说明这是出于探索与乐趣的项目,并非生产级、经实战检验的 UI 库。但它有真实测试——1348 个单元测试(190 个套件)外加 8 个浏览器 QA 套件(303 条断言,用真实鼠标 / 键盘事件驱动 demo 页,任何 console 错误都会让 QA 失败),另有一条示例页冒烟(9 个合成页,逐页断言无 console/pageerror 且画布内容像素占比达标)。

一个完整的实时例子(就是仓库里的 examples/gallery.html

下面这个例子直接由文档静态托管的 ice-render + ice-web-components UMD 运行时在文档页里画出(无需联网):84 个组件在一张画布上逐个排布,按钮点击、输入框、下拉、表格、弹窗、通知等交互全部可用。

趣味示例(Just for fun)

下面这些都是用 ice-web-components 写的完整小应用,同样由打包好的运行时在文档页里直接画出(鼠标、键盘全部可用,运行时从本站静态托管加载,无需联网)。它们最能体现「一个 canvas 上能画出多好玩的东西」:

📐 这些 demo 的画布比文档栏更宽,容器内会出现横向滚动条——把框往右拖就能看到完整画面(鼠标 / 键盘交互始终准确,因为引擎按 CSS 像素做坐标映射,不做缩放)。

🖥️ ICE Desktop · Windows XP

纯 ICE 组件复刻的 XP 桌面:开机自检 → 启动菜单 → 桌面 + 任务栏 + 开始菜单 + 可拖拽窗口。它顺便演示了组件库的主题系统(iceUIManager.registerTheme('xp', ICE_XP_THEME)),一套令牌切出整台机器的皮肤。

🎨 局部主题作用域

一块画布里分区用不同主题:左边跟随页面主题,右边用 theme: themeScope('dark') 固定深色。两块面板里放的是同一组组件(按钮 / 头像 / 骨架屏 / 列表)——连 painter 画出来的骨架屏与列表行也跟着作用域走。切页面主题时,只有左边那块变。

🎮 ICE Arcade

一台纯组件绘制的掌机,卡带即插即换:2048 / 贪吃蛇 / 俄罗斯方块 / 扫雷。游戏规则全部落在纯逻辑模型里(各自有单测),画面里没有一个位图资源——机壳、屏幕框、HUD、按键全是 ICE 组件。

🎨 ICE Pixel Studio

像素画板:铅笔 / 橡皮 / 直线 / 矩形 / 油漆桶,撤销重做 + PNG / SVG 导出,全部由 canvas 组件绘制。

🧪 ICE Algorithm Sandbox

算法可视化:排序(冒泡 / 插入 / 选择 / 归并 / 快速)+ 寻路(BFS / DFS / Dijkstra / A*),可播放、单步、倒带、变速,回放每一步的轨迹。

💻 ICE-DOS Terminal

一个能敲的 DOS 终端:虚拟文件系统 + 16 条命令 + 历史记录 / TAB 补全 / 清屏,逻辑全在纯模型里(点一下框内、直接用键盘 input)。

🗂️ ICE Admin · 管理后台

🧰 ICE Workbench · 工作台

🧩 ICE Custom Component · 自定义组件

核心能力

能力说明
84 个 UI 组件类按钮 / 输入 / 选择 / 表格 / 树 / 菜单 / 模态 / 抽屉 / 通知 / 上传 / 日期时间 / 级联 / 穿梭 / 轮播 / 取色,以及标签、徽标、头像、骨架、加载等小件
统一的浮层栈Modal / Drawer / Dropdown / Tooltip / Popover / Popconfirm / Select / DatePicker / Cascader 全部走 ICEOverlayManager:12 种 Placement、自动翻转 + 夹紧到可视区、Esc / 点击外部关闭、焦点陷阱、进退场动画
表单同步 + 异步校验ICEFormModel(required / min / max / length / pattern / custom / asyncValidator),ICEFormItem 展示错误与「校验中」态,submitAsync() 等待异步规则
键盘与焦点Tab / Shift+Tab 轮换、Enter/Space 激活、方向键驱动滑块 / 菜单 / 标签页 / 评分;焦点环绘制在所有内容之上
主题Bootstrap 5 令牌主题(含深色主题),一次调用换肤
与引擎无命名冲突运行时导出与 ice-render 互不相交(有专门的回归测试守护)
真实测试1348 单测(190 套件)+ 8 个浏览器 QA 套件(303 断言,真实键鼠驱动 demo 页,console 报错即失败)+ 示例页冒烟(9 页)
1.5.3 一个值得注意的点
  • 日历首日 weekStart 按语言推导 + 显式覆盖ICEDatePicker / ICECalendar 的周首日默认由 props.locale 推导(如中文环境从周一开始),传入 weekStart(0 = 周日 … 6 = 周六)即强制覆盖——国际化场景下无需手动算偏移。

快速开始

安装

# 组件库会自动拉入 ice-render 作为依赖
npm install ice-web-components

在浏览器里(无构建,UMD 全局 ICEWEB

注意引擎要先于组件库引入

<canvas id="canvas" width="900" height="600"></canvas>
<script src="./ice-render.umd.js"></script>
<script src="./ice-web-components.umd.js"></script>
<script>
const ice = new ICEWEB.ICE().init('canvas');
new ICEWEB.ICEHoverManager(ice).start(); // canvas 无原生 hover:显式开启
ICEWEB.getICEFocusManager(ice).start(); // Tab / Enter / Esc 处理

const panel = new ICEWEB.ICEPanel({ left: 24, top: 24, width: 372, height: 192 });
panel.addChild(new ICEWEB.ICELabel({ left: 24, top: 20, text: 'Quick start' }));

const button = new ICEWEB.ICEButton({ left: 24, top: 64, width: 140, text: 'Click me' });
const hint = new ICEWEB.ICELabel({ left: 24, top: 112, text: 'clicked 0 times' });
let count = 0;
button.on('click', () => {
count += 1;
hint.setText(`clicked ${count} times`);
ICEWEB.ICEMessage.success(ice, `clicked ${count} times`);
});

panel.addChildren([button, hint]);
ice.addChild(panel);
</script>

在打包工程里(ES Module)

import { ICE } from 'ice-render';
import {
ICEButton,
ICEHoverManager,
ICELabel,
ICEMessage,
ICEPanel,
getICEFocusManager,
} from 'ice-web-components';

const ice = new ICE().init('canvas');
new ICEHoverManager(ice).start();
getICEFocusManager(ice).start();

const panel = new ICEPanel({ left: 24, top: 24, width: 372, height: 192 });
panel.addChild(new ICELabel({ left: 24, top: 20, text: 'Quick start' }));

const button = new ICEButton({ left: 24, top: 64, width: 140, text: 'Click me' });
button.on('click', () => ICEMessage.success(ice, 'clicked!'));
panel.addChild(button);
ice.addChild(panel);
表单有配套的 JSON-first DSL

与 ice-render / ice-entity-designer / ice-chart 不同,ice-web-components 的组件 API 本身是命令式的(new ICEButton(...) / new ICEPanel(...) 这类)——AI Agent 要直接拼装组件树。但表单场景已经有配套的 JSON-first DSL:ice-web-components-dsl 用一份扁平 fields[] 编译出 ICEForm / ICEFormItem / 控件,约束(夹取 + 校验)与结构化诊断都由它兜底,Agent 不必手写三层构造。如果你的场景想用 DSL 驱动 UI、又不在表单范畴,仍需要在 Agent 侧把「意图 → 组件树」这层自己写掉。

相关链接