@eva/plugin-a11y 2.0.1-beta.3 → 2.0.1-beta.31
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/dist/plugin-a11y.cjs.js +184 -0
- package/dist/plugin-a11y.d.ts +182 -0
- package/dist/plugin-a11y.esm.js +184 -0
- package/package.json +3 -3
package/dist/plugin-a11y.cjs.js
CHANGED
|
@@ -37,6 +37,11 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* 生成唯一的标识符
|
|
42
|
+
* @param len 长度
|
|
43
|
+
* @param radix 基
|
|
44
|
+
*/
|
|
40
45
|
function uuid(len) {
|
|
41
46
|
let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
|
|
42
47
|
let uuid = [];
|
|
@@ -45,6 +50,11 @@ function uuid(len) {
|
|
|
45
50
|
uuid[i] = chars[0 | (Math.random() * radix)];
|
|
46
51
|
return uuid.join('');
|
|
47
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* 设置 dom 样式
|
|
55
|
+
* @param div 需要设置样式的dom元素
|
|
56
|
+
* @param style 样式属性
|
|
57
|
+
*/
|
|
48
58
|
const setStyle = (element, style) => {
|
|
49
59
|
const { width, height, position, left = 0, top = 0, zIndex, pointerEvents, background } = style;
|
|
50
60
|
element.style.width = `${width}px`;
|
|
@@ -68,7 +78,70 @@ const setTransform = (element, transform, ratioX, ratioY) => {
|
|
|
68
78
|
element.style.webkitTransformOrigin = 'left top';
|
|
69
79
|
};
|
|
70
80
|
|
|
81
|
+
/**
|
|
82
|
+
* 无障碍组件(A11y/Accessibility)
|
|
83
|
+
*
|
|
84
|
+
* A11y 组件为游戏对象提供无障碍支持,使屏幕阅读器能够识别和朗读游戏内容。
|
|
85
|
+
* 它在游戏画布上方创建透明的 DOM 元素,携带 ARIA 属性,让视障用户也能使用游戏。
|
|
86
|
+
*
|
|
87
|
+
* 主要功能:
|
|
88
|
+
* - 提供屏幕阅读器可识别的文本标签
|
|
89
|
+
* - 支持 ARIA 角色和属性
|
|
90
|
+
* - 自动同步游戏对象的位置和尺寸
|
|
91
|
+
* - 支持交互事件的无障碍访问
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* // 为游戏对象提供朗读能力
|
|
96
|
+
* const button = new GameObject('button');
|
|
97
|
+
* button.addComponent(new A11y({
|
|
98
|
+
* hint: '开始游戏按钮',
|
|
99
|
+
* role: 'button'
|
|
100
|
+
* }));
|
|
101
|
+
*
|
|
102
|
+
* // 带交互事件的无障碍元素
|
|
103
|
+
* button.addComponent(new A11y({
|
|
104
|
+
* hint: '点击开始游戏',
|
|
105
|
+
* event: eventComponent
|
|
106
|
+
* }));
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
71
109
|
class A11y extends eva_js.Component {
|
|
110
|
+
/**
|
|
111
|
+
* 构造无障碍组件
|
|
112
|
+
*
|
|
113
|
+
* @param param - 无障碍组件配置参数
|
|
114
|
+
* @param param.hint - 屏幕阅读器朗读文本
|
|
115
|
+
* @param param.interactive - 是否可交互,默认 false
|
|
116
|
+
* @param param.role - ARIA 角色属性
|
|
117
|
+
* @param param.event - 关联的事件组件(已弃用)
|
|
118
|
+
* @param param.delay - DOM 延迟加载时间(毫秒)
|
|
119
|
+
* @param param.props - ARIA value 属性(已弃用)
|
|
120
|
+
* @param param.state - ARIA state 属性(已弃用)
|
|
121
|
+
* @param param.attr - 自定义属性(已弃用)
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* // 简单文本朗读
|
|
126
|
+
* new A11y({ hint: '这是一个图片' })
|
|
127
|
+
*
|
|
128
|
+
* // 可交互按钮
|
|
129
|
+
* new A11y({
|
|
130
|
+
* hint: '开始游戏',
|
|
131
|
+
* role: 'button',
|
|
132
|
+
* interactive: true
|
|
133
|
+
* })
|
|
134
|
+
*
|
|
135
|
+
* // 带 ARIA 属性
|
|
136
|
+
* new A11y({
|
|
137
|
+
* hint: '进度条',
|
|
138
|
+
* role: 'progressbar',
|
|
139
|
+
* 'aria-valuemin': '0',
|
|
140
|
+
* 'aria-valuemax': '100',
|
|
141
|
+
* 'aria-valuenow': '50'
|
|
142
|
+
* })
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
72
145
|
constructor(param) {
|
|
73
146
|
super();
|
|
74
147
|
Object.assign(this, param);
|
|
@@ -83,6 +156,7 @@ class A11y extends eva_js.Component {
|
|
|
83
156
|
this.a11yId = `_${uuid(6)}`;
|
|
84
157
|
}
|
|
85
158
|
}
|
|
159
|
+
/** 组件名称 */
|
|
86
160
|
A11y.componentName = 'A11y';
|
|
87
161
|
__decorate([
|
|
88
162
|
inspectorDecorator.type('boolean')
|
|
@@ -109,16 +183,25 @@ exports.A11yActivate = void 0;
|
|
|
109
183
|
A11yActivate[A11yActivate["DISABLE"] = 1] = "DISABLE";
|
|
110
184
|
A11yActivate[A11yActivate["CHECK"] = 2] = "CHECK";
|
|
111
185
|
})(exports.A11yActivate || (exports.A11yActivate = {}));
|
|
186
|
+
/**
|
|
187
|
+
* 无障碍 DOM 的指针事件
|
|
188
|
+
*/
|
|
112
189
|
var PointerEvents;
|
|
113
190
|
(function (PointerEvents) {
|
|
114
191
|
PointerEvents["NONE"] = "none";
|
|
115
192
|
PointerEvents["AUTO"] = "auto";
|
|
116
193
|
})(PointerEvents || (PointerEvents = {}));
|
|
194
|
+
/**
|
|
195
|
+
* 无障碍 DOM 层的样式
|
|
196
|
+
*/
|
|
117
197
|
var MaskBackground;
|
|
118
198
|
(function (MaskBackground) {
|
|
119
199
|
MaskBackground["DEBUG"] = "rgba(255,0,0,0.5)";
|
|
120
200
|
MaskBackground["NONE"] = "transparent";
|
|
121
201
|
})(MaskBackground || (MaskBackground = {}));
|
|
202
|
+
/**
|
|
203
|
+
* 无障碍 DOM 的类型
|
|
204
|
+
*/
|
|
122
205
|
var ElementType;
|
|
123
206
|
(function (ElementType) {
|
|
124
207
|
ElementType["BUTTON"] = "button";
|
|
@@ -137,11 +220,69 @@ const getEventFunc = function (event, gameObject, e) {
|
|
|
137
220
|
});
|
|
138
221
|
});
|
|
139
222
|
};
|
|
223
|
+
/**
|
|
224
|
+
* 无障碍系统(A11y System)
|
|
225
|
+
*
|
|
226
|
+
* A11ySystem 管理游戏中所有无障碍组件,在游戏画布上方创建无障碍覆盖层。
|
|
227
|
+
* 它会自动将游戏对象的位置、尺寸同步到对应的 DOM 元素上,
|
|
228
|
+
* 并处理与屏幕阅读器的交互。
|
|
229
|
+
*
|
|
230
|
+
* 主要功能:
|
|
231
|
+
* - 创建和管理无障碍 DOM 覆盖层
|
|
232
|
+
* - 同步游戏对象的变换到 DOM 元素
|
|
233
|
+
* - 处理无障碍元素的事件绑定
|
|
234
|
+
* - 支持调试模式(可视化无障碍区域)
|
|
235
|
+
* - 自动检测或手动配置无障碍功能开关
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* // 自动检测系统读屏功能
|
|
240
|
+
* game.addSystem(new A11ySystem());
|
|
241
|
+
*
|
|
242
|
+
* // 开启调试模式
|
|
243
|
+
* game.addSystem(new A11ySystem({ debug: true }));
|
|
244
|
+
*
|
|
245
|
+
* // 强制启用无障碍功能
|
|
246
|
+
* game.addSystem(new A11ySystem({
|
|
247
|
+
* activate: A11yActivate.ENABLE,
|
|
248
|
+
* zIndex: 10000
|
|
249
|
+
* }));
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
140
252
|
let A11ySystem = class A11ySystem extends eva_js.System {
|
|
253
|
+
/**
|
|
254
|
+
* 构造无障碍系统
|
|
255
|
+
*
|
|
256
|
+
* @param opt - 系统配置选项
|
|
257
|
+
* @param opt.debug - 是否开启调试模式,默认 false
|
|
258
|
+
* @param opt.activate - 无障碍功能开关模式,默认 CHECK(自动检测)
|
|
259
|
+
* @param opt.delay - DOM 元素延迟创建时间(毫秒),默认 100
|
|
260
|
+
* @param opt.zIndex - 覆盖层的 z-index,默认 10000
|
|
261
|
+
* @param opt.checkA11yOpen - 自定义检测无障碍功能是否开启的函数
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* ```typescript
|
|
265
|
+
* // 开启调试,无障碍区域会显示红色透明背景
|
|
266
|
+
* new A11ySystem({ debug: true })
|
|
267
|
+
*
|
|
268
|
+
* // 禁用无障碍功能
|
|
269
|
+
* new A11ySystem({ activate: A11yActivate.DISABLE })
|
|
270
|
+
*
|
|
271
|
+
* // 自定义检测逻辑
|
|
272
|
+
* new A11ySystem({
|
|
273
|
+
* checkA11yOpen: async () => {
|
|
274
|
+
* return await isScreenReaderActive();
|
|
275
|
+
* }
|
|
276
|
+
* })
|
|
277
|
+
* ```
|
|
278
|
+
*/
|
|
141
279
|
constructor(opt) {
|
|
142
280
|
super(opt);
|
|
281
|
+
/** 无障碍 DOM 元素缓存 */
|
|
143
282
|
this.cache = new Map();
|
|
283
|
+
/** 事件处理函数缓存 */
|
|
144
284
|
this.eventCache = new Map();
|
|
285
|
+
/** 无障碍覆盖层的 z-index 值 */
|
|
145
286
|
this.zIndex = ZINDEX;
|
|
146
287
|
}
|
|
147
288
|
get ratioX() {
|
|
@@ -199,8 +340,10 @@ let A11ySystem = class A11ySystem extends eva_js.System {
|
|
|
199
340
|
}
|
|
200
341
|
if (!this.activate)
|
|
201
342
|
return;
|
|
343
|
+
// 渲染出父容器
|
|
202
344
|
const div = document.createElement('div');
|
|
203
345
|
this.div = div;
|
|
346
|
+
// 如果存在父容器,则渲染这个 div,子元素则会相对这个 div 进行定位,否则直接相对于 body 进行定位
|
|
204
347
|
if (this.game.canvas.parentNode) {
|
|
205
348
|
this.game.canvas.parentNode.insertBefore(this.div, this.game.canvas);
|
|
206
349
|
}
|
|
@@ -225,12 +368,14 @@ let A11ySystem = class A11ySystem extends eva_js.System {
|
|
|
225
368
|
return { renderWidth, renderHeight };
|
|
226
369
|
}
|
|
227
370
|
getCanvasBoundingClientRect() {
|
|
371
|
+
// 渲染画布相对于视口的实际宽高以及位置,实际的像素
|
|
228
372
|
const { width, height, left, top } = this.game.canvas.getBoundingClientRect();
|
|
229
373
|
return { width, height, left, top };
|
|
230
374
|
}
|
|
231
375
|
initDiv() {
|
|
232
376
|
const { pageXOffset, pageYOffset } = window;
|
|
233
377
|
const { width, height, left, top } = this.getCanvasBoundingClientRect();
|
|
378
|
+
// 父容器位置
|
|
234
379
|
const style = {
|
|
235
380
|
width,
|
|
236
381
|
height,
|
|
@@ -242,6 +387,7 @@ let A11ySystem = class A11ySystem extends eva_js.System {
|
|
|
242
387
|
background: MaskBackground.NONE,
|
|
243
388
|
};
|
|
244
389
|
setStyle(this.div, style);
|
|
390
|
+
// 给父容器设置捕获事件,用于监听事件坐标
|
|
245
391
|
this.div.addEventListener('click', e => {
|
|
246
392
|
const currentTarget = e.currentTarget;
|
|
247
393
|
const { left, top } = currentTarget.getBoundingClientRect();
|
|
@@ -250,6 +396,9 @@ let A11ySystem = class A11ySystem extends eva_js.System {
|
|
|
250
396
|
this.eventPosition = { x, y };
|
|
251
397
|
}, true);
|
|
252
398
|
}
|
|
399
|
+
/**
|
|
400
|
+
* 监听插件更新
|
|
401
|
+
*/
|
|
253
402
|
update() {
|
|
254
403
|
return __awaiter(this, void 0, void 0, function* () {
|
|
255
404
|
const changes = this.componentObserver.clear();
|
|
@@ -290,6 +439,10 @@ let A11ySystem = class A11ySystem extends eva_js.System {
|
|
|
290
439
|
element && this.div.removeChild(element);
|
|
291
440
|
this.cache.delete(a11yId);
|
|
292
441
|
}
|
|
442
|
+
/**
|
|
443
|
+
* 监听组件被添加至游戏对象
|
|
444
|
+
* @param changed 改变的组件
|
|
445
|
+
*/
|
|
293
446
|
add(changed) {
|
|
294
447
|
if (!this.activate)
|
|
295
448
|
return;
|
|
@@ -318,6 +471,7 @@ let A11ySystem = class A11ySystem extends eva_js.System {
|
|
|
318
471
|
}
|
|
319
472
|
}, delay || this.delay);
|
|
320
473
|
}
|
|
474
|
+
// 监听 scene 改变
|
|
321
475
|
transformChange(changed) {
|
|
322
476
|
const component = changed.component;
|
|
323
477
|
const { gameObject } = changed;
|
|
@@ -326,16 +480,26 @@ let A11ySystem = class A11ySystem extends eva_js.System {
|
|
|
326
480
|
return;
|
|
327
481
|
const { a11yId } = a11yComponent;
|
|
328
482
|
if (!component.inScene) {
|
|
483
|
+
// 监听 scene 删除游戏对象
|
|
329
484
|
const dom = this.div.querySelector(`#${a11yId}`);
|
|
330
485
|
dom && this.div.removeChild(dom);
|
|
486
|
+
// this.cache.delete(a11yId)
|
|
331
487
|
}
|
|
332
488
|
else {
|
|
489
|
+
// 监听 scene add
|
|
490
|
+
// this.div.appendChild(this.cache)
|
|
333
491
|
if (this.cache.has(a11yId)) {
|
|
334
492
|
const addDom = this.cache.get(a11yId);
|
|
335
493
|
addDom && this.div.appendChild(addDom);
|
|
336
494
|
}
|
|
337
495
|
}
|
|
338
496
|
}
|
|
497
|
+
/**
|
|
498
|
+
* 为无障碍组件设置监听事件
|
|
499
|
+
* @param element DOM 元素
|
|
500
|
+
* @param event 事件组件对象
|
|
501
|
+
* @param gameObject 游戏对象
|
|
502
|
+
*/
|
|
339
503
|
setEvent(element, event, gameObject, id) {
|
|
340
504
|
if (!event) {
|
|
341
505
|
return;
|
|
@@ -367,12 +531,19 @@ let A11ySystem = class A11ySystem extends eva_js.System {
|
|
|
367
531
|
const element = this.cache.get(a11yId);
|
|
368
532
|
element && element.removeEventListener('click', func);
|
|
369
533
|
}
|
|
534
|
+
/**
|
|
535
|
+
* 设置无障碍属性标签
|
|
536
|
+
* @param element DOM 元素
|
|
537
|
+
* @param hint 无障碍朗读文字
|
|
538
|
+
* @param interactive 是否可交互
|
|
539
|
+
*/
|
|
370
540
|
setA11yAttr(element, component) {
|
|
371
541
|
const { hint, props = {}, state = {}, role, a11yId: id } = component;
|
|
372
542
|
const realRole = role || 'text';
|
|
373
543
|
element.setAttribute('role', realRole);
|
|
374
544
|
element.setAttribute('aria-label', hint);
|
|
375
545
|
element.id = id;
|
|
546
|
+
// 这里兼容
|
|
376
547
|
const ariaProps = Object.keys(props);
|
|
377
548
|
for (const key of ariaProps) {
|
|
378
549
|
element.setAttribute(key, props[key]);
|
|
@@ -387,8 +558,19 @@ let A11ySystem = class A11ySystem extends eva_js.System {
|
|
|
387
558
|
}
|
|
388
559
|
}
|
|
389
560
|
}
|
|
561
|
+
/**
|
|
562
|
+
* 将无障碍元素设置到对应的位置
|
|
563
|
+
* @param element DOM 元素
|
|
564
|
+
* @param transform 位置属性
|
|
565
|
+
*/
|
|
390
566
|
setPosition(element, transform) {
|
|
567
|
+
// 相对画布定位
|
|
568
|
+
// const { x: anchorX, y: anchorY } = transform.anchor
|
|
569
|
+
// 游戏对象的宽高
|
|
391
570
|
const { width, height } = transform.size;
|
|
571
|
+
// position
|
|
572
|
+
// const { x: positionX, y: positionY } = transform.position
|
|
573
|
+
// 设置无障碍 DOM 的样式,龙骨动画默认 2px
|
|
392
574
|
const style = {
|
|
393
575
|
width: width === 0 ? 1 : width * this.ratioX,
|
|
394
576
|
height: height === 0 ? 1 : height * this.ratioY,
|
|
@@ -398,6 +580,7 @@ let A11ySystem = class A11ySystem extends eva_js.System {
|
|
|
398
580
|
background: this.debug ? MaskBackground.DEBUG : MaskBackground.NONE,
|
|
399
581
|
};
|
|
400
582
|
setStyle(element, style);
|
|
583
|
+
// 调整 DOM 的位置
|
|
401
584
|
setTransform(element, transform, this.ratioX, this.ratioY);
|
|
402
585
|
}
|
|
403
586
|
onDestroy() {
|
|
@@ -407,6 +590,7 @@ let A11ySystem = class A11ySystem extends eva_js.System {
|
|
|
407
590
|
this.div = null;
|
|
408
591
|
}
|
|
409
592
|
};
|
|
593
|
+
/** 系统名称 */
|
|
410
594
|
A11ySystem.systemName = 'A11ySystem';
|
|
411
595
|
A11ySystem = __decorate([
|
|
412
596
|
eva_js.decorators.componentObserver({
|
package/dist/plugin-a11y.d.ts
CHANGED
|
@@ -5,17 +5,106 @@ import type { GameObject } from '@eva/eva.js';
|
|
|
5
5
|
import { System } from '@eva/eva.js';
|
|
6
6
|
import { Transform } from '@eva/eva.js';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* 无障碍组件(A11y/Accessibility)
|
|
10
|
+
*
|
|
11
|
+
* A11y 组件为游戏对象提供无障碍支持,使屏幕阅读器能够识别和朗读游戏内容。
|
|
12
|
+
* 它在游戏画布上方创建透明的 DOM 元素,携带 ARIA 属性,让视障用户也能使用游戏。
|
|
13
|
+
*
|
|
14
|
+
* 主要功能:
|
|
15
|
+
* - 提供屏幕阅读器可识别的文本标签
|
|
16
|
+
* - 支持 ARIA 角色和属性
|
|
17
|
+
* - 自动同步游戏对象的位置和尺寸
|
|
18
|
+
* - 支持交互事件的无障碍访问
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* // 为游戏对象提供朗读能力
|
|
23
|
+
* const button = new GameObject('button');
|
|
24
|
+
* button.addComponent(new A11y({
|
|
25
|
+
* hint: '开始游戏按钮',
|
|
26
|
+
* role: 'button'
|
|
27
|
+
* }));
|
|
28
|
+
*
|
|
29
|
+
* // 带交互事件的无障碍元素
|
|
30
|
+
* button.addComponent(new A11y({
|
|
31
|
+
* hint: '点击开始游戏',
|
|
32
|
+
* event: eventComponent
|
|
33
|
+
* }));
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
8
36
|
export declare class A11y extends Component<A11yParams> {
|
|
37
|
+
/** 组件名称 */
|
|
9
38
|
static componentName: string;
|
|
39
|
+
/** 是否可交互 */
|
|
10
40
|
interactive: boolean;
|
|
41
|
+
/** 屏幕阅读器朗读的文本内容 */
|
|
11
42
|
hint: string;
|
|
43
|
+
/**
|
|
44
|
+
* 事件组件对象
|
|
45
|
+
* @deprecated 已弃用,将根据 Event 组件自动添加
|
|
46
|
+
*/
|
|
12
47
|
event: Component;
|
|
48
|
+
/** DOM 元素延迟加载时间(毫秒) */
|
|
13
49
|
delay: number;
|
|
50
|
+
/** ARIA role 属性,定义元素的角色(如 button、link 等) */
|
|
14
51
|
role: string;
|
|
52
|
+
/**
|
|
53
|
+
* ARIA value 属性集合
|
|
54
|
+
* @deprecated 已弃用,请将属性直接写在 component 上
|
|
55
|
+
* @example
|
|
56
|
+
* aria-valuemin = "0"
|
|
57
|
+
*/
|
|
15
58
|
props: object;
|
|
59
|
+
/**
|
|
60
|
+
* ARIA state 属性集合
|
|
61
|
+
* @deprecated 已弃用,请将属性直接写在 component 上
|
|
62
|
+
* @example
|
|
63
|
+
* aria-hidden = "true"
|
|
64
|
+
*/
|
|
16
65
|
state: object;
|
|
66
|
+
/**
|
|
67
|
+
* 自定义 DOM 属性
|
|
68
|
+
* @deprecated 已弃用,请将属性直接写在 component 上
|
|
69
|
+
*/
|
|
17
70
|
attr: object;
|
|
71
|
+
/** 辅助 DOM 元素的唯一 ID,自动生成 */
|
|
18
72
|
a11yId: string;
|
|
73
|
+
/**
|
|
74
|
+
* 构造无障碍组件
|
|
75
|
+
*
|
|
76
|
+
* @param param - 无障碍组件配置参数
|
|
77
|
+
* @param param.hint - 屏幕阅读器朗读文本
|
|
78
|
+
* @param param.interactive - 是否可交互,默认 false
|
|
79
|
+
* @param param.role - ARIA 角色属性
|
|
80
|
+
* @param param.event - 关联的事件组件(已弃用)
|
|
81
|
+
* @param param.delay - DOM 延迟加载时间(毫秒)
|
|
82
|
+
* @param param.props - ARIA value 属性(已弃用)
|
|
83
|
+
* @param param.state - ARIA state 属性(已弃用)
|
|
84
|
+
* @param param.attr - 自定义属性(已弃用)
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* // 简单文本朗读
|
|
89
|
+
* new A11y({ hint: '这是一个图片' })
|
|
90
|
+
*
|
|
91
|
+
* // 可交互按钮
|
|
92
|
+
* new A11y({
|
|
93
|
+
* hint: '开始游戏',
|
|
94
|
+
* role: 'button',
|
|
95
|
+
* interactive: true
|
|
96
|
+
* })
|
|
97
|
+
*
|
|
98
|
+
* // 带 ARIA 属性
|
|
99
|
+
* new A11y({
|
|
100
|
+
* hint: '进度条',
|
|
101
|
+
* role: 'progressbar',
|
|
102
|
+
* 'aria-valuemin': '0',
|
|
103
|
+
* 'aria-valuemax': '100',
|
|
104
|
+
* 'aria-valuenow': '50'
|
|
105
|
+
* })
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
19
108
|
constructor(param: A11yParams);
|
|
20
109
|
}
|
|
21
110
|
|
|
@@ -37,18 +126,84 @@ declare interface A11yParams {
|
|
|
37
126
|
[propName: string]: string | object | number;
|
|
38
127
|
}
|
|
39
128
|
|
|
129
|
+
/**
|
|
130
|
+
* 无障碍系统(A11y System)
|
|
131
|
+
*
|
|
132
|
+
* A11ySystem 管理游戏中所有无障碍组件,在游戏画布上方创建无障碍覆盖层。
|
|
133
|
+
* 它会自动将游戏对象的位置、尺寸同步到对应的 DOM 元素上,
|
|
134
|
+
* 并处理与屏幕阅读器的交互。
|
|
135
|
+
*
|
|
136
|
+
* 主要功能:
|
|
137
|
+
* - 创建和管理无障碍 DOM 覆盖层
|
|
138
|
+
* - 同步游戏对象的变换到 DOM 元素
|
|
139
|
+
* - 处理无障碍元素的事件绑定
|
|
140
|
+
* - 支持调试模式(可视化无障碍区域)
|
|
141
|
+
* - 自动检测或手动配置无障碍功能开关
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```typescript
|
|
145
|
+
* // 自动检测系统读屏功能
|
|
146
|
+
* game.addSystem(new A11ySystem());
|
|
147
|
+
*
|
|
148
|
+
* // 开启调试模式
|
|
149
|
+
* game.addSystem(new A11ySystem({ debug: true }));
|
|
150
|
+
*
|
|
151
|
+
* // 强制启用无障碍功能
|
|
152
|
+
* game.addSystem(new A11ySystem({
|
|
153
|
+
* activate: A11yActivate.ENABLE,
|
|
154
|
+
* zIndex: 10000
|
|
155
|
+
* }));
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
40
158
|
export declare class A11ySystem extends System {
|
|
159
|
+
/** 系统名称 */
|
|
41
160
|
static systemName: string;
|
|
161
|
+
/** 无障碍覆盖层容器 */
|
|
42
162
|
div: HTMLDivElement;
|
|
163
|
+
/** 是否开启调试模式(显示无障碍区域背景色) */
|
|
43
164
|
debug: boolean;
|
|
165
|
+
/** 画布横向缩放比例 */
|
|
44
166
|
_ratioX: number;
|
|
167
|
+
/** 画布纵向缩放比例 */
|
|
45
168
|
_ratioY: number;
|
|
169
|
+
/** 当前事件触发的坐标位置 */
|
|
46
170
|
eventPosition: EventPosition;
|
|
171
|
+
/** 是否启用无障碍功能 */
|
|
47
172
|
activate: boolean;
|
|
173
|
+
/** DOM 元素延迟放置时间(毫秒) */
|
|
48
174
|
delay: number;
|
|
175
|
+
/** 无障碍 DOM 元素缓存 */
|
|
49
176
|
cache: Map<string, HTMLElement>;
|
|
177
|
+
/** 事件处理函数缓存 */
|
|
50
178
|
eventCache: Map<string, (e: MouseEvent) => void>;
|
|
179
|
+
/** 无障碍覆盖层的 z-index 值 */
|
|
51
180
|
zIndex: number;
|
|
181
|
+
/**
|
|
182
|
+
* 构造无障碍系统
|
|
183
|
+
*
|
|
184
|
+
* @param opt - 系统配置选项
|
|
185
|
+
* @param opt.debug - 是否开启调试模式,默认 false
|
|
186
|
+
* @param opt.activate - 无障碍功能开关模式,默认 CHECK(自动检测)
|
|
187
|
+
* @param opt.delay - DOM 元素延迟创建时间(毫秒),默认 100
|
|
188
|
+
* @param opt.zIndex - 覆盖层的 z-index,默认 10000
|
|
189
|
+
* @param opt.checkA11yOpen - 自定义检测无障碍功能是否开启的函数
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* // 开启调试,无障碍区域会显示红色透明背景
|
|
194
|
+
* new A11ySystem({ debug: true })
|
|
195
|
+
*
|
|
196
|
+
* // 禁用无障碍功能
|
|
197
|
+
* new A11ySystem({ activate: A11yActivate.DISABLE })
|
|
198
|
+
*
|
|
199
|
+
* // 自定义检测逻辑
|
|
200
|
+
* new A11ySystem({
|
|
201
|
+
* checkA11yOpen: async () => {
|
|
202
|
+
* return await isScreenReaderActive();
|
|
203
|
+
* }
|
|
204
|
+
* })
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
52
207
|
constructor(opt?: SystemParam);
|
|
53
208
|
get ratioX(): number;
|
|
54
209
|
get ratioY(): number;
|
|
@@ -65,19 +220,46 @@ export declare class A11ySystem extends System {
|
|
|
65
220
|
top: number;
|
|
66
221
|
};
|
|
67
222
|
initDiv(): void;
|
|
223
|
+
/**
|
|
224
|
+
* 监听插件更新
|
|
225
|
+
*/
|
|
68
226
|
update(): Promise<void>;
|
|
69
227
|
change(changed: ComponentChanged): void;
|
|
70
228
|
remove(changed: ComponentChanged): void;
|
|
229
|
+
/**
|
|
230
|
+
* 监听组件被添加至游戏对象
|
|
231
|
+
* @param changed 改变的组件
|
|
232
|
+
*/
|
|
71
233
|
add(changed: ComponentChanged): void;
|
|
72
234
|
transformChange(changed: ComponentChanged): void;
|
|
235
|
+
/**
|
|
236
|
+
* 为无障碍组件设置监听事件
|
|
237
|
+
* @param element DOM 元素
|
|
238
|
+
* @param event 事件组件对象
|
|
239
|
+
* @param gameObject 游戏对象
|
|
240
|
+
*/
|
|
73
241
|
setEvent(element: HTMLElement, event: EE, gameObject: GameObject, id: any): void;
|
|
74
242
|
addEvent(gameObject: GameObject): void;
|
|
75
243
|
removeEvent(changed: ComponentChanged): void;
|
|
244
|
+
/**
|
|
245
|
+
* 设置无障碍属性标签
|
|
246
|
+
* @param element DOM 元素
|
|
247
|
+
* @param hint 无障碍朗读文字
|
|
248
|
+
* @param interactive 是否可交互
|
|
249
|
+
*/
|
|
76
250
|
setA11yAttr(element: HTMLElement, component: A11y): void;
|
|
251
|
+
/**
|
|
252
|
+
* 将无障碍元素设置到对应的位置
|
|
253
|
+
* @param element DOM 元素
|
|
254
|
+
* @param transform 位置属性
|
|
255
|
+
*/
|
|
77
256
|
setPosition(element: HTMLElement, transform: Transform): void;
|
|
78
257
|
onDestroy(): void;
|
|
79
258
|
}
|
|
80
259
|
|
|
260
|
+
/**
|
|
261
|
+
* 点击事件位置
|
|
262
|
+
*/
|
|
81
263
|
declare interface EventPosition {
|
|
82
264
|
x: number;
|
|
83
265
|
y: number;
|
package/dist/plugin-a11y.esm.js
CHANGED
|
@@ -33,6 +33,11 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* 生成唯一的标识符
|
|
38
|
+
* @param len 长度
|
|
39
|
+
* @param radix 基
|
|
40
|
+
*/
|
|
36
41
|
function uuid(len) {
|
|
37
42
|
let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
|
|
38
43
|
let uuid = [];
|
|
@@ -41,6 +46,11 @@ function uuid(len) {
|
|
|
41
46
|
uuid[i] = chars[0 | (Math.random() * radix)];
|
|
42
47
|
return uuid.join('');
|
|
43
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* 设置 dom 样式
|
|
51
|
+
* @param div 需要设置样式的dom元素
|
|
52
|
+
* @param style 样式属性
|
|
53
|
+
*/
|
|
44
54
|
const setStyle = (element, style) => {
|
|
45
55
|
const { width, height, position, left = 0, top = 0, zIndex, pointerEvents, background } = style;
|
|
46
56
|
element.style.width = `${width}px`;
|
|
@@ -64,7 +74,70 @@ const setTransform = (element, transform, ratioX, ratioY) => {
|
|
|
64
74
|
element.style.webkitTransformOrigin = 'left top';
|
|
65
75
|
};
|
|
66
76
|
|
|
77
|
+
/**
|
|
78
|
+
* 无障碍组件(A11y/Accessibility)
|
|
79
|
+
*
|
|
80
|
+
* A11y 组件为游戏对象提供无障碍支持,使屏幕阅读器能够识别和朗读游戏内容。
|
|
81
|
+
* 它在游戏画布上方创建透明的 DOM 元素,携带 ARIA 属性,让视障用户也能使用游戏。
|
|
82
|
+
*
|
|
83
|
+
* 主要功能:
|
|
84
|
+
* - 提供屏幕阅读器可识别的文本标签
|
|
85
|
+
* - 支持 ARIA 角色和属性
|
|
86
|
+
* - 自动同步游戏对象的位置和尺寸
|
|
87
|
+
* - 支持交互事件的无障碍访问
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* // 为游戏对象提供朗读能力
|
|
92
|
+
* const button = new GameObject('button');
|
|
93
|
+
* button.addComponent(new A11y({
|
|
94
|
+
* hint: '开始游戏按钮',
|
|
95
|
+
* role: 'button'
|
|
96
|
+
* }));
|
|
97
|
+
*
|
|
98
|
+
* // 带交互事件的无障碍元素
|
|
99
|
+
* button.addComponent(new A11y({
|
|
100
|
+
* hint: '点击开始游戏',
|
|
101
|
+
* event: eventComponent
|
|
102
|
+
* }));
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
67
105
|
class A11y extends Component {
|
|
106
|
+
/**
|
|
107
|
+
* 构造无障碍组件
|
|
108
|
+
*
|
|
109
|
+
* @param param - 无障碍组件配置参数
|
|
110
|
+
* @param param.hint - 屏幕阅读器朗读文本
|
|
111
|
+
* @param param.interactive - 是否可交互,默认 false
|
|
112
|
+
* @param param.role - ARIA 角色属性
|
|
113
|
+
* @param param.event - 关联的事件组件(已弃用)
|
|
114
|
+
* @param param.delay - DOM 延迟加载时间(毫秒)
|
|
115
|
+
* @param param.props - ARIA value 属性(已弃用)
|
|
116
|
+
* @param param.state - ARIA state 属性(已弃用)
|
|
117
|
+
* @param param.attr - 自定义属性(已弃用)
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* // 简单文本朗读
|
|
122
|
+
* new A11y({ hint: '这是一个图片' })
|
|
123
|
+
*
|
|
124
|
+
* // 可交互按钮
|
|
125
|
+
* new A11y({
|
|
126
|
+
* hint: '开始游戏',
|
|
127
|
+
* role: 'button',
|
|
128
|
+
* interactive: true
|
|
129
|
+
* })
|
|
130
|
+
*
|
|
131
|
+
* // 带 ARIA 属性
|
|
132
|
+
* new A11y({
|
|
133
|
+
* hint: '进度条',
|
|
134
|
+
* role: 'progressbar',
|
|
135
|
+
* 'aria-valuemin': '0',
|
|
136
|
+
* 'aria-valuemax': '100',
|
|
137
|
+
* 'aria-valuenow': '50'
|
|
138
|
+
* })
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
68
141
|
constructor(param) {
|
|
69
142
|
super();
|
|
70
143
|
Object.assign(this, param);
|
|
@@ -79,6 +152,7 @@ class A11y extends Component {
|
|
|
79
152
|
this.a11yId = `_${uuid(6)}`;
|
|
80
153
|
}
|
|
81
154
|
}
|
|
155
|
+
/** 组件名称 */
|
|
82
156
|
A11y.componentName = 'A11y';
|
|
83
157
|
__decorate([
|
|
84
158
|
type('boolean')
|
|
@@ -105,16 +179,25 @@ var A11yActivate;
|
|
|
105
179
|
A11yActivate[A11yActivate["DISABLE"] = 1] = "DISABLE";
|
|
106
180
|
A11yActivate[A11yActivate["CHECK"] = 2] = "CHECK";
|
|
107
181
|
})(A11yActivate || (A11yActivate = {}));
|
|
182
|
+
/**
|
|
183
|
+
* 无障碍 DOM 的指针事件
|
|
184
|
+
*/
|
|
108
185
|
var PointerEvents;
|
|
109
186
|
(function (PointerEvents) {
|
|
110
187
|
PointerEvents["NONE"] = "none";
|
|
111
188
|
PointerEvents["AUTO"] = "auto";
|
|
112
189
|
})(PointerEvents || (PointerEvents = {}));
|
|
190
|
+
/**
|
|
191
|
+
* 无障碍 DOM 层的样式
|
|
192
|
+
*/
|
|
113
193
|
var MaskBackground;
|
|
114
194
|
(function (MaskBackground) {
|
|
115
195
|
MaskBackground["DEBUG"] = "rgba(255,0,0,0.5)";
|
|
116
196
|
MaskBackground["NONE"] = "transparent";
|
|
117
197
|
})(MaskBackground || (MaskBackground = {}));
|
|
198
|
+
/**
|
|
199
|
+
* 无障碍 DOM 的类型
|
|
200
|
+
*/
|
|
118
201
|
var ElementType;
|
|
119
202
|
(function (ElementType) {
|
|
120
203
|
ElementType["BUTTON"] = "button";
|
|
@@ -133,11 +216,69 @@ const getEventFunc = function (event, gameObject, e) {
|
|
|
133
216
|
});
|
|
134
217
|
});
|
|
135
218
|
};
|
|
219
|
+
/**
|
|
220
|
+
* 无障碍系统(A11y System)
|
|
221
|
+
*
|
|
222
|
+
* A11ySystem 管理游戏中所有无障碍组件,在游戏画布上方创建无障碍覆盖层。
|
|
223
|
+
* 它会自动将游戏对象的位置、尺寸同步到对应的 DOM 元素上,
|
|
224
|
+
* 并处理与屏幕阅读器的交互。
|
|
225
|
+
*
|
|
226
|
+
* 主要功能:
|
|
227
|
+
* - 创建和管理无障碍 DOM 覆盖层
|
|
228
|
+
* - 同步游戏对象的变换到 DOM 元素
|
|
229
|
+
* - 处理无障碍元素的事件绑定
|
|
230
|
+
* - 支持调试模式(可视化无障碍区域)
|
|
231
|
+
* - 自动检测或手动配置无障碍功能开关
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* // 自动检测系统读屏功能
|
|
236
|
+
* game.addSystem(new A11ySystem());
|
|
237
|
+
*
|
|
238
|
+
* // 开启调试模式
|
|
239
|
+
* game.addSystem(new A11ySystem({ debug: true }));
|
|
240
|
+
*
|
|
241
|
+
* // 强制启用无障碍功能
|
|
242
|
+
* game.addSystem(new A11ySystem({
|
|
243
|
+
* activate: A11yActivate.ENABLE,
|
|
244
|
+
* zIndex: 10000
|
|
245
|
+
* }));
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
136
248
|
let A11ySystem = class A11ySystem extends System {
|
|
249
|
+
/**
|
|
250
|
+
* 构造无障碍系统
|
|
251
|
+
*
|
|
252
|
+
* @param opt - 系统配置选项
|
|
253
|
+
* @param opt.debug - 是否开启调试模式,默认 false
|
|
254
|
+
* @param opt.activate - 无障碍功能开关模式,默认 CHECK(自动检测)
|
|
255
|
+
* @param opt.delay - DOM 元素延迟创建时间(毫秒),默认 100
|
|
256
|
+
* @param opt.zIndex - 覆盖层的 z-index,默认 10000
|
|
257
|
+
* @param opt.checkA11yOpen - 自定义检测无障碍功能是否开启的函数
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* // 开启调试,无障碍区域会显示红色透明背景
|
|
262
|
+
* new A11ySystem({ debug: true })
|
|
263
|
+
*
|
|
264
|
+
* // 禁用无障碍功能
|
|
265
|
+
* new A11ySystem({ activate: A11yActivate.DISABLE })
|
|
266
|
+
*
|
|
267
|
+
* // 自定义检测逻辑
|
|
268
|
+
* new A11ySystem({
|
|
269
|
+
* checkA11yOpen: async () => {
|
|
270
|
+
* return await isScreenReaderActive();
|
|
271
|
+
* }
|
|
272
|
+
* })
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
137
275
|
constructor(opt) {
|
|
138
276
|
super(opt);
|
|
277
|
+
/** 无障碍 DOM 元素缓存 */
|
|
139
278
|
this.cache = new Map();
|
|
279
|
+
/** 事件处理函数缓存 */
|
|
140
280
|
this.eventCache = new Map();
|
|
281
|
+
/** 无障碍覆盖层的 z-index 值 */
|
|
141
282
|
this.zIndex = ZINDEX;
|
|
142
283
|
}
|
|
143
284
|
get ratioX() {
|
|
@@ -195,8 +336,10 @@ let A11ySystem = class A11ySystem extends System {
|
|
|
195
336
|
}
|
|
196
337
|
if (!this.activate)
|
|
197
338
|
return;
|
|
339
|
+
// 渲染出父容器
|
|
198
340
|
const div = document.createElement('div');
|
|
199
341
|
this.div = div;
|
|
342
|
+
// 如果存在父容器,则渲染这个 div,子元素则会相对这个 div 进行定位,否则直接相对于 body 进行定位
|
|
200
343
|
if (this.game.canvas.parentNode) {
|
|
201
344
|
this.game.canvas.parentNode.insertBefore(this.div, this.game.canvas);
|
|
202
345
|
}
|
|
@@ -221,12 +364,14 @@ let A11ySystem = class A11ySystem extends System {
|
|
|
221
364
|
return { renderWidth, renderHeight };
|
|
222
365
|
}
|
|
223
366
|
getCanvasBoundingClientRect() {
|
|
367
|
+
// 渲染画布相对于视口的实际宽高以及位置,实际的像素
|
|
224
368
|
const { width, height, left, top } = this.game.canvas.getBoundingClientRect();
|
|
225
369
|
return { width, height, left, top };
|
|
226
370
|
}
|
|
227
371
|
initDiv() {
|
|
228
372
|
const { pageXOffset, pageYOffset } = window;
|
|
229
373
|
const { width, height, left, top } = this.getCanvasBoundingClientRect();
|
|
374
|
+
// 父容器位置
|
|
230
375
|
const style = {
|
|
231
376
|
width,
|
|
232
377
|
height,
|
|
@@ -238,6 +383,7 @@ let A11ySystem = class A11ySystem extends System {
|
|
|
238
383
|
background: MaskBackground.NONE,
|
|
239
384
|
};
|
|
240
385
|
setStyle(this.div, style);
|
|
386
|
+
// 给父容器设置捕获事件,用于监听事件坐标
|
|
241
387
|
this.div.addEventListener('click', e => {
|
|
242
388
|
const currentTarget = e.currentTarget;
|
|
243
389
|
const { left, top } = currentTarget.getBoundingClientRect();
|
|
@@ -246,6 +392,9 @@ let A11ySystem = class A11ySystem extends System {
|
|
|
246
392
|
this.eventPosition = { x, y };
|
|
247
393
|
}, true);
|
|
248
394
|
}
|
|
395
|
+
/**
|
|
396
|
+
* 监听插件更新
|
|
397
|
+
*/
|
|
249
398
|
update() {
|
|
250
399
|
return __awaiter(this, void 0, void 0, function* () {
|
|
251
400
|
const changes = this.componentObserver.clear();
|
|
@@ -286,6 +435,10 @@ let A11ySystem = class A11ySystem extends System {
|
|
|
286
435
|
element && this.div.removeChild(element);
|
|
287
436
|
this.cache.delete(a11yId);
|
|
288
437
|
}
|
|
438
|
+
/**
|
|
439
|
+
* 监听组件被添加至游戏对象
|
|
440
|
+
* @param changed 改变的组件
|
|
441
|
+
*/
|
|
289
442
|
add(changed) {
|
|
290
443
|
if (!this.activate)
|
|
291
444
|
return;
|
|
@@ -314,6 +467,7 @@ let A11ySystem = class A11ySystem extends System {
|
|
|
314
467
|
}
|
|
315
468
|
}, delay || this.delay);
|
|
316
469
|
}
|
|
470
|
+
// 监听 scene 改变
|
|
317
471
|
transformChange(changed) {
|
|
318
472
|
const component = changed.component;
|
|
319
473
|
const { gameObject } = changed;
|
|
@@ -322,16 +476,26 @@ let A11ySystem = class A11ySystem extends System {
|
|
|
322
476
|
return;
|
|
323
477
|
const { a11yId } = a11yComponent;
|
|
324
478
|
if (!component.inScene) {
|
|
479
|
+
// 监听 scene 删除游戏对象
|
|
325
480
|
const dom = this.div.querySelector(`#${a11yId}`);
|
|
326
481
|
dom && this.div.removeChild(dom);
|
|
482
|
+
// this.cache.delete(a11yId)
|
|
327
483
|
}
|
|
328
484
|
else {
|
|
485
|
+
// 监听 scene add
|
|
486
|
+
// this.div.appendChild(this.cache)
|
|
329
487
|
if (this.cache.has(a11yId)) {
|
|
330
488
|
const addDom = this.cache.get(a11yId);
|
|
331
489
|
addDom && this.div.appendChild(addDom);
|
|
332
490
|
}
|
|
333
491
|
}
|
|
334
492
|
}
|
|
493
|
+
/**
|
|
494
|
+
* 为无障碍组件设置监听事件
|
|
495
|
+
* @param element DOM 元素
|
|
496
|
+
* @param event 事件组件对象
|
|
497
|
+
* @param gameObject 游戏对象
|
|
498
|
+
*/
|
|
335
499
|
setEvent(element, event, gameObject, id) {
|
|
336
500
|
if (!event) {
|
|
337
501
|
return;
|
|
@@ -363,12 +527,19 @@ let A11ySystem = class A11ySystem extends System {
|
|
|
363
527
|
const element = this.cache.get(a11yId);
|
|
364
528
|
element && element.removeEventListener('click', func);
|
|
365
529
|
}
|
|
530
|
+
/**
|
|
531
|
+
* 设置无障碍属性标签
|
|
532
|
+
* @param element DOM 元素
|
|
533
|
+
* @param hint 无障碍朗读文字
|
|
534
|
+
* @param interactive 是否可交互
|
|
535
|
+
*/
|
|
366
536
|
setA11yAttr(element, component) {
|
|
367
537
|
const { hint, props = {}, state = {}, role, a11yId: id } = component;
|
|
368
538
|
const realRole = role || 'text';
|
|
369
539
|
element.setAttribute('role', realRole);
|
|
370
540
|
element.setAttribute('aria-label', hint);
|
|
371
541
|
element.id = id;
|
|
542
|
+
// 这里兼容
|
|
372
543
|
const ariaProps = Object.keys(props);
|
|
373
544
|
for (const key of ariaProps) {
|
|
374
545
|
element.setAttribute(key, props[key]);
|
|
@@ -383,8 +554,19 @@ let A11ySystem = class A11ySystem extends System {
|
|
|
383
554
|
}
|
|
384
555
|
}
|
|
385
556
|
}
|
|
557
|
+
/**
|
|
558
|
+
* 将无障碍元素设置到对应的位置
|
|
559
|
+
* @param element DOM 元素
|
|
560
|
+
* @param transform 位置属性
|
|
561
|
+
*/
|
|
386
562
|
setPosition(element, transform) {
|
|
563
|
+
// 相对画布定位
|
|
564
|
+
// const { x: anchorX, y: anchorY } = transform.anchor
|
|
565
|
+
// 游戏对象的宽高
|
|
387
566
|
const { width, height } = transform.size;
|
|
567
|
+
// position
|
|
568
|
+
// const { x: positionX, y: positionY } = transform.position
|
|
569
|
+
// 设置无障碍 DOM 的样式,龙骨动画默认 2px
|
|
388
570
|
const style = {
|
|
389
571
|
width: width === 0 ? 1 : width * this.ratioX,
|
|
390
572
|
height: height === 0 ? 1 : height * this.ratioY,
|
|
@@ -394,6 +576,7 @@ let A11ySystem = class A11ySystem extends System {
|
|
|
394
576
|
background: this.debug ? MaskBackground.DEBUG : MaskBackground.NONE,
|
|
395
577
|
};
|
|
396
578
|
setStyle(element, style);
|
|
579
|
+
// 调整 DOM 的位置
|
|
397
580
|
setTransform(element, transform, this.ratioX, this.ratioY);
|
|
398
581
|
}
|
|
399
582
|
onDestroy() {
|
|
@@ -403,6 +586,7 @@ let A11ySystem = class A11ySystem extends System {
|
|
|
403
586
|
this.div = null;
|
|
404
587
|
}
|
|
405
588
|
};
|
|
589
|
+
/** 系统名称 */
|
|
406
590
|
A11ySystem.systemName = 'A11ySystem';
|
|
407
591
|
A11ySystem = __decorate([
|
|
408
592
|
decorators.componentObserver({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eva/plugin-a11y",
|
|
3
|
-
"version": "2.0.1-beta.
|
|
3
|
+
"version": "2.0.1-beta.31",
|
|
4
4
|
"description": "@eva/plugin-a11y",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "dist/plugin-a11y.esm.js",
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"homepage": "https://eva.js.org",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@eva/eva.js": "2.0.1-beta.
|
|
21
|
+
"@eva/eva.js": "2.0.1-beta.31",
|
|
22
22
|
"@eva/inspector-decorator": "^0.0.5",
|
|
23
|
-
"@eva/plugin-renderer": "2.0.1-beta.
|
|
23
|
+
"@eva/plugin-renderer": "2.0.1-beta.31",
|
|
24
24
|
"eventemitter3": "^3.1.2"
|
|
25
25
|
}
|
|
26
26
|
}
|