@combos-fun/plugin-a11y 0.0.1

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/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # @combos-fun/plugin-a11y
2
+
3
+ Internal workspace package (Combos Fun monorepo).
@@ -0,0 +1,481 @@
1
+ 'use strict';
2
+
3
+ var tslib = require('tslib');
4
+ var engine = require('@combos-fun/engine');
5
+ var pluginRenderer = require('@combos-fun/plugin-renderer');
6
+ var inspectorDecorator = require('@combos-fun/inspector-decorator');
7
+
8
+ /**
9
+ * 生成唯一的标识符
10
+ * @param len 长度
11
+ * @param radix 基
12
+ */
13
+ function uuid(len) {
14
+ let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
15
+ let uuid = [];
16
+ let radix = chars.length;
17
+ for (let i = 0; i < len; i++)
18
+ uuid[i] = chars[0 | (Math.random() * radix)];
19
+ return uuid.join('');
20
+ }
21
+ /**
22
+ * 设置 dom 样式
23
+ * @param div 需要设置样式的dom元素
24
+ * @param style 样式属性
25
+ */
26
+ const setStyle = (element, style) => {
27
+ const { width, height, position, left = 0, top = 0, zIndex, pointerEvents, background } = style;
28
+ element.style.width = `${width}px`;
29
+ element.style.height = `${height}px`;
30
+ element.style.position = position;
31
+ element.style.left = `${left}`;
32
+ element.style.top = `${top}`;
33
+ element.style.zIndex = `${zIndex}`;
34
+ element.style.pointerEvents = pointerEvents;
35
+ element.style.background = background;
36
+ element.style.border = 'none';
37
+ element.style.overflow = 'hidden';
38
+ };
39
+ const setTransform = (element, transform, ratioX, ratioY) => {
40
+ const { worldTransform } = transform;
41
+ const { a, b, c, d, tx, ty } = worldTransform;
42
+ const matrix = `matrix(${a}, ${b}, ${c}, ${d}, ${tx * ratioX}, ${ty * ratioY})`;
43
+ element.style.transform = `${matrix}`;
44
+ element.style.webkitTransform = `${matrix}`;
45
+ element.style.transformOrigin = 'left top';
46
+ element.style.webkitTransformOrigin = 'left top';
47
+ };
48
+
49
+ class A11y extends engine.Component {
50
+ static { this.componentName = 'A11y'; }
51
+ /**
52
+ * 无障碍组件构造函数
53
+ * @param param interactive 默认为 false,如果游戏对象可交互,传入 true
54
+ * @example
55
+ * // 为游戏对象提供朗读能力
56
+ * new A11y({hint: '这是一个div'})
57
+ * // 游戏对象有事件,传入 event 对象
58
+ * new A11y({hint: '点击事件对象', event: event})
59
+ * // 无障碍属性
60
+ * new A11y({hint:'按钮', role: 'button', state: {aria-hidden="true"}})
61
+ * // 自定义属性
62
+ * new A11y({hint: '自定义属性', attr: {key: '1'}})
63
+ */
64
+ constructor(param) {
65
+ super();
66
+ Object.assign(this, param);
67
+ const { hint = '', event, delay = 0, attr = {}, role = '', props = {}, state = {} } = param;
68
+ this.hint = hint;
69
+ this.event = event;
70
+ this.delay = delay;
71
+ this.attr = attr;
72
+ this.role = role;
73
+ this.props = props;
74
+ this.state = state;
75
+ this.a11yId = `_${uuid(6)}`;
76
+ }
77
+ }
78
+ tslib.__decorate([
79
+ inspectorDecorator.type('boolean')
80
+ ], A11y.prototype, "interactive", void 0);
81
+ tslib.__decorate([
82
+ inspectorDecorator.type('string')
83
+ ], A11y.prototype, "hint", void 0);
84
+ tslib.__decorate([
85
+ inspectorDecorator.type('number'),
86
+ inspectorDecorator.step(1)
87
+ ], A11y.prototype, "delay", void 0);
88
+ tslib.__decorate([
89
+ inspectorDecorator.type('string')
90
+ ], A11y.prototype, "role", void 0);
91
+ tslib.__decorate([
92
+ inspectorDecorator.type('string')
93
+ ], A11y.prototype, "a11yId", void 0);
94
+
95
+ const POSITION = 'absolute';
96
+ const ZINDEX = 3;
97
+ exports.A11yActivate = void 0;
98
+ (function (A11yActivate) {
99
+ A11yActivate[A11yActivate["ENABLE"] = 0] = "ENABLE";
100
+ A11yActivate[A11yActivate["DISABLE"] = 1] = "DISABLE";
101
+ A11yActivate[A11yActivate["CHECK"] = 2] = "CHECK";
102
+ })(exports.A11yActivate || (exports.A11yActivate = {}));
103
+ /**
104
+ * 无障碍 DOM 的指针事件
105
+ */
106
+ var PointerEvents;
107
+ (function (PointerEvents) {
108
+ PointerEvents["NONE"] = "none";
109
+ PointerEvents["AUTO"] = "auto";
110
+ })(PointerEvents || (PointerEvents = {}));
111
+ /**
112
+ * 无障碍 DOM 层的样式
113
+ */
114
+ var MaskBackground;
115
+ (function (MaskBackground) {
116
+ MaskBackground["DEBUG"] = "rgba(255,0,0,0.5)";
117
+ MaskBackground["NONE"] = "transparent";
118
+ })(MaskBackground || (MaskBackground = {}));
119
+ /**
120
+ * 无障碍 DOM 的类型
121
+ */
122
+ var ElementType;
123
+ (function (ElementType) {
124
+ ElementType["BUTTON"] = "button";
125
+ ElementType["DIV"] = "div";
126
+ })(ElementType || (ElementType = {}));
127
+
128
+ const notAttr = ['hint', 'event', 'delay', 'attr', 'role', 'props', 'state', 'a11yId', 'name'];
129
+ const getEventFunc = function (event, gameObject, e) {
130
+ ['touchstart', 'touchend', 'tap'].forEach(name => {
131
+ event.emit(name, {
132
+ stopPropagation: () => e.stopPropagation(),
133
+ data: {
134
+ position: this.eventPosition,
135
+ },
136
+ gameObject,
137
+ });
138
+ });
139
+ };
140
+ let A11ySystem = class A11ySystem extends engine.System {
141
+ static { this.systemName = 'A11ySystem'; }
142
+ /**
143
+ *
144
+ * @param opt
145
+ */
146
+ /**
147
+ * 无障碍插件初始化函数
148
+ * @param opt 无障碍插件选项
149
+ * @param opt.activate 是否开启无障碍能力,默认为自动根据系统读屏能力进行开启 AUTO | ENABLE | DISABLE
150
+ * @example
151
+ * // 开启调试,无障碍区域会显示红色透明背景
152
+ * new A11ySystem({debug: true})
153
+ * // 禁用无障碍
154
+ * new A11ySystem({activate: A11yActivate.DISABLE})
155
+ */
156
+ constructor(opt) {
157
+ super(opt);
158
+ this.cache = new Map();
159
+ this.eventCache = new Map();
160
+ /**
161
+ *
162
+ * dom 的 zIndex
163
+ */
164
+ this.zIndex = ZINDEX;
165
+ }
166
+ get ratioX() {
167
+ if (this._ratioX) {
168
+ return this._ratioX;
169
+ }
170
+ else {
171
+ const success = this.setRatio();
172
+ if (success) {
173
+ return this._ratioX;
174
+ }
175
+ else {
176
+ return 0;
177
+ }
178
+ }
179
+ }
180
+ get ratioY() {
181
+ if (this._ratioY) {
182
+ return this._ratioY;
183
+ }
184
+ else {
185
+ const success = this.setRatio();
186
+ if (success) {
187
+ return this._ratioY;
188
+ }
189
+ else {
190
+ return 0;
191
+ }
192
+ }
193
+ }
194
+ async init(opt = {}) {
195
+ const { activate = exports.A11yActivate.CHECK, delay = 100, checkA11yOpen = () => Promise.resolve(false), zIndex } = opt;
196
+ this.delay = delay;
197
+ this.zIndex = zIndex || this.zIndex;
198
+ switch (activate) {
199
+ case exports.A11yActivate.CHECK:
200
+ try {
201
+ this.activate = await checkA11yOpen();
202
+ }
203
+ catch (error) {
204
+ this.activate = false;
205
+ }
206
+ break;
207
+ case exports.A11yActivate.DISABLE:
208
+ this.activate = false;
209
+ break;
210
+ case exports.A11yActivate.ENABLE:
211
+ this.activate = true;
212
+ break;
213
+ }
214
+ this.debug = opt.debug || false;
215
+ if (this.debug) {
216
+ this.activate = true;
217
+ }
218
+ if (!this.activate)
219
+ return;
220
+ // 渲染出父容器
221
+ const div = document.createElement('div');
222
+ this.div = div;
223
+ // 如果存在父容器,则渲染这个 div,子元素则会相对这个 div 进行定位,否则直接相对于 body 进行定位
224
+ if (this.game.canvas.parentNode) {
225
+ this.game.canvas.parentNode.insertBefore(this.div, this.game.canvas);
226
+ }
227
+ }
228
+ setRatio() {
229
+ const { width, height } = this.getCanvasBoundingClientRect();
230
+ const { renderWidth, renderHeight } = this.getRenderRect();
231
+ this._ratioX = width / renderWidth;
232
+ this._ratioY = height / renderHeight;
233
+ if (width || height) {
234
+ this.initDiv();
235
+ return true;
236
+ }
237
+ else {
238
+ return false;
239
+ }
240
+ }
241
+ getRenderRect() {
242
+ const { params = { width: 300, height: 300 } } = this.game.getSystem(pluginRenderer.RendererSystem);
243
+ const { height: renderHeight, width: renderWidth } = params;
244
+ return { renderWidth, renderHeight };
245
+ }
246
+ getCanvasBoundingClientRect() {
247
+ // 渲染画布相对于视口的实际宽高以及位置,实际的像素
248
+ const { width, height, left, top } = this.game.canvas.getBoundingClientRect();
249
+ return { width, height, left, top };
250
+ }
251
+ initDiv() {
252
+ const { pageXOffset, pageYOffset } = window;
253
+ const { width, height, left, top } = this.getCanvasBoundingClientRect();
254
+ // 父容器位置
255
+ const style = {
256
+ width,
257
+ height,
258
+ left: `${left + pageXOffset}px`,
259
+ top: `${top + pageYOffset}px`,
260
+ position: POSITION,
261
+ zIndex: this.zIndex,
262
+ pointerEvents: PointerEvents.NONE,
263
+ background: MaskBackground.NONE,
264
+ };
265
+ setStyle(this.div, style);
266
+ // 给父容器设置捕获事件,用于监听事件坐标
267
+ this.div.addEventListener('click', e => {
268
+ const currentTarget = e.currentTarget;
269
+ const { left, top } = currentTarget.getBoundingClientRect();
270
+ const x = (e.pageX - left) / this.ratioX;
271
+ const y = (e.pageY - top) / this.ratioY;
272
+ this.eventPosition = { x, y };
273
+ }, true);
274
+ }
275
+ /**
276
+ * 监听插件更新
277
+ */
278
+ async update() {
279
+ const changes = this.componentObserver.clear();
280
+ if (!this.activate) {
281
+ return;
282
+ }
283
+ for (const changed of changes) {
284
+ switch (changed.type) {
285
+ case engine.OBSERVER_TYPE.ADD:
286
+ changed.componentName === 'Event' && this.addEvent(changed.gameObject);
287
+ changed.componentName === 'A11y' && this.add(changed);
288
+ break;
289
+ case engine.OBSERVER_TYPE.CHANGE:
290
+ changed.componentName === 'Transform' && this.transformChange(changed);
291
+ changed.componentName === 'A11y' && this.change(changed);
292
+ break;
293
+ case engine.OBSERVER_TYPE.REMOVE:
294
+ changed.componentName === 'Event' && this.removeEvent(changed);
295
+ changed.componentName === 'A11y' && this.remove(changed);
296
+ }
297
+ }
298
+ }
299
+ change(changed) {
300
+ const component = changed.component;
301
+ if (changed.prop.prop[0] === 'hint') {
302
+ const dom = this.cache.get(component.a11yId);
303
+ dom?.setAttribute('aria-label', component.hint);
304
+ dom && this.setPosition(dom, changed.gameObject.transform);
305
+ }
306
+ }
307
+ remove(changed) {
308
+ const component = changed.component;
309
+ if (!component)
310
+ return;
311
+ const { a11yId } = component;
312
+ const element = this.div.querySelector(`#${a11yId}`);
313
+ element && this.div.removeChild(element);
314
+ this.cache.delete(a11yId);
315
+ }
316
+ /**
317
+ * 监听组件被添加至游戏对象
318
+ * @param changed 改变的组件
319
+ */
320
+ add(changed) {
321
+ if (!this.activate)
322
+ return;
323
+ const component = changed.component;
324
+ const { gameObject } = changed;
325
+ const { delay, a11yId: id } = component;
326
+ let { event } = component;
327
+ if (!gameObject)
328
+ return;
329
+ const { transform } = gameObject;
330
+ if (!transform)
331
+ return;
332
+ const element = document.createElement('div');
333
+ this.cache.set(id, element);
334
+ if (!event) {
335
+ event = gameObject.getComponent('Event');
336
+ }
337
+ setTimeout(() => {
338
+ this.setPosition(element, transform);
339
+ this.setA11yAttr(element, component);
340
+ if (event) {
341
+ this.addEvent(gameObject);
342
+ }
343
+ if (gameObject.scene) {
344
+ this.div.appendChild(element);
345
+ }
346
+ }, delay || this.delay);
347
+ }
348
+ // 监听 scene 改变
349
+ transformChange(changed) {
350
+ const component = changed.component;
351
+ const { gameObject } = changed;
352
+ const a11yComponent = gameObject.getComponent(A11y);
353
+ if (!a11yComponent)
354
+ return;
355
+ const { a11yId } = a11yComponent;
356
+ if (!component.inScene) {
357
+ // 监听 scene 删除游戏对象
358
+ const dom = this.div.querySelector(`#${a11yId}`);
359
+ dom && this.div.removeChild(dom);
360
+ // this.cache.delete(a11yId)
361
+ }
362
+ else {
363
+ // 监听 scene add
364
+ // this.div.appendChild(this.cache)
365
+ if (this.cache.has(a11yId)) {
366
+ const addDom = this.cache.get(a11yId);
367
+ addDom && this.div.appendChild(addDom);
368
+ }
369
+ }
370
+ }
371
+ /**
372
+ * 为无障碍组件设置监听事件
373
+ * @param element DOM 元素
374
+ * @param event 事件组件对象
375
+ * @param gameObject 游戏对象
376
+ */
377
+ setEvent(element, event, gameObject, id) {
378
+ if (!event) {
379
+ return;
380
+ }
381
+ const func = getEventFunc.bind(this, event, gameObject);
382
+ this.eventCache.set(id, func);
383
+ element.addEventListener('click', func);
384
+ }
385
+ addEvent(gameObject) {
386
+ const a11y = gameObject.getComponent(A11y);
387
+ if (!a11y)
388
+ return;
389
+ const event = gameObject.getComponent('Event');
390
+ if (!event)
391
+ return;
392
+ const element = this.cache.get(a11y.a11yId);
393
+ element && this.setEvent(element, event, gameObject, a11y.a11yId);
394
+ }
395
+ removeEvent(changed) {
396
+ const { gameObject } = changed;
397
+ const a11y = gameObject.getComponent(A11y);
398
+ if (!a11y)
399
+ return;
400
+ const event = changed.component;
401
+ if (!event)
402
+ return;
403
+ const { a11yId } = a11y;
404
+ const func = this.eventCache.get(a11yId);
405
+ const element = this.cache.get(a11yId);
406
+ element && element.removeEventListener('click', func);
407
+ }
408
+ /**
409
+ * 设置无障碍属性标签
410
+ * @param element DOM 元素
411
+ * @param hint 无障碍朗读文字
412
+ * @param interactive 是否可交互
413
+ */
414
+ setA11yAttr(element, component) {
415
+ const { hint, props = {}, state = {}, role, a11yId: id } = component;
416
+ const realRole = role || 'text';
417
+ element.setAttribute('role', realRole);
418
+ element.setAttribute('aria-label', hint);
419
+ element.id = id;
420
+ // 这里兼容
421
+ const ariaProps = Object.keys(props);
422
+ for (const key of ariaProps) {
423
+ element.setAttribute(key, props[key]);
424
+ }
425
+ const ariaState = Object.keys(state);
426
+ for (const key of ariaState) {
427
+ element.setAttribute(key, state[key]);
428
+ }
429
+ for (const key of Object.keys(component)) {
430
+ if (typeof component[key] === 'string' && notAttr.indexOf(key) === -1 && key.indexOf('_') !== 1) {
431
+ element.setAttribute(key, component[key]);
432
+ }
433
+ }
434
+ }
435
+ /**
436
+ * 将无障碍元素设置到对应的位置
437
+ * @param element DOM 元素
438
+ * @param transform 位置属性
439
+ */
440
+ setPosition(element, transform) {
441
+ // 相对画布定位
442
+ // const { x: anchorX, y: anchorY } = transform.anchor
443
+ // 游戏对象的宽高
444
+ const { width, height } = transform.size;
445
+ // position
446
+ // const { x: positionX, y: positionY } = transform.position
447
+ // 设置无障碍 DOM 的样式,龙骨动画默认 2px
448
+ const style = {
449
+ width: width === 0 ? 1 : width * this.ratioX,
450
+ height: height === 0 ? 1 : height * this.ratioY,
451
+ position: POSITION,
452
+ zIndex: this.zIndex,
453
+ pointerEvents: PointerEvents.AUTO,
454
+ background: this.debug ? MaskBackground.DEBUG : MaskBackground.NONE,
455
+ };
456
+ const transformProps = {
457
+ ...transform,
458
+ };
459
+ setStyle(element, style);
460
+ // 调整 DOM 的位置
461
+ setTransform(element, transformProps, this.ratioX, this.ratioY);
462
+ }
463
+ onDestroy() {
464
+ this.div.parentElement.removeChild(this.div);
465
+ this.cache = null;
466
+ this.eventCache = null;
467
+ this.div = null;
468
+ }
469
+ };
470
+ A11ySystem = tslib.__decorate([
471
+ engine.decorators.componentObserver({
472
+ A11y: ['hint'],
473
+ Transform: ['inScene'],
474
+ Event: [],
475
+ })
476
+ ], A11ySystem);
477
+ var A11ySystem_default = A11ySystem;
478
+
479
+ exports.A11y = A11y;
480
+ exports.A11ySystem = A11ySystem_default;
481
+ //# sourceMappingURL=plugin-a11y.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-a11y.cjs.js","sources":["../lib/utils.ts","../lib/A11y.ts","../lib/constant.ts","../lib/A11ySystem.ts"],"sourcesContent":["import { A11yMaskStyle } from './constant';\n\n/**\n * 生成唯一的标识符\n * @param len 长度\n * @param radix 基\n */\nfunction uuid(len: number) {\n let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');\n let uuid = [];\n let radix = chars.length;\n for (let i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];\n return uuid.join('');\n}\n\n/**\n * 设置 dom 样式\n * @param div 需要设置样式的dom元素\n * @param style 样式属性\n */\nconst setStyle = (element: HTMLElement, style: A11yMaskStyle) => {\n const { width, height, position, left = 0, top = 0, zIndex, pointerEvents, background } = style;\n element.style.width = `${width}px`;\n element.style.height = `${height}px`;\n element.style.position = position;\n element.style.left = `${left}`;\n element.style.top = `${top}`;\n element.style.zIndex = `${zIndex}`;\n element.style.pointerEvents = pointerEvents;\n element.style.background = background;\n element.style.border = 'none';\n element.style.overflow = 'hidden';\n};\n\nconst setTransform = (element: HTMLElement, transform, ratioX, ratioY) => {\n const { worldTransform } = transform;\n const { a, b, c, d, tx, ty } = worldTransform;\n const matrix = `matrix(${a}, ${b}, ${c}, ${d}, ${tx * ratioX}, ${ty * ratioY})`;\n element.style.transform = `${matrix}`;\n element.style.webkitTransform = `${matrix}`;\n element.style.transformOrigin = 'left top';\n element.style.webkitTransformOrigin = 'left top';\n};\n\nexport { setStyle, setTransform, uuid };\n","import {Component} from '@combos-fun/engine';\nimport {type, step} from '@combos-fun/inspector-decorator';\nimport {uuid} from './utils';\n\nexport interface A11yParams {\n hint: string;\n event?: Component;\n delay?: number;\n role?: string;\n props?: object;\n state?: object;\n attr?: object;\n a11yId?: string;\n [propName: string]: string | object | number;\n}\n\nexport default class A11y extends Component<A11yParams> {\n static componentName: string = 'A11y';\n\n /**\n * 是否可交互\n */\n @type('boolean') interactive: boolean;\n /**\n * 无障碍标签朗读内容\n */\n @type('string') hint: string;\n /**\n * 弃用,将根据Event组件自动添加\n * 事件对象\n */\n event: Component;\n /**\n * 延时加载时间(millisecond)\n */\n @type('number') @step(1) delay: number;\n\n /**\n * role 属性\n */\n @type('string') role: string;\n\n /**\n * 弃用,将属性写在component上\n * aria-value 属性\n * @example\n * aria-valuemin = \"0\"\n */\n props: object;\n\n /**\n * 弃用,将属性写在component上\n * aria state 属性\n * @example\n * aria-hidden = \"true\"\n */\n state: object;\n\n /**\n * 弃用,将属性写在component上\n * 传入自定义属性\n */\n attr: object;\n\n /**\n * 辅助Dom id 自动生成\n */\n @type('string') a11yId: string;\n\n /**\n * 无障碍组件构造函数\n * @param param interactive 默认为 false,如果游戏对象可交互,传入 true\n * @example\n * // 为游戏对象提供朗读能力\n * new A11y({hint: '这是一个div'})\n * // 游戏对象有事件,传入 event 对象\n * new A11y({hint: '点击事件对象', event: event})\n * // 无障碍属性\n * new A11y({hint:'按钮', role: 'button', state: {aria-hidden=\"true\"}})\n * // 自定义属性\n * new A11y({hint: '自定义属性', attr: {key: '1'}})\n */\n constructor(param: A11yParams) {\n super();\n Object.assign(this, param);\n const { hint = '', event, delay = 0, attr = {}, role = '', props = {}, state = {} } = param;\n this.hint = hint;\n this.event = event;\n this.delay = delay;\n this.attr = attr;\n this.role = role;\n this.props = props;\n this.state = state;\n this.a11yId = `_${uuid(6)}`;\n }\n}\n","export const POSITION = 'absolute';\nexport const ZINDEX = 3;\n\nexport enum A11yActivate {\n ENABLE = 0,\n DISABLE = 1,\n CHECK = 2,\n}\n\n/**\n * 无障碍 DOM 的指针事件\n */\nexport enum PointerEvents {\n NONE = 'none', // 元素不会成为鼠标事件的target,会被穿透\n AUTO = 'auto', // 默认值正常\n}\n\n/**\n * 无障碍 DOM 层的样式\n */\nexport enum MaskBackground {\n DEBUG = 'rgba(255,0,0,0.5)',\n NONE = 'transparent',\n}\n\n/**\n * 无障碍 DOM 的类型\n */\nexport enum ElementType {\n BUTTON = 'button',\n DIV = 'div',\n}\n\n/**\n * 无障碍遮罩层样式\n */\nexport interface A11yMaskStyle {\n width: number;\n height: number;\n background: string;\n position: string;\n left?: string;\n top?: string;\n zIndex: number;\n pointerEvents: PointerEvents;\n}\n\n/**\n * 点击事件位置\n */\nexport interface EventPosition {\n x: number;\n y: number;\n}\n","import { System, decorators, ComponentChanged, Transform, OBSERVER_TYPE } from '@combos-fun/engine';\nimport type { GameObject } from '@combos-fun/engine';\nimport { RendererSystem } from '@combos-fun/plugin-renderer';\nimport EE from 'eventemitter3';\n\nimport A11y from './A11y';\nimport { setStyle, setTransform } from './utils';\nimport {\n POSITION,\n ZINDEX,\n PointerEvents,\n MaskBackground,\n EventPosition,\n A11yMaskStyle,\n A11yActivate,\n} from './constant';\n\ninterface SystemParam {\n debug?: boolean;\n activate?: A11yActivate;\n delay?: number;\n zIndex?: number;\n checkA11yOpen?: () => Promise<boolean>;\n}\n\nconst notAttr = ['hint', 'event', 'delay', 'attr', 'role', 'props', 'state', 'a11yId', 'name'];\n\nconst getEventFunc = function (event: EE, gameObject: GameObject, e: MouseEvent) {\n ['touchstart', 'touchend', 'tap'].forEach(name => {\n event.emit(name, {\n stopPropagation: () => e.stopPropagation(),\n data: {\n position: this.eventPosition,\n },\n gameObject,\n });\n });\n};\n\n@decorators.componentObserver({\n A11y: ['hint'],\n Transform: ['inScene'],\n Event: [],\n})\nexport default class A11ySystem extends System {\n static systemName = 'A11ySystem';\n\n /**\n * 无障碍覆盖层\n */\n div: HTMLDivElement;\n /**\n * 是否开启调试\n */\n debug: boolean;\n /**\n * 横向的比例\n */\n _ratioX: number;\n /**\n * 纵向的比例\n */\n _ratioY: number;\n /**\n * 事件坐标\n */\n eventPosition: EventPosition;\n /**\n * 是否开启无障碍能力\n */\n activate: boolean;\n /**\n * dom 延迟放置\n */\n delay: number;\n cache: Map<string, HTMLElement> = new Map();\n eventCache: Map<string, (e: MouseEvent) => void> = new Map();\n /**\n * \n * dom 的 zIndex\n */\n zIndex: number = ZINDEX;\n /**\n *\n * @param opt\n */\n\n /**\n * 无障碍插件初始化函数\n * @param opt 无障碍插件选项\n * @param opt.activate 是否开启无障碍能力,默认为自动根据系统读屏能力进行开启 AUTO | ENABLE | DISABLE\n * @example\n * // 开启调试,无障碍区域会显示红色透明背景\n * new A11ySystem({debug: true})\n * // 禁用无障碍\n * new A11ySystem({activate: A11yActivate.DISABLE})\n */\n constructor(opt?: SystemParam) {\n super(opt);\n }\n\n get ratioX() {\n if (this._ratioX) {\n return this._ratioX;\n } else {\n const success = this.setRatio();\n if (success) {\n return this._ratioX;\n } else {\n return 0;\n }\n }\n }\n get ratioY() {\n if (this._ratioY) {\n return this._ratioY;\n } else {\n const success = this.setRatio();\n if (success) {\n return this._ratioY;\n } else {\n return 0;\n }\n }\n }\n\n async init(opt: SystemParam = {}) {\n const { activate = A11yActivate.CHECK, delay = 100, checkA11yOpen = () => Promise.resolve(false), zIndex } = opt;\n this.delay = delay;\n this.zIndex = zIndex || this.zIndex\n switch (activate) {\n case A11yActivate.CHECK:\n try {\n this.activate = await checkA11yOpen();\n } catch (error) {\n this.activate = false;\n }\n break;\n case A11yActivate.DISABLE:\n this.activate = false;\n break;\n case A11yActivate.ENABLE:\n this.activate = true;\n break;\n }\n this.debug = opt.debug || false;\n if (this.debug) {\n this.activate = true;\n }\n\n if (!this.activate) return;\n // 渲染出父容器\n const div = document.createElement('div');\n this.div = div;\n // 如果存在父容器,则渲染这个 div,子元素则会相对这个 div 进行定位,否则直接相对于 body 进行定位\n if (this.game.canvas.parentNode) {\n this.game.canvas.parentNode.insertBefore(this.div, this.game.canvas);\n }\n }\n setRatio() {\n const { width, height } = this.getCanvasBoundingClientRect();\n const { renderWidth, renderHeight } = this.getRenderRect();\n this._ratioX = width / renderWidth;\n this._ratioY = height / renderHeight;\n if (width || height) {\n this.initDiv();\n return true;\n } else {\n return false;\n }\n }\n getRenderRect() {\n const { params = { width: 300, height: 300 } } = this.game.getSystem(RendererSystem);\n const { height: renderHeight, width: renderWidth } = params;\n return { renderWidth, renderHeight };\n }\n getCanvasBoundingClientRect() {\n // 渲染画布相对于视口的实际宽高以及位置,实际的像素\n const { width, height, left, top } = this.game.canvas.getBoundingClientRect();\n return { width, height, left, top };\n }\n initDiv() {\n const { pageXOffset, pageYOffset } = window;\n\n const { width, height, left, top } = this.getCanvasBoundingClientRect();\n // 父容器位置\n const style: A11yMaskStyle = {\n width,\n height,\n left: `${left + pageXOffset}px`,\n top: `${top + pageYOffset}px`,\n position: POSITION,\n zIndex: this.zIndex,\n pointerEvents: PointerEvents.NONE,\n background: MaskBackground.NONE,\n };\n setStyle(this.div, style);\n // 给父容器设置捕获事件,用于监听事件坐标\n this.div.addEventListener(\n 'click',\n e => {\n const currentTarget = e.currentTarget as HTMLDivElement;\n const { left, top } = currentTarget.getBoundingClientRect();\n const x = (e.pageX - left) / this.ratioX;\n const y = (e.pageY - top) / this.ratioY;\n this.eventPosition = { x, y };\n },\n true,\n );\n }\n\n /**\n * 监听插件更新\n */\n async update() {\n const changes = this.componentObserver.clear();\n if (!this.activate) {\n return;\n }\n for (const changed of changes) {\n switch (changed.type) {\n case OBSERVER_TYPE.ADD:\n changed.componentName === 'Event' && this.addEvent(changed.gameObject);\n changed.componentName === 'A11y' && this.add(changed);\n break;\n case OBSERVER_TYPE.CHANGE:\n changed.componentName === 'Transform' && this.transformChange(changed);\n changed.componentName === 'A11y' && this.change(changed);\n break;\n case OBSERVER_TYPE.REMOVE:\n changed.componentName === 'Event' && this.removeEvent(changed);\n changed.componentName === 'A11y' && this.remove(changed);\n }\n }\n }\n\n change(changed: ComponentChanged) {\n const component = changed.component as A11y\n if (changed.prop.prop[0] === 'hint') {\n const dom = this.cache.get(component.a11yId)\n dom?.setAttribute('aria-label', component.hint)\n dom && this.setPosition(dom, changed.gameObject.transform)\n }\n }\n\n remove(changed: ComponentChanged) {\n const component = changed.component as A11y;\n if (!component) return;\n const { a11yId } = component;\n const element = this.div.querySelector(`#${a11yId}`);\n element && this.div.removeChild(element);\n this.cache.delete(a11yId);\n }\n\n /**\n * 监听组件被添加至游戏对象\n * @param changed 改变的组件\n */\n add(changed: ComponentChanged) {\n if (!this.activate) return;\n const component = changed.component as A11y;\n const { gameObject } = changed;\n const { delay, a11yId: id } = component;\n let { event } = component;\n if (!gameObject) return;\n const { transform } = gameObject;\n if (!transform) return;\n const element = document.createElement('div');\n this.cache.set(id, element);\n if (!event) {\n event = gameObject.getComponent('Event');\n }\n setTimeout(() => {\n this.setPosition(element, transform);\n this.setA11yAttr(element, component);\n if (event) {\n this.addEvent(gameObject);\n }\n if (gameObject.scene) {\n this.div.appendChild(element);\n }\n }, delay || this.delay);\n }\n\n // 监听 scene 改变\n transformChange(changed: ComponentChanged) {\n const component = changed.component as Transform;\n const { gameObject } = changed;\n const a11yComponent = gameObject.getComponent(A11y) as A11y;\n if (!a11yComponent) return;\n const { a11yId } = a11yComponent;\n if (!component.inScene) {\n // 监听 scene 删除游戏对象\n const dom = this.div.querySelector(`#${a11yId}`);\n dom && this.div.removeChild(dom);\n // this.cache.delete(a11yId)\n } else {\n // 监听 scene add\n // this.div.appendChild(this.cache)\n if (this.cache.has(a11yId)) {\n const addDom = this.cache.get(a11yId);\n addDom && this.div.appendChild(addDom);\n }\n }\n }\n\n /**\n * 为无障碍组件设置监听事件\n * @param element DOM 元素\n * @param event 事件组件对象\n * @param gameObject 游戏对象\n */\n setEvent(element: HTMLElement, event: EE, gameObject: GameObject, id) {\n if (!event) {\n return;\n }\n const func = getEventFunc.bind(this, event, gameObject) as (e: MouseEvent) => void;\n this.eventCache.set(id, func);\n element.addEventListener('click', func);\n }\n\n addEvent(gameObject: GameObject) {\n const a11y = gameObject.getComponent(A11y) as A11y;\n if (!a11y) return;\n const event = gameObject.getComponent('Event');\n if (!event) return;\n const element = this.cache.get(a11y.a11yId);\n element && this.setEvent(element, event, gameObject, a11y.a11yId);\n }\n\n removeEvent(changed: ComponentChanged) {\n const { gameObject } = changed;\n const a11y = gameObject.getComponent(A11y) as A11y;\n if (!a11y) return;\n const event = changed.component;\n if (!event) return;\n const { a11yId } = a11y;\n const func = this.eventCache.get(a11yId);\n const element = this.cache.get(a11yId);\n element && element.removeEventListener('click', func);\n }\n\n /**\n * 设置无障碍属性标签\n * @param element DOM 元素\n * @param hint 无障碍朗读文字\n * @param interactive 是否可交互\n */\n setA11yAttr(element: HTMLElement, component: A11y) {\n const { hint, props = {}, state = {}, role, a11yId: id } = component;\n const realRole = role || 'text';\n element.setAttribute('role', realRole);\n element.setAttribute('aria-label', hint);\n element.id = id;\n\n // 这里兼容\n const ariaProps = Object.keys(props);\n for (const key of ariaProps) {\n element.setAttribute(key, props[key]);\n }\n const ariaState = Object.keys(state);\n for (const key of ariaState) {\n element.setAttribute(key, state[key]);\n }\n\n for (const key of Object.keys(component)) {\n if (typeof component[key] === 'string' && notAttr.indexOf(key) === -1 && key.indexOf('_') !== 1) {\n element.setAttribute(key, component[key]);\n }\n }\n }\n\n /**\n * 将无障碍元素设置到对应的位置\n * @param element DOM 元素\n * @param transform 位置属性\n */\n setPosition(element: HTMLElement, transform: Transform) {\n // 相对画布定位\n // const { x: anchorX, y: anchorY } = transform.anchor\n // 游戏对象的宽高\n const { width, height } = transform.size;\n // position\n // const { x: positionX, y: positionY } = transform.position\n // 设置无障碍 DOM 的样式,龙骨动画默认 2px\n const style: A11yMaskStyle = {\n width: width === 0 ? 1 : width * this.ratioX,\n height: height === 0 ? 1 : height * this.ratioY,\n position: POSITION,\n zIndex: this.zIndex,\n pointerEvents: PointerEvents.AUTO,\n background: this.debug ? MaskBackground.DEBUG : MaskBackground.NONE,\n };\n const transformProps = {\n ...transform,\n };\n setStyle(element, style);\n // 调整 DOM 的位置\n setTransform(element, transformProps, this.ratioX, this.ratioY);\n }\n onDestroy() {\n this.div.parentElement.removeChild(this.div);\n this.cache = null;\n this.eventCache = null;\n this.div = null\n }\n}\n"],"names":["Component","__decorate","type","step","A11yActivate","System","RendererSystem","OBSERVER_TYPE","decorators"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ "use strict";var t=require("tslib"),e=require("@combos-fun/engine"),i=require("@combos-fun/plugin-renderer"),n=require("@combos-fun/inspector-decorator");const s=(t,e)=>{const{width:i,height:n,position:s,left:o=0,top:r=0,zIndex:a,pointerEvents:c,background:h}=e;t.style.width=`${i}px`,t.style.height=`${n}px`,t.style.position=s,t.style.left=`${o}`,t.style.top=`${r}`,t.style.zIndex=`${a}`,t.style.pointerEvents=c,t.style.background=h,t.style.border="none",t.style.overflow="hidden"};class o extends e.Component{static{this.componentName="A11y"}constructor(t){super(),Object.assign(this,t);const{hint:e="",event:i,delay:n=0,attr:s={},role:o="",props:r={},state:a={}}=t;this.hint=e,this.event=i,this.delay=n,this.attr=s,this.role=o,this.props=r,this.state=a,this.a11yId=`_${function(t){let e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),i=[],n=e.length;for(let s=0;s<t;s++)i[s]=e[0|Math.random()*n];return i.join("")}(6)}`}}t.__decorate([n.type("boolean")],o.prototype,"interactive",void 0),t.__decorate([n.type("string")],o.prototype,"hint",void 0),t.__decorate([n.type("number"),n.step(1)],o.prototype,"delay",void 0),t.__decorate([n.type("string")],o.prototype,"role",void 0),t.__decorate([n.type("string")],o.prototype,"a11yId",void 0);const r="absolute";var a,c,h,d;exports.A11yActivate=void 0,(a=exports.A11yActivate||(exports.A11yActivate={}))[a.ENABLE=0]="ENABLE",a[a.DISABLE=1]="DISABLE",a[a.CHECK=2]="CHECK",function(t){t.NONE="none",t.AUTO="auto"}(c||(c={})),function(t){t.DEBUG="rgba(255,0,0,0.5)",t.NONE="transparent"}(h||(h={})),function(t){t.BUTTON="button",t.DIV="div"}(d||(d={}));const p=["hint","event","delay","attr","role","props","state","a11yId","name"],v=function(t,e,i){["touchstart","touchend","tap"].forEach(n=>{t.emit(n,{stopPropagation:()=>i.stopPropagation(),data:{position:this.eventPosition},gameObject:e})})};let l=class extends e.System{static{this.systemName="A11ySystem"}constructor(t){super(t),this.cache=new Map,this.eventCache=new Map,this.zIndex=3}get ratioX(){if(this._ratioX)return this._ratioX;return this.setRatio()?this._ratioX:0}get ratioY(){if(this._ratioY)return this._ratioY;return this.setRatio()?this._ratioY:0}async init(t={}){const{activate:e=exports.A11yActivate.CHECK,delay:i=100,checkA11yOpen:n=()=>Promise.resolve(!1),zIndex:s}=t;switch(this.delay=i,this.zIndex=s||this.zIndex,e){case exports.A11yActivate.CHECK:try{this.activate=await n()}catch(t){this.activate=!1}break;case exports.A11yActivate.DISABLE:this.activate=!1;break;case exports.A11yActivate.ENABLE:this.activate=!0}if(this.debug=t.debug||!1,this.debug&&(this.activate=!0),!this.activate)return;const o=document.createElement("div");this.div=o,this.game.canvas.parentNode&&this.game.canvas.parentNode.insertBefore(this.div,this.game.canvas)}setRatio(){const{width:t,height:e}=this.getCanvasBoundingClientRect(),{renderWidth:i,renderHeight:n}=this.getRenderRect();return this._ratioX=t/i,this._ratioY=e/n,!(!t&&!e)&&(this.initDiv(),!0)}getRenderRect(){const{params:t={width:300,height:300}}=this.game.getSystem(i.RendererSystem),{height:e,width:n}=t;return{renderWidth:n,renderHeight:e}}getCanvasBoundingClientRect(){const{width:t,height:e,left:i,top:n}=this.game.canvas.getBoundingClientRect();return{width:t,height:e,left:i,top:n}}initDiv(){const{pageXOffset:t,pageYOffset:e}=window,{width:i,height:n,left:o,top:a}=this.getCanvasBoundingClientRect(),d={width:i,height:n,left:`${o+t}px`,top:`${a+e}px`,position:r,zIndex:this.zIndex,pointerEvents:c.NONE,background:h.NONE};s(this.div,d),this.div.addEventListener("click",t=>{const e=t.currentTarget,{left:i,top:n}=e.getBoundingClientRect(),s=(t.pageX-i)/this.ratioX,o=(t.pageY-n)/this.ratioY;this.eventPosition={x:s,y:o}},!0)}async update(){const t=this.componentObserver.clear();if(this.activate)for(const i of t)switch(i.type){case e.OBSERVER_TYPE.ADD:"Event"===i.componentName&&this.addEvent(i.gameObject),"A11y"===i.componentName&&this.add(i);break;case e.OBSERVER_TYPE.CHANGE:"Transform"===i.componentName&&this.transformChange(i),"A11y"===i.componentName&&this.change(i);break;case e.OBSERVER_TYPE.REMOVE:"Event"===i.componentName&&this.removeEvent(i),"A11y"===i.componentName&&this.remove(i)}}change(t){const e=t.component;if("hint"===t.prop.prop[0]){const i=this.cache.get(e.a11yId);i?.setAttribute("aria-label",e.hint),i&&this.setPosition(i,t.gameObject.transform)}}remove(t){const e=t.component;if(!e)return;const{a11yId:i}=e,n=this.div.querySelector(`#${i}`);n&&this.div.removeChild(n),this.cache.delete(i)}add(t){if(!this.activate)return;const e=t.component,{gameObject:i}=t,{delay:n,a11yId:s}=e;let{event:o}=e;if(!i)return;const{transform:r}=i;if(!r)return;const a=document.createElement("div");this.cache.set(s,a),o||(o=i.getComponent("Event")),setTimeout(()=>{this.setPosition(a,r),this.setA11yAttr(a,e),o&&this.addEvent(i),i.scene&&this.div.appendChild(a)},n||this.delay)}transformChange(t){const e=t.component,{gameObject:i}=t,n=i.getComponent(o);if(!n)return;const{a11yId:s}=n;if(e.inScene){if(this.cache.has(s)){const t=this.cache.get(s);t&&this.div.appendChild(t)}}else{const t=this.div.querySelector(`#${s}`);t&&this.div.removeChild(t)}}setEvent(t,e,i,n){if(!e)return;const s=v.bind(this,e,i);this.eventCache.set(n,s),t.addEventListener("click",s)}addEvent(t){const e=t.getComponent(o);if(!e)return;const i=t.getComponent("Event");if(!i)return;const n=this.cache.get(e.a11yId);n&&this.setEvent(n,i,t,e.a11yId)}removeEvent(t){const{gameObject:e}=t,i=e.getComponent(o);if(!i)return;if(!t.component)return;const{a11yId:n}=i,s=this.eventCache.get(n),r=this.cache.get(n);r&&r.removeEventListener("click",s)}setA11yAttr(t,e){const{hint:i,props:n={},state:s={},role:o,a11yId:r}=e,a=o||"text";t.setAttribute("role",a),t.setAttribute("aria-label",i),t.id=r;const c=Object.keys(n);for(const e of c)t.setAttribute(e,n[e]);const h=Object.keys(s);for(const e of h)t.setAttribute(e,s[e]);for(const i of Object.keys(e))"string"==typeof e[i]&&-1===p.indexOf(i)&&1!==i.indexOf("_")&&t.setAttribute(i,e[i])}setPosition(t,e){const{width:i,height:n}=e.size,o={width:0===i?1:i*this.ratioX,height:0===n?1:n*this.ratioY,position:r,zIndex:this.zIndex,pointerEvents:c.AUTO,background:this.debug?h.DEBUG:h.NONE},a={...e};s(t,o),((t,e,i,n)=>{const{worldTransform:s}=e,{a:o,b:r,c:a,d:c,tx:h,ty:d}=s,p=`matrix(${o}, ${r}, ${a}, ${c}, ${h*i}, ${d*n})`;t.style.transform=`${p}`,t.style.webkitTransform=`${p}`,t.style.transformOrigin="left top",t.style.webkitTransformOrigin="left top"})(t,a,this.ratioX,this.ratioY)}onDestroy(){this.div.parentElement.removeChild(this.div),this.cache=null,this.eventCache=null,this.div=null}};l=t.__decorate([e.decorators.componentObserver({A11y:["hint"],Transform:["inScene"],Event:[]})],l);var m=l;exports.A11y=o,exports.A11ySystem=m;
@@ -0,0 +1,201 @@
1
+ import { Component, System, ComponentChanged, GameObject, Transform } from '@combos-fun/engine';
2
+ import EE from 'eventemitter3';
3
+
4
+ interface A11yParams {
5
+ hint: string;
6
+ event?: Component;
7
+ delay?: number;
8
+ role?: string;
9
+ props?: object;
10
+ state?: object;
11
+ attr?: object;
12
+ a11yId?: string;
13
+ [propName: string]: string | object | number;
14
+ }
15
+ declare class A11y extends Component<A11yParams> {
16
+ static componentName: string;
17
+ /**
18
+ * 是否可交互
19
+ */
20
+ interactive: boolean;
21
+ /**
22
+ * 无障碍标签朗读内容
23
+ */
24
+ hint: string;
25
+ /**
26
+ * 弃用,将根据Event组件自动添加
27
+ * 事件对象
28
+ */
29
+ event: Component;
30
+ /**
31
+ * 延时加载时间(millisecond)
32
+ */
33
+ delay: number;
34
+ /**
35
+ * role 属性
36
+ */
37
+ role: string;
38
+ /**
39
+ * 弃用,将属性写在component上
40
+ * aria-value 属性
41
+ * @example
42
+ * aria-valuemin = "0"
43
+ */
44
+ props: object;
45
+ /**
46
+ * 弃用,将属性写在component上
47
+ * aria state 属性
48
+ * @example
49
+ * aria-hidden = "true"
50
+ */
51
+ state: object;
52
+ /**
53
+ * 弃用,将属性写在component上
54
+ * 传入自定义属性
55
+ */
56
+ attr: object;
57
+ /**
58
+ * 辅助Dom id 自动生成
59
+ */
60
+ a11yId: string;
61
+ /**
62
+ * 无障碍组件构造函数
63
+ * @param param interactive 默认为 false,如果游戏对象可交互,传入 true
64
+ * @example
65
+ * // 为游戏对象提供朗读能力
66
+ * new A11y({hint: '这是一个div'})
67
+ * // 游戏对象有事件,传入 event 对象
68
+ * new A11y({hint: '点击事件对象', event: event})
69
+ * // 无障碍属性
70
+ * new A11y({hint:'按钮', role: 'button', state: {aria-hidden="true"}})
71
+ * // 自定义属性
72
+ * new A11y({hint: '自定义属性', attr: {key: '1'}})
73
+ */
74
+ constructor(param: A11yParams);
75
+ }
76
+
77
+ declare enum A11yActivate {
78
+ ENABLE = 0,
79
+ DISABLE = 1,
80
+ CHECK = 2
81
+ }
82
+ /**
83
+ * 点击事件位置
84
+ */
85
+ interface EventPosition {
86
+ x: number;
87
+ y: number;
88
+ }
89
+
90
+ interface SystemParam {
91
+ debug?: boolean;
92
+ activate?: A11yActivate;
93
+ delay?: number;
94
+ zIndex?: number;
95
+ checkA11yOpen?: () => Promise<boolean>;
96
+ }
97
+ declare class A11ySystem extends System {
98
+ static systemName: string;
99
+ /**
100
+ * 无障碍覆盖层
101
+ */
102
+ div: HTMLDivElement;
103
+ /**
104
+ * 是否开启调试
105
+ */
106
+ debug: boolean;
107
+ /**
108
+ * 横向的比例
109
+ */
110
+ _ratioX: number;
111
+ /**
112
+ * 纵向的比例
113
+ */
114
+ _ratioY: number;
115
+ /**
116
+ * 事件坐标
117
+ */
118
+ eventPosition: EventPosition;
119
+ /**
120
+ * 是否开启无障碍能力
121
+ */
122
+ activate: boolean;
123
+ /**
124
+ * dom 延迟放置
125
+ */
126
+ delay: number;
127
+ cache: Map<string, HTMLElement>;
128
+ eventCache: Map<string, (e: MouseEvent) => void>;
129
+ /**
130
+ *
131
+ * dom 的 zIndex
132
+ */
133
+ zIndex: number;
134
+ /**
135
+ *
136
+ * @param opt
137
+ */
138
+ /**
139
+ * 无障碍插件初始化函数
140
+ * @param opt 无障碍插件选项
141
+ * @param opt.activate 是否开启无障碍能力,默认为自动根据系统读屏能力进行开启 AUTO | ENABLE | DISABLE
142
+ * @example
143
+ * // 开启调试,无障碍区域会显示红色透明背景
144
+ * new A11ySystem({debug: true})
145
+ * // 禁用无障碍
146
+ * new A11ySystem({activate: A11yActivate.DISABLE})
147
+ */
148
+ constructor(opt?: SystemParam);
149
+ get ratioX(): number;
150
+ get ratioY(): number;
151
+ init(opt?: SystemParam): Promise<void>;
152
+ setRatio(): boolean;
153
+ getRenderRect(): {
154
+ renderWidth: number;
155
+ renderHeight: number;
156
+ };
157
+ getCanvasBoundingClientRect(): {
158
+ width: number;
159
+ height: number;
160
+ left: number;
161
+ top: number;
162
+ };
163
+ initDiv(): void;
164
+ /**
165
+ * 监听插件更新
166
+ */
167
+ update(): Promise<void>;
168
+ change(changed: ComponentChanged): void;
169
+ remove(changed: ComponentChanged): void;
170
+ /**
171
+ * 监听组件被添加至游戏对象
172
+ * @param changed 改变的组件
173
+ */
174
+ add(changed: ComponentChanged): void;
175
+ transformChange(changed: ComponentChanged): void;
176
+ /**
177
+ * 为无障碍组件设置监听事件
178
+ * @param element DOM 元素
179
+ * @param event 事件组件对象
180
+ * @param gameObject 游戏对象
181
+ */
182
+ setEvent(element: HTMLElement, event: EE, gameObject: GameObject, id: any): void;
183
+ addEvent(gameObject: GameObject): void;
184
+ removeEvent(changed: ComponentChanged): void;
185
+ /**
186
+ * 设置无障碍属性标签
187
+ * @param element DOM 元素
188
+ * @param hint 无障碍朗读文字
189
+ * @param interactive 是否可交互
190
+ */
191
+ setA11yAttr(element: HTMLElement, component: A11y): void;
192
+ /**
193
+ * 将无障碍元素设置到对应的位置
194
+ * @param element DOM 元素
195
+ * @param transform 位置属性
196
+ */
197
+ setPosition(element: HTMLElement, transform: Transform): void;
198
+ onDestroy(): void;
199
+ }
200
+
201
+ export { A11y, A11yActivate, A11ySystem };
@@ -0,0 +1,478 @@
1
+ import { __decorate } from 'tslib';
2
+ import { Component, System, OBSERVER_TYPE, decorators } from '@combos-fun/engine';
3
+ import { RendererSystem } from '@combos-fun/plugin-renderer';
4
+ import { type, step } from '@combos-fun/inspector-decorator';
5
+
6
+ /**
7
+ * 生成唯一的标识符
8
+ * @param len 长度
9
+ * @param radix 基
10
+ */
11
+ function uuid(len) {
12
+ let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
13
+ let uuid = [];
14
+ let radix = chars.length;
15
+ for (let i = 0; i < len; i++)
16
+ uuid[i] = chars[0 | (Math.random() * radix)];
17
+ return uuid.join('');
18
+ }
19
+ /**
20
+ * 设置 dom 样式
21
+ * @param div 需要设置样式的dom元素
22
+ * @param style 样式属性
23
+ */
24
+ const setStyle = (element, style) => {
25
+ const { width, height, position, left = 0, top = 0, zIndex, pointerEvents, background } = style;
26
+ element.style.width = `${width}px`;
27
+ element.style.height = `${height}px`;
28
+ element.style.position = position;
29
+ element.style.left = `${left}`;
30
+ element.style.top = `${top}`;
31
+ element.style.zIndex = `${zIndex}`;
32
+ element.style.pointerEvents = pointerEvents;
33
+ element.style.background = background;
34
+ element.style.border = 'none';
35
+ element.style.overflow = 'hidden';
36
+ };
37
+ const setTransform = (element, transform, ratioX, ratioY) => {
38
+ const { worldTransform } = transform;
39
+ const { a, b, c, d, tx, ty } = worldTransform;
40
+ const matrix = `matrix(${a}, ${b}, ${c}, ${d}, ${tx * ratioX}, ${ty * ratioY})`;
41
+ element.style.transform = `${matrix}`;
42
+ element.style.webkitTransform = `${matrix}`;
43
+ element.style.transformOrigin = 'left top';
44
+ element.style.webkitTransformOrigin = 'left top';
45
+ };
46
+
47
+ class A11y extends Component {
48
+ static { this.componentName = 'A11y'; }
49
+ /**
50
+ * 无障碍组件构造函数
51
+ * @param param interactive 默认为 false,如果游戏对象可交互,传入 true
52
+ * @example
53
+ * // 为游戏对象提供朗读能力
54
+ * new A11y({hint: '这是一个div'})
55
+ * // 游戏对象有事件,传入 event 对象
56
+ * new A11y({hint: '点击事件对象', event: event})
57
+ * // 无障碍属性
58
+ * new A11y({hint:'按钮', role: 'button', state: {aria-hidden="true"}})
59
+ * // 自定义属性
60
+ * new A11y({hint: '自定义属性', attr: {key: '1'}})
61
+ */
62
+ constructor(param) {
63
+ super();
64
+ Object.assign(this, param);
65
+ const { hint = '', event, delay = 0, attr = {}, role = '', props = {}, state = {} } = param;
66
+ this.hint = hint;
67
+ this.event = event;
68
+ this.delay = delay;
69
+ this.attr = attr;
70
+ this.role = role;
71
+ this.props = props;
72
+ this.state = state;
73
+ this.a11yId = `_${uuid(6)}`;
74
+ }
75
+ }
76
+ __decorate([
77
+ type('boolean')
78
+ ], A11y.prototype, "interactive", void 0);
79
+ __decorate([
80
+ type('string')
81
+ ], A11y.prototype, "hint", void 0);
82
+ __decorate([
83
+ type('number'),
84
+ step(1)
85
+ ], A11y.prototype, "delay", void 0);
86
+ __decorate([
87
+ type('string')
88
+ ], A11y.prototype, "role", void 0);
89
+ __decorate([
90
+ type('string')
91
+ ], A11y.prototype, "a11yId", void 0);
92
+
93
+ const POSITION = 'absolute';
94
+ const ZINDEX = 3;
95
+ var A11yActivate;
96
+ (function (A11yActivate) {
97
+ A11yActivate[A11yActivate["ENABLE"] = 0] = "ENABLE";
98
+ A11yActivate[A11yActivate["DISABLE"] = 1] = "DISABLE";
99
+ A11yActivate[A11yActivate["CHECK"] = 2] = "CHECK";
100
+ })(A11yActivate || (A11yActivate = {}));
101
+ /**
102
+ * 无障碍 DOM 的指针事件
103
+ */
104
+ var PointerEvents;
105
+ (function (PointerEvents) {
106
+ PointerEvents["NONE"] = "none";
107
+ PointerEvents["AUTO"] = "auto";
108
+ })(PointerEvents || (PointerEvents = {}));
109
+ /**
110
+ * 无障碍 DOM 层的样式
111
+ */
112
+ var MaskBackground;
113
+ (function (MaskBackground) {
114
+ MaskBackground["DEBUG"] = "rgba(255,0,0,0.5)";
115
+ MaskBackground["NONE"] = "transparent";
116
+ })(MaskBackground || (MaskBackground = {}));
117
+ /**
118
+ * 无障碍 DOM 的类型
119
+ */
120
+ var ElementType;
121
+ (function (ElementType) {
122
+ ElementType["BUTTON"] = "button";
123
+ ElementType["DIV"] = "div";
124
+ })(ElementType || (ElementType = {}));
125
+
126
+ const notAttr = ['hint', 'event', 'delay', 'attr', 'role', 'props', 'state', 'a11yId', 'name'];
127
+ const getEventFunc = function (event, gameObject, e) {
128
+ ['touchstart', 'touchend', 'tap'].forEach(name => {
129
+ event.emit(name, {
130
+ stopPropagation: () => e.stopPropagation(),
131
+ data: {
132
+ position: this.eventPosition,
133
+ },
134
+ gameObject,
135
+ });
136
+ });
137
+ };
138
+ let A11ySystem = class A11ySystem extends System {
139
+ static { this.systemName = 'A11ySystem'; }
140
+ /**
141
+ *
142
+ * @param opt
143
+ */
144
+ /**
145
+ * 无障碍插件初始化函数
146
+ * @param opt 无障碍插件选项
147
+ * @param opt.activate 是否开启无障碍能力,默认为自动根据系统读屏能力进行开启 AUTO | ENABLE | DISABLE
148
+ * @example
149
+ * // 开启调试,无障碍区域会显示红色透明背景
150
+ * new A11ySystem({debug: true})
151
+ * // 禁用无障碍
152
+ * new A11ySystem({activate: A11yActivate.DISABLE})
153
+ */
154
+ constructor(opt) {
155
+ super(opt);
156
+ this.cache = new Map();
157
+ this.eventCache = new Map();
158
+ /**
159
+ *
160
+ * dom 的 zIndex
161
+ */
162
+ this.zIndex = ZINDEX;
163
+ }
164
+ get ratioX() {
165
+ if (this._ratioX) {
166
+ return this._ratioX;
167
+ }
168
+ else {
169
+ const success = this.setRatio();
170
+ if (success) {
171
+ return this._ratioX;
172
+ }
173
+ else {
174
+ return 0;
175
+ }
176
+ }
177
+ }
178
+ get ratioY() {
179
+ if (this._ratioY) {
180
+ return this._ratioY;
181
+ }
182
+ else {
183
+ const success = this.setRatio();
184
+ if (success) {
185
+ return this._ratioY;
186
+ }
187
+ else {
188
+ return 0;
189
+ }
190
+ }
191
+ }
192
+ async init(opt = {}) {
193
+ const { activate = A11yActivate.CHECK, delay = 100, checkA11yOpen = () => Promise.resolve(false), zIndex } = opt;
194
+ this.delay = delay;
195
+ this.zIndex = zIndex || this.zIndex;
196
+ switch (activate) {
197
+ case A11yActivate.CHECK:
198
+ try {
199
+ this.activate = await checkA11yOpen();
200
+ }
201
+ catch (error) {
202
+ this.activate = false;
203
+ }
204
+ break;
205
+ case A11yActivate.DISABLE:
206
+ this.activate = false;
207
+ break;
208
+ case A11yActivate.ENABLE:
209
+ this.activate = true;
210
+ break;
211
+ }
212
+ this.debug = opt.debug || false;
213
+ if (this.debug) {
214
+ this.activate = true;
215
+ }
216
+ if (!this.activate)
217
+ return;
218
+ // 渲染出父容器
219
+ const div = document.createElement('div');
220
+ this.div = div;
221
+ // 如果存在父容器,则渲染这个 div,子元素则会相对这个 div 进行定位,否则直接相对于 body 进行定位
222
+ if (this.game.canvas.parentNode) {
223
+ this.game.canvas.parentNode.insertBefore(this.div, this.game.canvas);
224
+ }
225
+ }
226
+ setRatio() {
227
+ const { width, height } = this.getCanvasBoundingClientRect();
228
+ const { renderWidth, renderHeight } = this.getRenderRect();
229
+ this._ratioX = width / renderWidth;
230
+ this._ratioY = height / renderHeight;
231
+ if (width || height) {
232
+ this.initDiv();
233
+ return true;
234
+ }
235
+ else {
236
+ return false;
237
+ }
238
+ }
239
+ getRenderRect() {
240
+ const { params = { width: 300, height: 300 } } = this.game.getSystem(RendererSystem);
241
+ const { height: renderHeight, width: renderWidth } = params;
242
+ return { renderWidth, renderHeight };
243
+ }
244
+ getCanvasBoundingClientRect() {
245
+ // 渲染画布相对于视口的实际宽高以及位置,实际的像素
246
+ const { width, height, left, top } = this.game.canvas.getBoundingClientRect();
247
+ return { width, height, left, top };
248
+ }
249
+ initDiv() {
250
+ const { pageXOffset, pageYOffset } = window;
251
+ const { width, height, left, top } = this.getCanvasBoundingClientRect();
252
+ // 父容器位置
253
+ const style = {
254
+ width,
255
+ height,
256
+ left: `${left + pageXOffset}px`,
257
+ top: `${top + pageYOffset}px`,
258
+ position: POSITION,
259
+ zIndex: this.zIndex,
260
+ pointerEvents: PointerEvents.NONE,
261
+ background: MaskBackground.NONE,
262
+ };
263
+ setStyle(this.div, style);
264
+ // 给父容器设置捕获事件,用于监听事件坐标
265
+ this.div.addEventListener('click', e => {
266
+ const currentTarget = e.currentTarget;
267
+ const { left, top } = currentTarget.getBoundingClientRect();
268
+ const x = (e.pageX - left) / this.ratioX;
269
+ const y = (e.pageY - top) / this.ratioY;
270
+ this.eventPosition = { x, y };
271
+ }, true);
272
+ }
273
+ /**
274
+ * 监听插件更新
275
+ */
276
+ async update() {
277
+ const changes = this.componentObserver.clear();
278
+ if (!this.activate) {
279
+ return;
280
+ }
281
+ for (const changed of changes) {
282
+ switch (changed.type) {
283
+ case OBSERVER_TYPE.ADD:
284
+ changed.componentName === 'Event' && this.addEvent(changed.gameObject);
285
+ changed.componentName === 'A11y' && this.add(changed);
286
+ break;
287
+ case OBSERVER_TYPE.CHANGE:
288
+ changed.componentName === 'Transform' && this.transformChange(changed);
289
+ changed.componentName === 'A11y' && this.change(changed);
290
+ break;
291
+ case OBSERVER_TYPE.REMOVE:
292
+ changed.componentName === 'Event' && this.removeEvent(changed);
293
+ changed.componentName === 'A11y' && this.remove(changed);
294
+ }
295
+ }
296
+ }
297
+ change(changed) {
298
+ const component = changed.component;
299
+ if (changed.prop.prop[0] === 'hint') {
300
+ const dom = this.cache.get(component.a11yId);
301
+ dom?.setAttribute('aria-label', component.hint);
302
+ dom && this.setPosition(dom, changed.gameObject.transform);
303
+ }
304
+ }
305
+ remove(changed) {
306
+ const component = changed.component;
307
+ if (!component)
308
+ return;
309
+ const { a11yId } = component;
310
+ const element = this.div.querySelector(`#${a11yId}`);
311
+ element && this.div.removeChild(element);
312
+ this.cache.delete(a11yId);
313
+ }
314
+ /**
315
+ * 监听组件被添加至游戏对象
316
+ * @param changed 改变的组件
317
+ */
318
+ add(changed) {
319
+ if (!this.activate)
320
+ return;
321
+ const component = changed.component;
322
+ const { gameObject } = changed;
323
+ const { delay, a11yId: id } = component;
324
+ let { event } = component;
325
+ if (!gameObject)
326
+ return;
327
+ const { transform } = gameObject;
328
+ if (!transform)
329
+ return;
330
+ const element = document.createElement('div');
331
+ this.cache.set(id, element);
332
+ if (!event) {
333
+ event = gameObject.getComponent('Event');
334
+ }
335
+ setTimeout(() => {
336
+ this.setPosition(element, transform);
337
+ this.setA11yAttr(element, component);
338
+ if (event) {
339
+ this.addEvent(gameObject);
340
+ }
341
+ if (gameObject.scene) {
342
+ this.div.appendChild(element);
343
+ }
344
+ }, delay || this.delay);
345
+ }
346
+ // 监听 scene 改变
347
+ transformChange(changed) {
348
+ const component = changed.component;
349
+ const { gameObject } = changed;
350
+ const a11yComponent = gameObject.getComponent(A11y);
351
+ if (!a11yComponent)
352
+ return;
353
+ const { a11yId } = a11yComponent;
354
+ if (!component.inScene) {
355
+ // 监听 scene 删除游戏对象
356
+ const dom = this.div.querySelector(`#${a11yId}`);
357
+ dom && this.div.removeChild(dom);
358
+ // this.cache.delete(a11yId)
359
+ }
360
+ else {
361
+ // 监听 scene add
362
+ // this.div.appendChild(this.cache)
363
+ if (this.cache.has(a11yId)) {
364
+ const addDom = this.cache.get(a11yId);
365
+ addDom && this.div.appendChild(addDom);
366
+ }
367
+ }
368
+ }
369
+ /**
370
+ * 为无障碍组件设置监听事件
371
+ * @param element DOM 元素
372
+ * @param event 事件组件对象
373
+ * @param gameObject 游戏对象
374
+ */
375
+ setEvent(element, event, gameObject, id) {
376
+ if (!event) {
377
+ return;
378
+ }
379
+ const func = getEventFunc.bind(this, event, gameObject);
380
+ this.eventCache.set(id, func);
381
+ element.addEventListener('click', func);
382
+ }
383
+ addEvent(gameObject) {
384
+ const a11y = gameObject.getComponent(A11y);
385
+ if (!a11y)
386
+ return;
387
+ const event = gameObject.getComponent('Event');
388
+ if (!event)
389
+ return;
390
+ const element = this.cache.get(a11y.a11yId);
391
+ element && this.setEvent(element, event, gameObject, a11y.a11yId);
392
+ }
393
+ removeEvent(changed) {
394
+ const { gameObject } = changed;
395
+ const a11y = gameObject.getComponent(A11y);
396
+ if (!a11y)
397
+ return;
398
+ const event = changed.component;
399
+ if (!event)
400
+ return;
401
+ const { a11yId } = a11y;
402
+ const func = this.eventCache.get(a11yId);
403
+ const element = this.cache.get(a11yId);
404
+ element && element.removeEventListener('click', func);
405
+ }
406
+ /**
407
+ * 设置无障碍属性标签
408
+ * @param element DOM 元素
409
+ * @param hint 无障碍朗读文字
410
+ * @param interactive 是否可交互
411
+ */
412
+ setA11yAttr(element, component) {
413
+ const { hint, props = {}, state = {}, role, a11yId: id } = component;
414
+ const realRole = role || 'text';
415
+ element.setAttribute('role', realRole);
416
+ element.setAttribute('aria-label', hint);
417
+ element.id = id;
418
+ // 这里兼容
419
+ const ariaProps = Object.keys(props);
420
+ for (const key of ariaProps) {
421
+ element.setAttribute(key, props[key]);
422
+ }
423
+ const ariaState = Object.keys(state);
424
+ for (const key of ariaState) {
425
+ element.setAttribute(key, state[key]);
426
+ }
427
+ for (const key of Object.keys(component)) {
428
+ if (typeof component[key] === 'string' && notAttr.indexOf(key) === -1 && key.indexOf('_') !== 1) {
429
+ element.setAttribute(key, component[key]);
430
+ }
431
+ }
432
+ }
433
+ /**
434
+ * 将无障碍元素设置到对应的位置
435
+ * @param element DOM 元素
436
+ * @param transform 位置属性
437
+ */
438
+ setPosition(element, transform) {
439
+ // 相对画布定位
440
+ // const { x: anchorX, y: anchorY } = transform.anchor
441
+ // 游戏对象的宽高
442
+ const { width, height } = transform.size;
443
+ // position
444
+ // const { x: positionX, y: positionY } = transform.position
445
+ // 设置无障碍 DOM 的样式,龙骨动画默认 2px
446
+ const style = {
447
+ width: width === 0 ? 1 : width * this.ratioX,
448
+ height: height === 0 ? 1 : height * this.ratioY,
449
+ position: POSITION,
450
+ zIndex: this.zIndex,
451
+ pointerEvents: PointerEvents.AUTO,
452
+ background: this.debug ? MaskBackground.DEBUG : MaskBackground.NONE,
453
+ };
454
+ const transformProps = {
455
+ ...transform,
456
+ };
457
+ setStyle(element, style);
458
+ // 调整 DOM 的位置
459
+ setTransform(element, transformProps, this.ratioX, this.ratioY);
460
+ }
461
+ onDestroy() {
462
+ this.div.parentElement.removeChild(this.div);
463
+ this.cache = null;
464
+ this.eventCache = null;
465
+ this.div = null;
466
+ }
467
+ };
468
+ A11ySystem = __decorate([
469
+ decorators.componentObserver({
470
+ A11y: ['hint'],
471
+ Transform: ['inScene'],
472
+ Event: [],
473
+ })
474
+ ], A11ySystem);
475
+ var A11ySystem_default = A11ySystem;
476
+
477
+ export { A11y, A11yActivate, A11ySystem_default as A11ySystem };
478
+ //# sourceMappingURL=plugin-a11y.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-a11y.esm.js","sources":["../lib/utils.ts","../lib/A11y.ts","../lib/constant.ts","../lib/A11ySystem.ts"],"sourcesContent":["import { A11yMaskStyle } from './constant';\n\n/**\n * 生成唯一的标识符\n * @param len 长度\n * @param radix 基\n */\nfunction uuid(len: number) {\n let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');\n let uuid = [];\n let radix = chars.length;\n for (let i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];\n return uuid.join('');\n}\n\n/**\n * 设置 dom 样式\n * @param div 需要设置样式的dom元素\n * @param style 样式属性\n */\nconst setStyle = (element: HTMLElement, style: A11yMaskStyle) => {\n const { width, height, position, left = 0, top = 0, zIndex, pointerEvents, background } = style;\n element.style.width = `${width}px`;\n element.style.height = `${height}px`;\n element.style.position = position;\n element.style.left = `${left}`;\n element.style.top = `${top}`;\n element.style.zIndex = `${zIndex}`;\n element.style.pointerEvents = pointerEvents;\n element.style.background = background;\n element.style.border = 'none';\n element.style.overflow = 'hidden';\n};\n\nconst setTransform = (element: HTMLElement, transform, ratioX, ratioY) => {\n const { worldTransform } = transform;\n const { a, b, c, d, tx, ty } = worldTransform;\n const matrix = `matrix(${a}, ${b}, ${c}, ${d}, ${tx * ratioX}, ${ty * ratioY})`;\n element.style.transform = `${matrix}`;\n element.style.webkitTransform = `${matrix}`;\n element.style.transformOrigin = 'left top';\n element.style.webkitTransformOrigin = 'left top';\n};\n\nexport { setStyle, setTransform, uuid };\n","import {Component} from '@combos-fun/engine';\nimport {type, step} from '@combos-fun/inspector-decorator';\nimport {uuid} from './utils';\n\nexport interface A11yParams {\n hint: string;\n event?: Component;\n delay?: number;\n role?: string;\n props?: object;\n state?: object;\n attr?: object;\n a11yId?: string;\n [propName: string]: string | object | number;\n}\n\nexport default class A11y extends Component<A11yParams> {\n static componentName: string = 'A11y';\n\n /**\n * 是否可交互\n */\n @type('boolean') interactive: boolean;\n /**\n * 无障碍标签朗读内容\n */\n @type('string') hint: string;\n /**\n * 弃用,将根据Event组件自动添加\n * 事件对象\n */\n event: Component;\n /**\n * 延时加载时间(millisecond)\n */\n @type('number') @step(1) delay: number;\n\n /**\n * role 属性\n */\n @type('string') role: string;\n\n /**\n * 弃用,将属性写在component上\n * aria-value 属性\n * @example\n * aria-valuemin = \"0\"\n */\n props: object;\n\n /**\n * 弃用,将属性写在component上\n * aria state 属性\n * @example\n * aria-hidden = \"true\"\n */\n state: object;\n\n /**\n * 弃用,将属性写在component上\n * 传入自定义属性\n */\n attr: object;\n\n /**\n * 辅助Dom id 自动生成\n */\n @type('string') a11yId: string;\n\n /**\n * 无障碍组件构造函数\n * @param param interactive 默认为 false,如果游戏对象可交互,传入 true\n * @example\n * // 为游戏对象提供朗读能力\n * new A11y({hint: '这是一个div'})\n * // 游戏对象有事件,传入 event 对象\n * new A11y({hint: '点击事件对象', event: event})\n * // 无障碍属性\n * new A11y({hint:'按钮', role: 'button', state: {aria-hidden=\"true\"}})\n * // 自定义属性\n * new A11y({hint: '自定义属性', attr: {key: '1'}})\n */\n constructor(param: A11yParams) {\n super();\n Object.assign(this, param);\n const { hint = '', event, delay = 0, attr = {}, role = '', props = {}, state = {} } = param;\n this.hint = hint;\n this.event = event;\n this.delay = delay;\n this.attr = attr;\n this.role = role;\n this.props = props;\n this.state = state;\n this.a11yId = `_${uuid(6)}`;\n }\n}\n","export const POSITION = 'absolute';\nexport const ZINDEX = 3;\n\nexport enum A11yActivate {\n ENABLE = 0,\n DISABLE = 1,\n CHECK = 2,\n}\n\n/**\n * 无障碍 DOM 的指针事件\n */\nexport enum PointerEvents {\n NONE = 'none', // 元素不会成为鼠标事件的target,会被穿透\n AUTO = 'auto', // 默认值正常\n}\n\n/**\n * 无障碍 DOM 层的样式\n */\nexport enum MaskBackground {\n DEBUG = 'rgba(255,0,0,0.5)',\n NONE = 'transparent',\n}\n\n/**\n * 无障碍 DOM 的类型\n */\nexport enum ElementType {\n BUTTON = 'button',\n DIV = 'div',\n}\n\n/**\n * 无障碍遮罩层样式\n */\nexport interface A11yMaskStyle {\n width: number;\n height: number;\n background: string;\n position: string;\n left?: string;\n top?: string;\n zIndex: number;\n pointerEvents: PointerEvents;\n}\n\n/**\n * 点击事件位置\n */\nexport interface EventPosition {\n x: number;\n y: number;\n}\n","import { System, decorators, ComponentChanged, Transform, OBSERVER_TYPE } from '@combos-fun/engine';\nimport type { GameObject } from '@combos-fun/engine';\nimport { RendererSystem } from '@combos-fun/plugin-renderer';\nimport EE from 'eventemitter3';\n\nimport A11y from './A11y';\nimport { setStyle, setTransform } from './utils';\nimport {\n POSITION,\n ZINDEX,\n PointerEvents,\n MaskBackground,\n EventPosition,\n A11yMaskStyle,\n A11yActivate,\n} from './constant';\n\ninterface SystemParam {\n debug?: boolean;\n activate?: A11yActivate;\n delay?: number;\n zIndex?: number;\n checkA11yOpen?: () => Promise<boolean>;\n}\n\nconst notAttr = ['hint', 'event', 'delay', 'attr', 'role', 'props', 'state', 'a11yId', 'name'];\n\nconst getEventFunc = function (event: EE, gameObject: GameObject, e: MouseEvent) {\n ['touchstart', 'touchend', 'tap'].forEach(name => {\n event.emit(name, {\n stopPropagation: () => e.stopPropagation(),\n data: {\n position: this.eventPosition,\n },\n gameObject,\n });\n });\n};\n\n@decorators.componentObserver({\n A11y: ['hint'],\n Transform: ['inScene'],\n Event: [],\n})\nexport default class A11ySystem extends System {\n static systemName = 'A11ySystem';\n\n /**\n * 无障碍覆盖层\n */\n div: HTMLDivElement;\n /**\n * 是否开启调试\n */\n debug: boolean;\n /**\n * 横向的比例\n */\n _ratioX: number;\n /**\n * 纵向的比例\n */\n _ratioY: number;\n /**\n * 事件坐标\n */\n eventPosition: EventPosition;\n /**\n * 是否开启无障碍能力\n */\n activate: boolean;\n /**\n * dom 延迟放置\n */\n delay: number;\n cache: Map<string, HTMLElement> = new Map();\n eventCache: Map<string, (e: MouseEvent) => void> = new Map();\n /**\n * \n * dom 的 zIndex\n */\n zIndex: number = ZINDEX;\n /**\n *\n * @param opt\n */\n\n /**\n * 无障碍插件初始化函数\n * @param opt 无障碍插件选项\n * @param opt.activate 是否开启无障碍能力,默认为自动根据系统读屏能力进行开启 AUTO | ENABLE | DISABLE\n * @example\n * // 开启调试,无障碍区域会显示红色透明背景\n * new A11ySystem({debug: true})\n * // 禁用无障碍\n * new A11ySystem({activate: A11yActivate.DISABLE})\n */\n constructor(opt?: SystemParam) {\n super(opt);\n }\n\n get ratioX() {\n if (this._ratioX) {\n return this._ratioX;\n } else {\n const success = this.setRatio();\n if (success) {\n return this._ratioX;\n } else {\n return 0;\n }\n }\n }\n get ratioY() {\n if (this._ratioY) {\n return this._ratioY;\n } else {\n const success = this.setRatio();\n if (success) {\n return this._ratioY;\n } else {\n return 0;\n }\n }\n }\n\n async init(opt: SystemParam = {}) {\n const { activate = A11yActivate.CHECK, delay = 100, checkA11yOpen = () => Promise.resolve(false), zIndex } = opt;\n this.delay = delay;\n this.zIndex = zIndex || this.zIndex\n switch (activate) {\n case A11yActivate.CHECK:\n try {\n this.activate = await checkA11yOpen();\n } catch (error) {\n this.activate = false;\n }\n break;\n case A11yActivate.DISABLE:\n this.activate = false;\n break;\n case A11yActivate.ENABLE:\n this.activate = true;\n break;\n }\n this.debug = opt.debug || false;\n if (this.debug) {\n this.activate = true;\n }\n\n if (!this.activate) return;\n // 渲染出父容器\n const div = document.createElement('div');\n this.div = div;\n // 如果存在父容器,则渲染这个 div,子元素则会相对这个 div 进行定位,否则直接相对于 body 进行定位\n if (this.game.canvas.parentNode) {\n this.game.canvas.parentNode.insertBefore(this.div, this.game.canvas);\n }\n }\n setRatio() {\n const { width, height } = this.getCanvasBoundingClientRect();\n const { renderWidth, renderHeight } = this.getRenderRect();\n this._ratioX = width / renderWidth;\n this._ratioY = height / renderHeight;\n if (width || height) {\n this.initDiv();\n return true;\n } else {\n return false;\n }\n }\n getRenderRect() {\n const { params = { width: 300, height: 300 } } = this.game.getSystem(RendererSystem);\n const { height: renderHeight, width: renderWidth } = params;\n return { renderWidth, renderHeight };\n }\n getCanvasBoundingClientRect() {\n // 渲染画布相对于视口的实际宽高以及位置,实际的像素\n const { width, height, left, top } = this.game.canvas.getBoundingClientRect();\n return { width, height, left, top };\n }\n initDiv() {\n const { pageXOffset, pageYOffset } = window;\n\n const { width, height, left, top } = this.getCanvasBoundingClientRect();\n // 父容器位置\n const style: A11yMaskStyle = {\n width,\n height,\n left: `${left + pageXOffset}px`,\n top: `${top + pageYOffset}px`,\n position: POSITION,\n zIndex: this.zIndex,\n pointerEvents: PointerEvents.NONE,\n background: MaskBackground.NONE,\n };\n setStyle(this.div, style);\n // 给父容器设置捕获事件,用于监听事件坐标\n this.div.addEventListener(\n 'click',\n e => {\n const currentTarget = e.currentTarget as HTMLDivElement;\n const { left, top } = currentTarget.getBoundingClientRect();\n const x = (e.pageX - left) / this.ratioX;\n const y = (e.pageY - top) / this.ratioY;\n this.eventPosition = { x, y };\n },\n true,\n );\n }\n\n /**\n * 监听插件更新\n */\n async update() {\n const changes = this.componentObserver.clear();\n if (!this.activate) {\n return;\n }\n for (const changed of changes) {\n switch (changed.type) {\n case OBSERVER_TYPE.ADD:\n changed.componentName === 'Event' && this.addEvent(changed.gameObject);\n changed.componentName === 'A11y' && this.add(changed);\n break;\n case OBSERVER_TYPE.CHANGE:\n changed.componentName === 'Transform' && this.transformChange(changed);\n changed.componentName === 'A11y' && this.change(changed);\n break;\n case OBSERVER_TYPE.REMOVE:\n changed.componentName === 'Event' && this.removeEvent(changed);\n changed.componentName === 'A11y' && this.remove(changed);\n }\n }\n }\n\n change(changed: ComponentChanged) {\n const component = changed.component as A11y\n if (changed.prop.prop[0] === 'hint') {\n const dom = this.cache.get(component.a11yId)\n dom?.setAttribute('aria-label', component.hint)\n dom && this.setPosition(dom, changed.gameObject.transform)\n }\n }\n\n remove(changed: ComponentChanged) {\n const component = changed.component as A11y;\n if (!component) return;\n const { a11yId } = component;\n const element = this.div.querySelector(`#${a11yId}`);\n element && this.div.removeChild(element);\n this.cache.delete(a11yId);\n }\n\n /**\n * 监听组件被添加至游戏对象\n * @param changed 改变的组件\n */\n add(changed: ComponentChanged) {\n if (!this.activate) return;\n const component = changed.component as A11y;\n const { gameObject } = changed;\n const { delay, a11yId: id } = component;\n let { event } = component;\n if (!gameObject) return;\n const { transform } = gameObject;\n if (!transform) return;\n const element = document.createElement('div');\n this.cache.set(id, element);\n if (!event) {\n event = gameObject.getComponent('Event');\n }\n setTimeout(() => {\n this.setPosition(element, transform);\n this.setA11yAttr(element, component);\n if (event) {\n this.addEvent(gameObject);\n }\n if (gameObject.scene) {\n this.div.appendChild(element);\n }\n }, delay || this.delay);\n }\n\n // 监听 scene 改变\n transformChange(changed: ComponentChanged) {\n const component = changed.component as Transform;\n const { gameObject } = changed;\n const a11yComponent = gameObject.getComponent(A11y) as A11y;\n if (!a11yComponent) return;\n const { a11yId } = a11yComponent;\n if (!component.inScene) {\n // 监听 scene 删除游戏对象\n const dom = this.div.querySelector(`#${a11yId}`);\n dom && this.div.removeChild(dom);\n // this.cache.delete(a11yId)\n } else {\n // 监听 scene add\n // this.div.appendChild(this.cache)\n if (this.cache.has(a11yId)) {\n const addDom = this.cache.get(a11yId);\n addDom && this.div.appendChild(addDom);\n }\n }\n }\n\n /**\n * 为无障碍组件设置监听事件\n * @param element DOM 元素\n * @param event 事件组件对象\n * @param gameObject 游戏对象\n */\n setEvent(element: HTMLElement, event: EE, gameObject: GameObject, id) {\n if (!event) {\n return;\n }\n const func = getEventFunc.bind(this, event, gameObject) as (e: MouseEvent) => void;\n this.eventCache.set(id, func);\n element.addEventListener('click', func);\n }\n\n addEvent(gameObject: GameObject) {\n const a11y = gameObject.getComponent(A11y) as A11y;\n if (!a11y) return;\n const event = gameObject.getComponent('Event');\n if (!event) return;\n const element = this.cache.get(a11y.a11yId);\n element && this.setEvent(element, event, gameObject, a11y.a11yId);\n }\n\n removeEvent(changed: ComponentChanged) {\n const { gameObject } = changed;\n const a11y = gameObject.getComponent(A11y) as A11y;\n if (!a11y) return;\n const event = changed.component;\n if (!event) return;\n const { a11yId } = a11y;\n const func = this.eventCache.get(a11yId);\n const element = this.cache.get(a11yId);\n element && element.removeEventListener('click', func);\n }\n\n /**\n * 设置无障碍属性标签\n * @param element DOM 元素\n * @param hint 无障碍朗读文字\n * @param interactive 是否可交互\n */\n setA11yAttr(element: HTMLElement, component: A11y) {\n const { hint, props = {}, state = {}, role, a11yId: id } = component;\n const realRole = role || 'text';\n element.setAttribute('role', realRole);\n element.setAttribute('aria-label', hint);\n element.id = id;\n\n // 这里兼容\n const ariaProps = Object.keys(props);\n for (const key of ariaProps) {\n element.setAttribute(key, props[key]);\n }\n const ariaState = Object.keys(state);\n for (const key of ariaState) {\n element.setAttribute(key, state[key]);\n }\n\n for (const key of Object.keys(component)) {\n if (typeof component[key] === 'string' && notAttr.indexOf(key) === -1 && key.indexOf('_') !== 1) {\n element.setAttribute(key, component[key]);\n }\n }\n }\n\n /**\n * 将无障碍元素设置到对应的位置\n * @param element DOM 元素\n * @param transform 位置属性\n */\n setPosition(element: HTMLElement, transform: Transform) {\n // 相对画布定位\n // const { x: anchorX, y: anchorY } = transform.anchor\n // 游戏对象的宽高\n const { width, height } = transform.size;\n // position\n // const { x: positionX, y: positionY } = transform.position\n // 设置无障碍 DOM 的样式,龙骨动画默认 2px\n const style: A11yMaskStyle = {\n width: width === 0 ? 1 : width * this.ratioX,\n height: height === 0 ? 1 : height * this.ratioY,\n position: POSITION,\n zIndex: this.zIndex,\n pointerEvents: PointerEvents.AUTO,\n background: this.debug ? MaskBackground.DEBUG : MaskBackground.NONE,\n };\n const transformProps = {\n ...transform,\n };\n setStyle(element, style);\n // 调整 DOM 的位置\n setTransform(element, transformProps, this.ratioX, this.ratioY);\n }\n onDestroy() {\n this.div.parentElement.removeChild(this.div);\n this.cache = null;\n this.eventCache = null;\n this.div = null\n }\n}\n"],"names":[],"mappings":"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"}
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ if (process.env.NODE_ENV === 'production') {
4
+ module.exports = require('./dist/plugin-a11y.cjs.prod.js');
5
+ } else {
6
+ module.exports = require('./dist/plugin-a11y.cjs.js');
7
+ }
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@combos-fun/plugin-a11y",
3
+ "version": "0.0.1",
4
+ "description": "@combos-fun/plugin-a11y",
5
+ "main": "index.js",
6
+ "module": "dist/plugin-a11y.esm.js",
7
+ "bundle": "CombosFun.plugin.a11y",
8
+ "unpkg": "dist/CombosFun.plugin.a11y.min.js",
9
+ "files": [
10
+ "index.js",
11
+ "dist"
12
+ ],
13
+ "types": "dist/plugin-a11y.d.ts",
14
+ "keywords": [
15
+ "combos-fun",
16
+ "game"
17
+ ],
18
+ "author": "sun668 <q947692259@gmail.com>",
19
+ "dependencies": {
20
+ "eventemitter3": "^5.0.4",
21
+ "@combos-fun/inspector-decorator": "0.0.1",
22
+ "@combos-fun/plugin-renderer": "0.0.1",
23
+ "@combos-fun/engine": "0.0.1"
24
+ },
25
+ "scripts": {
26
+ "build": "node ../../scripts/build-package.mjs"
27
+ }
28
+ }