agent-robot-avatar 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +193 -33
- package/agent-robot-avatar.js +11 -1
- package/docs/README.de.md +22 -8
- package/docs/README.es.md +19 -11
- package/docs/README.fr.md +21 -11
- package/docs/README.ja.md +19 -11
- package/docs/README.ko.md +19 -11
- package/docs/README.pt.md +19 -11
- package/docs/README.zh-CN.md +202 -92
- package/docs/README.zh-TW.md +19 -11
- package/index.d.ts +30 -0
- package/package.json +3 -2
- package/src/agent-robot-avatar-actions.js +8 -2
- package/src/agent-robot-avatar-antenna.js +24 -45
- package/src/agent-robot-avatar-core.js +80 -17
- package/src/agent-robot-avatar-extension-host.js +6 -1
- package/src/agent-robot-avatar-failure.js +5 -1
- package/src/agent-robot-avatar-geometry.js +40 -0
- package/src/agent-robot-avatar-head-roundness.js +2 -35
- package/src/agent-robot-avatar-inspect.js +41 -30
- package/src/agent-robot-avatar-runtime-fixes.js +178 -0
- package/src/agent-robot-avatar-runtime.js +744 -0
- package/src/agent-robot-avatar-version.js +1 -1
package/docs/README.zh-CN.md
CHANGED
|
@@ -6,53 +6,53 @@
|
|
|
6
6
|
|
|
7
7
|
[English](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/README.md) | [简体中文](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.zh-CN.md) | [繁體中文](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.zh-TW.md) | [日本語](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.ja.md) | [한국어](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.ko.md) | [Español](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.es.md) | [Português](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.pt.md) | [Deutsch](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.de.md) | [Français](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.fr.md)
|
|
8
8
|
|
|
9
|
-
 [](../LICENSE) [](https://github.com/CX-ArtLab/agent-robot-avatar/actions/workflows/validate.yml) [](https://ko-fi.com/P0E625WIOI)
|
|
10
10
|
|
|
11
11
|
      
|
|
12
12
|
|
|
13
13
|
一个轻量、富有表现力的机器人头像 Web Component,可用于 AI Agent,也可用于其他需要交互反馈的应用。
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
适用于 AI 助手和 Agent 交互界面,也可用于桌面宠物、数字吉祥物、聊天机器人头像以及其他互动角色体验。
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Agent Robot Avatar 基于 SVG 与原生 JavaScript 构建,不依赖第三方动画框架,作为原生自定义元素工作,并提供尽量精简的公开 API。
|
|
18
|
+
|
|
19
|
+
**当前公开版本:v0.3.0**
|
|
18
20
|
|
|
19
21
|
<p align="center">
|
|
20
22
|
<img src="../assets/demo/agent-robot-avatar-demo.gif" alt="Agent Robot Avatar 交互动画演示" width="560">
|
|
21
23
|
</p>
|
|
22
24
|
|
|
25
|
+
## 在线演示
|
|
26
|
+
|
|
27
|
+
直接体验交互效果:[打开 Agent Robot Avatar 在线演示](https://cx-artlab.github.io/agent-robot-avatar/?lang=zh-CN)
|
|
28
|
+
|
|
23
29
|
## 主要特点
|
|
24
30
|
|
|
25
31
|
- 纯 SVG + 原生 JavaScript
|
|
26
32
|
- 原生 Web Component
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
- 鼠标 / 指针跟随与带惯性的头部运动
|
|
33
|
+
- 零运行时第三方依赖
|
|
34
|
+
- 自动眨眼、视线与头部跟随
|
|
30
35
|
- 局部果冻式拖拽形变与弹性回弹
|
|
31
|
-
-
|
|
32
|
-
-
|
|
36
|
+
- 程序控制的 Agent 状态与表情
|
|
37
|
+
- 独立的 `action-state` 语义动作生命周期事件
|
|
38
|
+
- `wake-on` 睡眠唤醒策略
|
|
39
|
+
- `motion` 减少动态效果支持
|
|
40
|
+
- 不可见时暂停持续绘制
|
|
33
41
|
- 可调整头部圆角
|
|
34
|
-
-
|
|
35
|
-
- Demo 界面与可复用组件本体分离
|
|
42
|
+
- 悬浮式天线与可选状态闪动
|
|
36
43
|
|
|
37
44
|
## 快速开始
|
|
38
45
|
|
|
39
|
-
直接使用仓库源码时,请保持根目录的 `agent-robot-avatar.js` 与 `src/`
|
|
46
|
+
直接使用仓库源码时,请保持根目录的 `agent-robot-avatar.js` 与 `src/` 目录一起使用:
|
|
40
47
|
|
|
41
48
|
```html
|
|
42
49
|
<script type="module" src="./agent-robot-avatar.js"></script>
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
在页面中加入:
|
|
46
|
-
|
|
47
|
-
```html
|
|
48
50
|
<agent-robot-avatar id="avatar"></agent-robot-avatar>
|
|
49
51
|
```
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
最小可运行示例位于 [`examples/basic.html`](../examples/basic.html)。
|
|
53
|
+
最小示例位于 [`examples/basic.html`](../examples/basic.html),无障碍语义状态示例位于 [`examples/accessibility.html`](../examples/accessibility.html)。
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
通过 npm:
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
58
|
npm install agent-robot-avatar
|
|
@@ -62,12 +62,10 @@ npm install agent-robot-avatar
|
|
|
62
62
|
import 'agent-robot-avatar';
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
npm 包内置 TypeScript
|
|
65
|
+
npm 包内置 TypeScript 类型声明。
|
|
66
66
|
|
|
67
67
|
## 基本 API
|
|
68
68
|
|
|
69
|
-
统一通过 `play()` 触发表情或状态:
|
|
70
|
-
|
|
71
69
|
```js
|
|
72
70
|
const avatar = document.querySelector('#avatar');
|
|
73
71
|
|
|
@@ -75,7 +73,7 @@ avatar.play('success');
|
|
|
75
73
|
avatar.play('failure');
|
|
76
74
|
avatar.play('warning');
|
|
77
75
|
avatar.play('inspect');
|
|
78
|
-
avatar.play('
|
|
76
|
+
avatar.play('blocked');
|
|
79
77
|
avatar.play('error');
|
|
80
78
|
```
|
|
81
79
|
|
|
@@ -85,6 +83,10 @@ avatar.play('error');
|
|
|
85
83
|
avatar.reset();
|
|
86
84
|
```
|
|
87
85
|
|
|
86
|
+
`reset()` 会统一取消当前程序动作、待完成计时、头部动画、拖拽/回弹和尚未触发的拖拽表情,然后回到 `idle`。被取消的动画 Promise 仍按原约定正常结束,不会因为取消而产生未处理拒绝。移除组件时会执行同类内部清理,但不会额外发送用于清理的 `face-state` 或 `action-state` 通知;重新挂载后从 `idle` 开始,并保留配置。
|
|
87
|
+
|
|
88
|
+
真正开始的新动作会替换旧动作;旧动作不能在之后恢复并覆盖新动作。未知动作会在破坏性清理前抛错。已经醒着时调用 `wake`、已经处于持续输入时再次调用 `input` 等无操作调用不会破坏当前动作,也不会产生虚假的语义生命周期事件。
|
|
89
|
+
|
|
88
90
|
## 状态与表情
|
|
89
91
|
|
|
90
92
|
| 状态 | API 名称 | 典型用途 |
|
|
@@ -95,64 +97,183 @@ avatar.reset();
|
|
|
95
97
|
| 输入中 | `input` | 用户正在输入 |
|
|
96
98
|
| 发送 | `send` | 内容已发送 / 点头反馈 |
|
|
97
99
|
| 成功 | `success` | 任务成功完成 |
|
|
98
|
-
| 失败 | `failure` |
|
|
99
|
-
| 警告确认 | `warning` |
|
|
100
|
+
| 失败 | `failure` | 任务完成但结果失败 |
|
|
101
|
+
| 警告确认 | `warning` | 高风险操作需要再次确认 |
|
|
100
102
|
| 审视 | `inspect` | 检查、核对或验证结果 |
|
|
101
|
-
| 内容阻止 | `
|
|
103
|
+
| 内容阻止 | `blocked` | 请求被阻止、不允许执行或无法继续 |
|
|
102
104
|
| 系统错误 | `error` | 网络、服务或系统本身发生错误 |
|
|
103
105
|
| 惊讶 | `surprise` | 出现意外事件或结果 |
|
|
104
|
-
| 睡眠 | `sleep` |
|
|
105
|
-
| 唤醒 | `wake` |
|
|
106
|
+
| 睡眠 | `sleep` | 组件进入睡眠姿态 |
|
|
107
|
+
| 唤醒 | `wake` | 从睡眠姿态恢复 |
|
|
106
108
|
|
|
107
|
-
|
|
109
|
+
`sleep` 只描述头像组件自身的状态,不表示真实 Agent 已离线。
|
|
108
110
|
|
|
109
|
-
|
|
111
|
+
语义别名:
|
|
110
112
|
|
|
111
113
|
```js
|
|
112
|
-
avatar.play('failed'); //
|
|
113
|
-
avatar.play('fail'); //
|
|
114
|
-
avatar.play('verify'); //
|
|
115
|
-
avatar.play('review'); //
|
|
116
|
-
avatar.play('
|
|
117
|
-
avatar.play('policy-blocked'); //
|
|
118
|
-
avatar.play('system-error'); //
|
|
119
|
-
avatar.play('connection-error'); //
|
|
114
|
+
avatar.play('failed'); // failure
|
|
115
|
+
avatar.play('fail'); // failure
|
|
116
|
+
avatar.play('verify'); // inspect
|
|
117
|
+
avatar.play('review'); // inspect
|
|
118
|
+
avatar.play('angry'); // 与 blocked 使用相同视觉表情
|
|
119
|
+
avatar.play('policy-blocked'); // blocked
|
|
120
|
+
avatar.play('system-error'); // error
|
|
121
|
+
avatar.play('connection-error'); // error
|
|
120
122
|
```
|
|
121
123
|
|
|
122
124
|
## 持续等待
|
|
123
125
|
|
|
124
|
-
在实际 Agent 流程中,请求发出后、结果返回前可以使用持续等待状态:
|
|
125
|
-
|
|
126
126
|
```js
|
|
127
127
|
avatar.startWaiting();
|
|
128
128
|
|
|
129
|
-
//
|
|
129
|
+
// 请求在没有被其他动作替换的情况下结束时:
|
|
130
130
|
avatar.stopWaiting();
|
|
131
131
|
```
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
`startWaiting()` 会一直保持到 `stopWaiting()`、`reset()` 或新的程序动作将其替换。`stopWaiting()` 对语义生命周期来说是正常 `end`;被其他动作或 reset 替换时是 `cancel`。
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
等待、输入或其他尚未结束的程序动作期间仍可以拖拽产生形变,但拖拽表情不会覆盖程序动作;被抑制的拖拽表情会直接丢弃,不会在动作结束后补播。
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
典型请求生命周期:
|
|
138
|
+
|
|
139
|
+
```js
|
|
140
|
+
avatar.startWaiting();
|
|
141
|
+
try {
|
|
142
|
+
const result = await runAgentRequest();
|
|
143
|
+
await avatar.play(result.ok ? 'success' : 'failure');
|
|
144
|
+
} catch (error) {
|
|
145
|
+
await avatar.play('error');
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`error` 动画播放完并回到 `idle`,只表示头像动画结束,不表示真实连接或业务错误已经解决。真实请求状态始终由宿主应用决定。
|
|
150
|
+
|
|
151
|
+
## `action-state` 语义动作事件
|
|
152
|
+
|
|
153
|
+
现有 `face-state` 保留兼容,它描述视觉状态,可能出现 `happy`、`sad` 等视觉词,不建议直接拿它判断真实任务结果。
|
|
154
|
+
|
|
155
|
+
新增 `action-state`:
|
|
156
|
+
|
|
157
|
+
```js
|
|
158
|
+
avatar.addEventListener('action-state', (event) => {
|
|
159
|
+
const { action, phase, source } = event.detail;
|
|
160
|
+
console.log(action, phase, source);
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
约定:
|
|
165
|
+
|
|
166
|
+
- `action`:规范化后的动作名;`failed` / `fail` → `failure`,`verify` / `review` → `inspect`。
|
|
167
|
+
- `phase`:`start`,之后且仅之后一个 `end` 或 `cancel`。
|
|
168
|
+
- `source`:`api`、`interaction`、`automatic`。
|
|
169
|
+
- 持续 waiting / input 不会因为单次视觉循环完成而产生 `end`。
|
|
170
|
+
- `stopWaiting()` 正常结束 waiting;reset 或其他动作替换时记录 `cancel`。
|
|
171
|
+
- 无操作调用不产生虚假事件。
|
|
172
|
+
- 普通拖拽反馈使用 `action: "reaction"`、`source: "interaction"`,不会被误认为 API 发出的任务成功/失败。
|
|
173
|
+
- 事件会冒泡,并设置为 `composed`,可跨越组件的 Shadow DOM 边界监听。
|
|
174
|
+
- 卸载只清理内部工作,不额外制造宿主播报事件。
|
|
175
|
+
|
|
176
|
+
## 无障碍接入
|
|
177
|
+
|
|
178
|
+
建议宿主根据 `action-state` 将程序动作映射为本地化文字,并使用普通的 `role="status"`:
|
|
179
|
+
|
|
180
|
+
```html
|
|
181
|
+
<div id="agent-status" role="status" aria-live="polite"></div>
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
```js
|
|
185
|
+
const status = document.querySelector('#agent-status');
|
|
186
|
+
const messages = {
|
|
187
|
+
waiting: '正在处理…',
|
|
188
|
+
failure: '任务失败。',
|
|
189
|
+
error: '连接异常。',
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
avatar.addEventListener('action-state', ({ detail }) => {
|
|
193
|
+
if (detail.source === 'interaction') return;
|
|
194
|
+
if (detail.phase === 'start' && messages[detail.action]) {
|
|
195
|
+
status.textContent = messages[detail.action];
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
不要播报眨眼、视线变化或普通拖拽反应;也不要默认把所有错误都做成打断式警报。如果宿主本身已经播报同一状态,可以把头像视为装饰,避免重复通知。
|
|
201
|
+
|
|
202
|
+
完整示例见 [`examples/accessibility.html`](../examples/accessibility.html)。
|
|
203
|
+
|
|
204
|
+
## 睡眠唤醒策略
|
|
205
|
+
|
|
206
|
+
新增属性:
|
|
207
|
+
|
|
208
|
+
```html
|
|
209
|
+
<agent-robot-avatar wake-on="manual"></agent-robot-avatar>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
| 值 | 行为 |
|
|
213
|
+
| --- | --- |
|
|
214
|
+
| `activity` | 默认值;保留原行为,页面指针/键盘活动可以自动唤醒头像。 |
|
|
215
|
+
| `interaction` | 只有直接与这个头像交互时自动唤醒;页面其他区域活动不唤醒。 |
|
|
216
|
+
| `manual` | 页面活动和头像交互都不会自动唤醒,由宿主显式控制。 |
|
|
217
|
+
|
|
218
|
+
显式调用仍保持显式语义:`avatar.play('wake')` 在所有模式下都可唤醒;现有 `avatar.noteActivity()` 仍默认记录活动并唤醒,`noteActivity(false)` 只记录活动、不唤醒。其他程序动作可以按照动作语义离开睡眠;`reset()` 始终回到 `idle`。不同实例可以使用不同策略。
|
|
219
|
+
|
|
220
|
+
## 减少动态效果
|
|
221
|
+
|
|
222
|
+
新增:
|
|
223
|
+
|
|
224
|
+
```html
|
|
225
|
+
<agent-robot-avatar motion="auto"></agent-robot-avatar>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
| 值 | 行为 |
|
|
229
|
+
| --- | --- |
|
|
230
|
+
| `auto` | 默认;遵循系统 `prefers-reduced-motion`,并响应运行期间的偏好变化。 |
|
|
231
|
+
| `reduce` | 保留可辨认的静态状态,减少持续、弹性和闪烁类动画。 |
|
|
232
|
+
| `full` | 始终使用普通动画,不受系统减少动态效果偏好影响。 |
|
|
233
|
+
|
|
234
|
+
reduce 模式会简化等待转圈、待机游走/眨眼、惯性跟随、弹性回弹、天线弹簧和闪烁等装饰动态,但 waiting / input 等语义生命周期仍持续存在,直到宿主结束或替换。切换 motion 不会恢复已经被取消的旧动作,也不会改变 `action-state` 的语义。
|
|
235
|
+
|
|
236
|
+
## 鼠标 / 指针跟随
|
|
138
237
|
|
|
139
238
|
```js
|
|
140
239
|
avatar.setPointerFollow(false);
|
|
141
240
|
avatar.setPointerFollow(true);
|
|
142
241
|
```
|
|
143
242
|
|
|
144
|
-
|
|
243
|
+
高频指针更新会合并为每个动画帧最多处理最新位置一次,普通模式下的视线跟随保持不变。
|
|
145
244
|
|
|
146
|
-
|
|
245
|
+
## 移动端拖拽
|
|
246
|
+
|
|
247
|
+
头像交互区域使用 `touch-action: pinch-zoom`:单指移动交给头像拖拽逻辑,同时保留双指缩放能力;从头像外部开始的页面滚动仍按页面正常手势处理。
|
|
248
|
+
|
|
249
|
+
`pointercancel`、指针捕获丢失、reset、动作替换或卸载都会恢复形状,并且不会把手势取消误判成 `success` / `angry`。
|
|
250
|
+
|
|
251
|
+
## 天线闪动
|
|
147
252
|
|
|
148
253
|
```js
|
|
149
254
|
avatar.setAntennaFlash(true);
|
|
150
255
|
avatar.setAntennaFlash(false);
|
|
151
256
|
```
|
|
152
257
|
|
|
153
|
-
|
|
258
|
+
状态闪动默认关闭;reduce 模式会停止不必要的持续闪烁。
|
|
259
|
+
|
|
260
|
+
## 审视表情配置
|
|
261
|
+
|
|
262
|
+
可以在加载组件前配置:
|
|
263
|
+
|
|
264
|
+
```html
|
|
265
|
+
<script>
|
|
266
|
+
window.AgentRobotAvatarInspectConfig = {
|
|
267
|
+
aperture: 24,
|
|
268
|
+
scanOffset: 12,
|
|
269
|
+
};
|
|
270
|
+
</script>
|
|
271
|
+
<script type="module" src="./agent-robot-avatar.js"></script>
|
|
272
|
+
```
|
|
154
273
|
|
|
155
|
-
|
|
274
|
+
加载前已经提供的有效值会被保留,只对缺失或无效项补默认值。配置通过 `Number(...)` 转换并要求有限值;`aperture` 限制在 `6–40`,`scanOffset` 限制在 `0–24`,时间参数限制在对应的 `0/40–2400 ms` 范围。加载后仍可修改同一个 `window.AgentRobotAvatarInspectConfig` 对象,每次开始 inspect 时会再次规范化。默认配置的视觉效果保持不变。
|
|
275
|
+
|
|
276
|
+
## 头部圆角
|
|
156
277
|
|
|
157
278
|
```js
|
|
158
279
|
avatar.setHeadRoundness(0); // 更方
|
|
@@ -162,9 +283,9 @@ avatar.setHeadRoundness(100); // 更圆
|
|
|
162
283
|
console.log(avatar.getHeadRoundness());
|
|
163
284
|
```
|
|
164
285
|
|
|
165
|
-
|
|
286
|
+
输入值限制在 `0–100`。天线模块和圆角模块现在复用同一套头部扁平化几何计算,避免默认形状出现实现偏差。
|
|
166
287
|
|
|
167
|
-
|
|
288
|
+
`head-roundness-change`:
|
|
168
289
|
|
|
169
290
|
```js
|
|
170
291
|
avatar.addEventListener('head-roundness-change', (event) => {
|
|
@@ -172,9 +293,7 @@ avatar.addEventListener('head-roundness-change', (event) => {
|
|
|
172
293
|
});
|
|
173
294
|
```
|
|
174
295
|
|
|
175
|
-
##
|
|
176
|
-
|
|
177
|
-
视觉状态发生变化时,组件会触发 `face-state` 事件:
|
|
296
|
+
## `face-state` 视觉事件
|
|
178
297
|
|
|
179
298
|
```js
|
|
180
299
|
avatar.addEventListener('face-state', (event) => {
|
|
@@ -182,60 +301,51 @@ avatar.addEventListener('face-state', (event) => {
|
|
|
182
301
|
});
|
|
183
302
|
```
|
|
184
303
|
|
|
185
|
-
|
|
304
|
+
该事件继续用于视觉同步和旧接入;涉及真实 Agent 生命周期和无障碍播报时优先使用 `action-state`。
|
|
186
305
|
|
|
187
306
|
## 基础属性
|
|
188
307
|
|
|
189
308
|
```html
|
|
190
309
|
<agent-robot-avatar
|
|
191
|
-
size="
|
|
310
|
+
size="160px"
|
|
192
311
|
color="#08090b"
|
|
193
|
-
auto-sleep="30000"
|
|
312
|
+
auto-sleep="30000"
|
|
313
|
+
wake-on="activity"
|
|
314
|
+
motion="auto">
|
|
194
315
|
</agent-robot-avatar>
|
|
195
316
|
```
|
|
196
317
|
|
|
197
318
|
| 属性 | 说明 |
|
|
198
319
|
| --- | --- |
|
|
199
|
-
| `size` |
|
|
200
|
-
| `color` |
|
|
201
|
-
| `auto-sleep` |
|
|
320
|
+
| `size` | 正像素尺寸;支持 `140` 和 `140px`。不支持的单位、非法字符串、0、负数和非有限值统一回退到 `112px`。 |
|
|
321
|
+
| `color` | 头像主色。 |
|
|
322
|
+
| `auto-sleep` | 无操作后自动睡眠的毫秒数;`0` 关闭。 |
|
|
323
|
+
| `wake-on` | `activity`(默认)、`interaction`、`manual`。 |
|
|
324
|
+
| `motion` | `auto`(默认)、`reduce`、`full`。 |
|
|
202
325
|
|
|
203
|
-
|
|
326
|
+
动态修改尺寸后,拖拽坐标和指针跟随会使用当前实际布局尺寸。
|
|
204
327
|
|
|
205
328
|
## 默认行为
|
|
206
329
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
- 随机眨眼
|
|
210
|
-
- 轻微随机视线移动
|
|
211
|
-
- 鼠标靠近时自然跟随
|
|
212
|
-
- 头部带惯性的轻微运动
|
|
213
|
-
- 自然恢复默认待机
|
|
214
|
-
- 可选自动睡眠
|
|
330
|
+
普通模式下继续保留随机眨眼、轻微视线活动、指针跟随、头部惯性和自然回待机等既有风格。开启 reduce 后会简化这些装饰动作。
|
|
215
331
|
|
|
216
332
|
## 拖拽交互
|
|
217
333
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
-
|
|
221
|
-
-
|
|
222
|
-
-
|
|
334
|
+
- 空闲状态大幅向外拉:恢复后触发 `angry` 视觉反馈
|
|
335
|
+
- 空闲状态大幅向中心挤压:恢复后触发 `success` 视觉反馈
|
|
336
|
+
- 小幅拖动:只产生形变
|
|
337
|
+
- 程序动作活跃时:可以形变,但拖拽表情不覆盖程序动作
|
|
338
|
+
- reset / 新动作 / pointercancel / 丢失捕获 / 卸载:统一取消旧拖拽后续反应
|
|
223
339
|
|
|
224
|
-
|
|
340
|
+
## 不可见暂停与性能
|
|
225
341
|
|
|
226
|
-
|
|
342
|
+
组件在自身或父容器没有可见布局区域、或离开视口后暂停持续帧绘制;重新可见时按当前有效状态恢复,不补播已经失效的动作。有限动作的计时和 Promise 不依赖持续绘制,因此不会因为不可见而无限挂起。
|
|
227
343
|
|
|
228
|
-
|
|
344
|
+
指针移动按动画帧合并,只处理每帧最新位置。现有页面隐藏和稳定 sleep 暂停机制继续保留;实例卸载时会清理观察器与媒体查询监听。
|
|
229
345
|
|
|
230
|
-
|
|
231
|
-
- 鼠标跟随
|
|
232
|
-
- 果冻式拖拽形变
|
|
233
|
-
- 等待状态生命周期
|
|
234
|
-
- 头部圆角三档预设与连续调节
|
|
235
|
-
- 颜色与行为控制
|
|
236
|
-
- 模拟 Agent 对话状态
|
|
346
|
+
## 交互 Demo
|
|
237
347
|
|
|
238
|
-
|
|
348
|
+
`demo/index.html` 是完整交互 Demo,包含全部公开表情、指针跟随、拖拽形变、等待生命周期、圆角、颜色与模拟 Agent 对话状态。Demo 专用 JavaScript 与 npm 运行时保持分离。
|
|
239
349
|
|
|
240
350
|
## 项目结构
|
|
241
351
|
|
|
@@ -243,7 +353,7 @@ avatar.addEventListener('face-state', (event) => {
|
|
|
243
353
|
agent-robot-avatar.js 正式组件入口
|
|
244
354
|
src/ 可复用组件运行时与表情模块
|
|
245
355
|
demo/ 完整交互 Demo 与 Demo 专用辅助脚本
|
|
246
|
-
examples/
|
|
356
|
+
examples/ 最小集成与无障碍示例
|
|
247
357
|
assets/support/ 支持项目 / 支付二维码素材
|
|
248
358
|
docs/ 多语言文档
|
|
249
359
|
README.md 英文主文档
|
|
@@ -255,13 +365,13 @@ LICENSE MIT License
|
|
|
255
365
|
|
|
256
366
|
## 分发
|
|
257
367
|
|
|
258
|
-
|
|
368
|
+
软件包以 `agent-robot-avatar` 名称发布到 npm。npm 包包含公开入口、TypeScript 类型声明、`src/` 运行时、文档和支持项目素材;Demo 专用文件和测试文件不会进入运行时包。
|
|
259
369
|
|
|
260
|
-
|
|
370
|
+
## 兼容性与验证
|
|
261
371
|
|
|
262
|
-
|
|
372
|
+
面向支持 ES Modules、Custom Elements、SVG、Pointer Events、Web Animations API、`IntersectionObserver`、`ResizeObserver` 和 `matchMedia` 的现代浏览器。
|
|
263
373
|
|
|
264
|
-
|
|
374
|
+
自动浏览器测试覆盖 Chromium、Firefox 和 WebKit;移动端拖拽取消另外使用 Chromium 可信触摸模拟验证。真实手机是否验证以对应 PR / 发布说明为准。
|
|
265
375
|
|
|
266
376
|
## 参与贡献
|
|
267
377
|
|
|
@@ -269,7 +379,7 @@ Agent Robot Avatar 面向支持 ES Modules、Custom Elements、SVG、Pointer Eve
|
|
|
269
379
|
|
|
270
380
|
## 项目状态
|
|
271
381
|
|
|
272
|
-
v0.
|
|
382
|
+
v0.3.0 是当前公开版本。当前刻意保持较小的公开 API,以便在未来 `1.0.0` 稳定性承诺之前继续谨慎演进。
|
|
273
383
|
|
|
274
384
|
Agent Robot Avatar 为独立开发的开源项目,不隶属于、代表或获得任何 AI 平台或品牌的官方背书。
|
|
275
385
|
|
|
@@ -279,7 +389,7 @@ MIT License。详见 [`LICENSE`](../LICENSE)。
|
|
|
279
389
|
|
|
280
390
|
## 请我喝杯咖啡
|
|
281
391
|
|
|
282
|
-
|
|
392
|
+
如果这个项目对你有帮助,也可以请我喝杯咖啡:
|
|
283
393
|
|
|
284
394
|
| Ko-fi | 支付宝 | 微信支付 |
|
|
285
395
|
| --- | --- | --- |
|
package/docs/README.zh-TW.md
CHANGED
|
@@ -6,20 +6,30 @@
|
|
|
6
6
|
|
|
7
7
|
[English](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/README.md) | [简体中文](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.zh-CN.md) | [繁體中文](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.zh-TW.md) | [日本語](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.ja.md) | [한국어](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.ko.md) | [Español](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.es.md) | [Português](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.pt.md) | [Deutsch](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.de.md) | [Français](https://github.com/CX-ArtLab/agent-robot-avatar/blob/main/docs/README.fr.md)
|
|
8
8
|
|
|
9
|
-
 [](../LICENSE) [](https://github.com/CX-ArtLab/agent-robot-avatar/actions/workflows/validate.yml) [](https://ko-fi.com/P0E625WIOI)
|
|
10
10
|
|
|
11
11
|
      
|
|
12
12
|
|
|
13
13
|
一個輕量、富有表現力的機器人頭像 Web Component,可用於 AI Agent,也可用於其他需要互動回饋的應用。
|
|
14
14
|
|
|
15
|
+
適用於 AI 助理與 Agent 互動介面,包括與 ChatGPT、Claude、Codex、Cursor、Grok Bot、Gemini CLI 和 OpenCode 類似的產品與使用情境。
|
|
16
|
+
|
|
17
|
+
也可用於桌面寵物、虛擬寵物、桌面夥伴、數位吉祥物、聊天機器人頭像,以及其他互動角色體驗。
|
|
18
|
+
|
|
19
|
+
Agent Robot Avatar 也可作為 AG-UI 類 Agent 介面的視覺回饋層。
|
|
20
|
+
|
|
15
21
|
Agent Robot Avatar 以 SVG 與原生 JavaScript 建構,不依賴第三方動畫框架。它作為原生自訂元素運作,並提供精簡 API 來控制表情、互動狀態、指標跟隨、等待回饋與頭部造型。
|
|
16
22
|
|
|
17
|
-
**目前公開版本:v0.
|
|
23
|
+
**目前公開版本:v0.3.0**
|
|
18
24
|
|
|
19
25
|
<p align="center">
|
|
20
26
|
<img src="../assets/demo/agent-robot-avatar-demo.gif" alt="Agent Robot Avatar 互動動畫展示" width="560">
|
|
21
27
|
</p>
|
|
22
28
|
|
|
29
|
+
## 線上展示
|
|
30
|
+
|
|
31
|
+
直接體驗互動效果:[開啟 Agent Robot Avatar 線上展示](https://cx-artlab.github.io/agent-robot-avatar/?lang=zh-TW)
|
|
32
|
+
|
|
23
33
|
## 主要特色
|
|
24
34
|
|
|
25
35
|
- 純 SVG + 原生 JavaScript
|
|
@@ -59,7 +69,7 @@ avatar.play('success');
|
|
|
59
69
|
avatar.play('failure');
|
|
60
70
|
avatar.play('warning');
|
|
61
71
|
avatar.play('inspect');
|
|
62
|
-
avatar.play('
|
|
72
|
+
avatar.play('blocked');
|
|
63
73
|
avatar.play('error');
|
|
64
74
|
|
|
65
75
|
avatar.reset();
|
|
@@ -78,7 +88,7 @@ avatar.reset();
|
|
|
78
88
|
| 失敗 | `failure` | 任務完成,但結果失敗 |
|
|
79
89
|
| 警告確認 | `warning` | 高風險或破壞性操作需要確認 |
|
|
80
90
|
| 審視 | `inspect` | 檢查、核對或驗證結果 |
|
|
81
|
-
| 內容阻止 | `
|
|
91
|
+
| 內容阻止 | `blocked` | 請求被阻止、不允許或無法繼續 |
|
|
82
92
|
| 系統錯誤 | `error` | 連線、服務或系統錯誤 |
|
|
83
93
|
| 驚訝 | `surprise` | 意外事件或結果 |
|
|
84
94
|
| 睡眠 | `sleep` | 進入睡眠 |
|
|
@@ -93,7 +103,7 @@ avatar.play('failed');
|
|
|
93
103
|
avatar.play('fail');
|
|
94
104
|
avatar.play('verify');
|
|
95
105
|
avatar.play('review');
|
|
96
|
-
avatar.play('
|
|
106
|
+
avatar.play('angry'); // 與 blocked 使用相同表情
|
|
97
107
|
avatar.play('policy-blocked');
|
|
98
108
|
avatar.play('system-error');
|
|
99
109
|
avatar.play('connection-error');
|
|
@@ -172,6 +182,8 @@ avatar.addEventListener('face-state', (event) => {
|
|
|
172
182
|
- 強力向中心推:回彈後觸發 `success`
|
|
173
183
|
- 小幅拖曳:只變形,不觸發表情
|
|
174
184
|
|
|
185
|
+
上述拖曳表情只會在沒有程式控制動作佔用頭像的 idle 狀態生效。`waiting`、`input`、`inspect` 等動作執行期間仍保留拖曳形變,但拖曳表情會被抑制且不會延後補播;`pointercancel` 只恢復形狀,不會觸發成功或生氣表情。
|
|
186
|
+
|
|
175
187
|
## 互動 Demo
|
|
176
188
|
|
|
177
189
|
`demo/index.html` 包含全部公開表情、指標跟隨、果凍拖曳、等待生命週期、頭部圓角調整、顏色 / 行為控制,以及模擬 Agent 對話。Demo 專用 JavaScript 全部集中在 `demo/`,不會進入可重複使用的 npm runtime。
|
|
@@ -202,7 +214,7 @@ LICENSE MIT License
|
|
|
202
214
|
|
|
203
215
|
## 專案狀態
|
|
204
216
|
|
|
205
|
-
v0.1.0
|
|
217
|
+
v0.3.0 是目前的公開版本。v0.1.0 作為第一個公開版本繼續保留。公開 API 目前刻意保持精簡,讓專案能在未來 `1.0.0` 穩定性承諾前持續謹慎演進。
|
|
206
218
|
|
|
207
219
|
Agent Robot Avatar 是獨立開發的開源專案,不隸屬、代表或獲得任何 AI 平台或品牌的官方背書。
|
|
208
220
|
|
|
@@ -212,8 +224,4 @@ MIT License。詳見 [`LICENSE`](../LICENSE)。
|
|
|
212
224
|
|
|
213
225
|
## 請我喝杯咖啡
|
|
214
226
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
| Ko-fi | 支付寶 | 微信支付 |
|
|
218
|
-
| --- | --- | --- |
|
|
219
|
-
| <a href='https://ko-fi.com/P0E625WIOI' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://storage.ko-fi.com/cdn/kofi6.png?v=6' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a> | <img src="../assets/support/alipay.png" alt="支付寶收款碼" width="160"> | <img src="../assets/support/wechat-pay.png" alt="微信支付收款碼" width="160"> |
|
|
227
|
+
<a href='https://ko-fi.com/P0E625WIOI' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://storage.ko-fi.com/cdn/kofi6.png?v=6' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
|
package/index.d.ts
CHANGED
|
@@ -38,8 +38,38 @@ export type AgentRobotAvatarState =
|
|
|
38
38
|
| 'inspect'
|
|
39
39
|
| 'failure';
|
|
40
40
|
|
|
41
|
+
export type AgentRobotAvatarCanonicalAction =
|
|
42
|
+
| 'idle'
|
|
43
|
+
| 'bored'
|
|
44
|
+
| 'waiting'
|
|
45
|
+
| 'input'
|
|
46
|
+
| 'send'
|
|
47
|
+
| 'success'
|
|
48
|
+
| 'failure'
|
|
49
|
+
| 'warning'
|
|
50
|
+
| 'inspect'
|
|
51
|
+
| 'angry'
|
|
52
|
+
| 'blocked'
|
|
53
|
+
| 'error'
|
|
54
|
+
| 'surprise'
|
|
55
|
+
| 'sleep'
|
|
56
|
+
| 'wake'
|
|
57
|
+
| 'reaction';
|
|
58
|
+
|
|
59
|
+
export type AgentRobotAvatarActionPhase = 'start' | 'end' | 'cancel';
|
|
60
|
+
export type AgentRobotAvatarActionSource = 'api' | 'interaction' | 'automatic';
|
|
61
|
+
export type AgentRobotAvatarWakeOn = 'activity' | 'interaction' | 'manual';
|
|
62
|
+
export type AgentRobotAvatarMotion = 'auto' | 'reduce' | 'full';
|
|
63
|
+
|
|
64
|
+
export interface AgentRobotAvatarActionStateDetail {
|
|
65
|
+
action: AgentRobotAvatarCanonicalAction;
|
|
66
|
+
phase: AgentRobotAvatarActionPhase;
|
|
67
|
+
source: AgentRobotAvatarActionSource;
|
|
68
|
+
}
|
|
69
|
+
|
|
41
70
|
export interface AgentRobotAvatarEventMap extends HTMLElementEventMap {
|
|
42
71
|
'face-state': CustomEvent<{ state: AgentRobotAvatarState }>;
|
|
72
|
+
'action-state': CustomEvent<AgentRobotAvatarActionStateDetail>;
|
|
43
73
|
'head-roundness-change': CustomEvent<{ value: number; version: string }>;
|
|
44
74
|
}
|
|
45
75
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-robot-avatar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A lightweight expressive robot avatar Web Component for AI agents and interactive applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./agent-robot-avatar.js",
|
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
"sideEffects": true,
|
|
20
20
|
"scripts": {
|
|
21
21
|
"dev": "node scripts/serve.mjs",
|
|
22
|
+
"build:pages": "node scripts/build-pages.mjs",
|
|
22
23
|
"check": "node scripts/check-source.mjs",
|
|
23
|
-
"test": "npm run check && npm run test:types && npm run test:release && npm run test:package && npm run test:browser",
|
|
24
|
+
"test": "npm run check && npm run test:types && npm run test:release && npm run test:package && npm run test:browser && npm run build:pages",
|
|
24
25
|
"release:check": "npm test && npm publish --dry-run --ignore-scripts --tag latest",
|
|
25
26
|
"prepublishOnly": "npm test && node scripts/check-publish-tag.mjs",
|
|
26
27
|
"test:types": "tsc -p tsconfig.types.json",
|
|
@@ -204,13 +204,16 @@ proto.error = async function() {
|
|
|
204
204
|
|
|
205
205
|
centerHeadTransform(this);
|
|
206
206
|
if (this._headMotion?.animate) {
|
|
207
|
+
const animationToken = this._transitionToken;
|
|
207
208
|
const anim = this._headMotion.animate([
|
|
208
209
|
{ transform: 'translateX(0px)', offset: 0, easing: 'cubic-bezier(.38,0,.28,1)' },
|
|
209
210
|
{ transform: 'translateX(-4px)', offset: 0.34, easing: 'cubic-bezier(.35,0,.22,1)' },
|
|
210
211
|
{ transform: 'translateX(4px)', offset: 0.72, easing: 'cubic-bezier(.35,0,.22,1)' },
|
|
211
212
|
{ transform: 'translateX(0px)', offset: 1 }
|
|
212
213
|
], { duration: headDuration, easing: 'linear', fill: 'forwards' });
|
|
213
|
-
anim.onfinish = () => {
|
|
214
|
+
anim.onfinish = () => {
|
|
215
|
+
if (animationToken === this._transitionToken) this._headMotion.style.transform = 'translateX(0px)';
|
|
216
|
+
};
|
|
214
217
|
}
|
|
215
218
|
|
|
216
219
|
await this._wait(headDuration + 40);
|
|
@@ -235,6 +238,7 @@ proto.warning = async function() {
|
|
|
235
238
|
|
|
236
239
|
centerHeadTransform(this);
|
|
237
240
|
if (this._headMotion?.animate) {
|
|
241
|
+
const animationToken = this._transitionToken;
|
|
238
242
|
const anim = this._headMotion.animate([
|
|
239
243
|
{ transform: 'translateY(0px)', offset: 0 },
|
|
240
244
|
{ transform: 'translateY(0px)', offset: WARNING_PHASES.w5Start / duration, easing: 'cubic-bezier(.38,0,.25,1)' },
|
|
@@ -245,7 +249,9 @@ proto.warning = async function() {
|
|
|
245
249
|
{ transform: 'translateY(0px)', offset: WARNING_PHASES.w7End / duration },
|
|
246
250
|
{ transform: 'translateY(0px)', offset: 1 }
|
|
247
251
|
], { duration, easing: 'linear', fill: 'forwards' });
|
|
248
|
-
anim.onfinish = () => {
|
|
252
|
+
anim.onfinish = () => {
|
|
253
|
+
if (animationToken === this._transitionToken) this._headMotion.style.transform = 'translateY(0px)';
|
|
254
|
+
};
|
|
249
255
|
}
|
|
250
256
|
|
|
251
257
|
await this._wait(duration + 40);
|