@eva/plugin-worker 2.0.1-beta.27 → 2.0.1-beta.28

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.
@@ -9,14 +9,35 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
9
9
 
10
10
  var EventEmitter__default = /*#__PURE__*/_interopDefaultLegacy(EventEmitter);
11
11
 
12
+ /**
13
+ * 事件时钟类
14
+ *
15
+ * EventsTicker 用于在指针静止时自动触发指针事件,
16
+ * 确保即使指针不移动,移动的对象也能正确触发悬停测试。
17
+ * 这对于实现动态对象的鼠标交互至关重要。
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * EventsTicker.init(eventSystem);
22
+ * EventsTicker.addTickerListener();
23
+ * EventsTicker.pointerMoved(); // 标记指针已移动
24
+ * ```
25
+ *
26
+ * @since 7.2.0
27
+ */
12
28
  class EventsTickerClass {
13
29
  constructor() {
30
+ /** 触发模拟事件的频率(毫秒) */
14
31
  this.interactionFrequency = 10;
15
32
  this._deltaTime = 0;
16
33
  this._didMove = false;
17
34
  this._tickerAdded = false;
18
35
  this._pauseUpdate = true;
19
36
  }
37
+ /**
38
+ * Initializes the event ticker.
39
+ * @param events - The event system.
40
+ */
20
41
  init(events) {
21
42
  this.removeTickerListener();
22
43
  this.events = events;
@@ -26,12 +47,14 @@ class EventsTickerClass {
26
47
  this._tickerAdded = false;
27
48
  this._pauseUpdate = true;
28
49
  }
50
+ /** Whether to pause the update checks or not. */
29
51
  get pauseUpdate() {
30
52
  return this._pauseUpdate;
31
53
  }
32
54
  set pauseUpdate(paused) {
33
55
  this._pauseUpdate = paused;
34
56
  }
57
+ /** Adds the ticker listener. */
35
58
  addTickerListener() {
36
59
  if (this._tickerAdded || !this.domElement) {
37
60
  return;
@@ -39,6 +62,7 @@ class EventsTickerClass {
39
62
  pixi_js.Ticker.system.add(this._tickerUpdate, this, pixi_js.UPDATE_PRIORITY.INTERACTION);
40
63
  this._tickerAdded = true;
41
64
  }
65
+ /** Removes the ticker listener. */
42
66
  removeTickerListener() {
43
67
  if (!this._tickerAdded) {
44
68
  return;
@@ -46,17 +70,21 @@ class EventsTickerClass {
46
70
  pixi_js.Ticker.system.remove(this._tickerUpdate, this);
47
71
  this._tickerAdded = false;
48
72
  }
73
+ /** Sets flag to not fire extra events when the user has already moved there mouse */
49
74
  pointerMoved() {
50
75
  this._didMove = true;
51
76
  }
77
+ /** Updates the state of interactive objects. */
52
78
  _update() {
53
79
  if (!this.domElement || this._pauseUpdate) {
54
80
  return;
55
81
  }
82
+ // if the user move the mouse this check has already been done using the mouse move!
56
83
  if (this._didMove) {
57
84
  this._didMove = false;
58
85
  return;
59
86
  }
87
+ // eslint-disable-next-line dot-notation
60
88
  const rootPointerEvent = this.events['_rootPointerEvent'];
61
89
  if (this.events.supportsTouchEvents && rootPointerEvent.pointerType === 'touch') {
62
90
  return;
@@ -68,6 +96,13 @@ class EventsTickerClass {
68
96
  pointerId: rootPointerEvent.pointerId,
69
97
  }));
70
98
  }
99
+ /**
100
+ * Updates the state of interactive objects if at least {@link interactionFrequency}
101
+ * milliseconds have passed since the last invocation.
102
+ *
103
+ * Invoked by a throttled ticker update from {@link Ticker.system}.
104
+ * @param ticker - The throttled ticker.
105
+ */
71
106
  _tickerUpdate(ticker) {
72
107
  this._deltaTime += ticker.deltaTime;
73
108
  if (this._deltaTime < this.interactionFrequency) {
@@ -79,17 +114,64 @@ class EventsTickerClass {
79
114
  }
80
115
  const EventsTicker = new EventsTickerClass();
81
116
 
117
+ /**
118
+ * 联合事件类
119
+ *
120
+ * FederatedEvent 是一个兼容 DOM 的合成事件实现,
121
+ * 代表原始的 FederatedEvent 或原生 DOM 事件进行传播。
122
+ * 它提供了统一的事件接口,抹平了不同浏览器和设备之间的差异。
123
+ *
124
+ * 主要特性:
125
+ * - 兼容 DOM Event API
126
+ * - 支持事件冒泡和捕获
127
+ * - 提供事件传播控制
128
+ * - 记录事件路径
129
+ *
130
+ * @typeParam N - 持有的原生事件类型
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * sprite.on('pointerdown', (event: FederatedPointerEvent) => {
135
+ * console.log('Clicked at:', event.global.x, event.global.y);
136
+ * event.stopPropagation(); // 停止事件传播
137
+ * });
138
+ * ```
139
+ */
82
140
  class FederatedEvent {
141
+ /**
142
+ * @param manager - The event boundary which manages this event. Propagation can only occur
143
+ * within the boundary's jurisdiction.
144
+ */
83
145
  constructor(manager) {
146
+ /** 事件是否冒泡(仅在传播前设置有效) */
84
147
  this.bubbles = true;
148
+ /** @deprecated 自 7.0.0 起弃用 */
85
149
  this.cancelBubble = true;
150
+ /**
151
+ * 事件是否可以被取消
152
+ * @readonly
153
+ */
86
154
  this.cancelable = false;
155
+ /**
156
+ * Flag added for compatibility with DOM {@code Event}. It is not used in the Federated Events
157
+ * API.
158
+ * @see https://dom.spec.whatwg.org/#dom-event-composed
159
+ */
87
160
  this.composed = false;
161
+ /** Flags whether the default response of the user agent was prevent through this event. */
88
162
  this.defaultPrevented = false;
163
+ /**
164
+ * The propagation phase.
165
+ * @default {@link FederatedEvent.NONE}
166
+ */
89
167
  this.eventPhase = FederatedEvent.prototype.NONE;
168
+ /** Flags whether propagation was stopped. */
90
169
  this.propagationStopped = false;
170
+ /** Flags whether propagation was immediately stopped. */
91
171
  this.propagationImmediatelyStopped = false;
172
+ /** The coordinates of the event relative to the nearest DOM layer. This is a non-standard property. */
92
173
  this.layer = new pixi_js.Point();
174
+ /** The coordinates of the event relative to the DOM document. This is a non-standard property. */
93
175
  this.page = new pixi_js.Point();
94
176
  this.NONE = 0;
95
177
  this.CAPTURING_PHASE = 1;
@@ -97,147 +179,373 @@ class FederatedEvent {
97
179
  this.BUBBLING_PHASE = 3;
98
180
  this.manager = manager;
99
181
  }
182
+ /** @readonly */
100
183
  get layerX() {
101
184
  return this.layer.x;
102
185
  }
186
+ /** @readonly */
103
187
  get layerY() {
104
188
  return this.layer.y;
105
189
  }
190
+ /** @readonly */
106
191
  get pageX() {
107
192
  return this.page.x;
108
193
  }
194
+ /** @readonly */
109
195
  get pageY() {
110
196
  return this.page.y;
111
197
  }
198
+ /**
199
+ * Fallback for the deprecated @code{InteractionEvent.data}.
200
+ * @deprecated since 7.0.0
201
+ */
112
202
  get data() {
113
203
  return this;
114
204
  }
205
+ /** The propagation path for this event. Alias for {@link EventBoundary.propagationPath}. */
115
206
  composedPath() {
207
+ // Find the propagation path if it isn't cached or if the target has changed since since
208
+ // the last evaluation.
116
209
  if (this.manager && (!this.path || this.path[this.path.length - 1] !== this.target)) {
117
210
  this.path = this.target ? this.manager.propagationPath(this.target) : [];
118
211
  }
119
212
  return this.path;
120
213
  }
214
+ /**
215
+ * Unimplemented method included for implementing the DOM interface {@code Event}. It will throw an {@code Error}.
216
+ * @deprecated
217
+ * @param _type
218
+ * @param _bubbles
219
+ * @param _cancelable
220
+ */
121
221
  initEvent(_type, _bubbles, _cancelable) {
122
222
  throw new Error('initEvent() is a legacy DOM API. It is not implemented in the Federated Events API.');
123
223
  }
224
+ /**
225
+ * Unimplemented method included for implementing the DOM interface {@code UIEvent}. It will throw an {@code Error}.
226
+ * @deprecated
227
+ * @param _typeArg
228
+ * @param _bubblesArg
229
+ * @param _cancelableArg
230
+ * @param _viewArg
231
+ * @param _detailArg
232
+ */
124
233
  initUIEvent(_typeArg, _bubblesArg, _cancelableArg, _viewArg, _detailArg) {
125
234
  throw new Error('initUIEvent() is a legacy DOM API. It is not implemented in the Federated Events API.');
126
235
  }
236
+ /** Prevent default behavior of PixiJS and the user agent. */
127
237
  preventDefault() {
128
238
  if (this.nativeEvent instanceof Event && this.nativeEvent.cancelable) {
129
239
  this.nativeEvent.preventDefault();
130
240
  }
131
241
  this.defaultPrevented = true;
132
242
  }
243
+ /**
244
+ * Stop this event from propagating to any addition listeners, including on the
245
+ * {@link FederatedEventTarget.currentTarget currentTarget} and also the following
246
+ * event targets on the propagation path.
247
+ */
133
248
  stopImmediatePropagation() {
134
249
  this.propagationImmediatelyStopped = true;
135
250
  }
251
+ /**
252
+ * Stop this event from propagating to the next {@link FederatedEventTarget}. The rest of the listeners
253
+ * on the {@link FederatedEventTarget.currentTarget currentTarget} will still be notified.
254
+ */
136
255
  stopPropagation() {
137
256
  this.propagationStopped = true;
138
257
  }
139
258
  }
140
259
 
260
+ /**
261
+ * A {@link FederatedEvent} for mouse events.
262
+ * @memberof events
263
+ */
141
264
  class FederatedMouseEvent extends FederatedEvent {
142
265
  constructor() {
143
266
  super(...arguments);
267
+ /** The coordinates of the mouse event relative to the canvas. */
144
268
  this.client = new pixi_js.Point();
269
+ /** The movement in this pointer relative to the last `mousemove` event. */
145
270
  this.movement = new pixi_js.Point();
271
+ /** The offset of the pointer coordinates w.r.t. target Container in world space. This is not supported at the moment. */
146
272
  this.offset = new pixi_js.Point();
273
+ /** The pointer coordinates in world space. */
147
274
  this.global = new pixi_js.Point();
275
+ /**
276
+ * The pointer coordinates in the renderer's {@link Renderer.screen screen}. This has slightly
277
+ * different semantics than native PointerEvent screenX/screenY.
278
+ */
148
279
  this.screen = new pixi_js.Point();
149
280
  }
281
+ /** @readonly */
150
282
  get clientX() {
151
283
  return this.client.x;
152
284
  }
285
+ /** @readonly */
153
286
  get clientY() {
154
287
  return this.client.y;
155
288
  }
289
+ /**
290
+ * Alias for {@link FederatedMouseEvent.clientX this.clientX}.
291
+ * @readonly
292
+ */
156
293
  get x() {
157
294
  return this.clientX;
158
295
  }
296
+ /**
297
+ * Alias for {@link FederatedMouseEvent.clientY this.clientY}.
298
+ * @readonly
299
+ */
159
300
  get y() {
160
301
  return this.clientY;
161
302
  }
303
+ /** @readonly */
162
304
  get movementX() {
163
305
  return this.movement.x;
164
306
  }
307
+ /** @readonly */
165
308
  get movementY() {
166
309
  return this.movement.y;
167
310
  }
311
+ /** @readonly */
168
312
  get offsetX() {
169
313
  return this.offset.x;
170
314
  }
315
+ /** @readonly */
171
316
  get offsetY() {
172
317
  return this.offset.y;
173
318
  }
319
+ /** @readonly */
174
320
  get globalX() {
175
321
  return this.global.x;
176
322
  }
323
+ /** @readonly */
177
324
  get globalY() {
178
325
  return this.global.y;
179
326
  }
327
+ /**
328
+ * The pointer coordinates in the renderer's screen. Alias for {@code screen.x}.
329
+ * @readonly
330
+ */
180
331
  get screenX() {
181
332
  return this.screen.x;
182
333
  }
334
+ /**
335
+ * The pointer coordinates in the renderer's screen. Alias for {@code screen.y}.
336
+ * @readonly
337
+ */
183
338
  get screenY() {
184
339
  return this.screen.y;
185
340
  }
341
+ /**
342
+ * This will return the local coordinates of the specified container for this InteractionData
343
+ * @param {Container} container - The Container that you would like the local
344
+ * coords off
345
+ * @param {PointData} point - A Point object in which to store the value, optional (otherwise
346
+ * will create a new point)
347
+ * @param {PointData} globalPos - A Point object containing your custom global coords, optional
348
+ * (otherwise will use the current global coords)
349
+ * @returns - A point containing the coordinates of the InteractionData position relative
350
+ * to the Container
351
+ */
186
352
  getLocalPosition(container, point, globalPos) {
187
353
  return container.worldTransform.applyInverse(globalPos || this.global, point);
188
354
  }
355
+ /**
356
+ * Whether the modifier key was pressed when this event natively occurred.
357
+ * @param key - The modifier key.
358
+ */
189
359
  getModifierState(key) {
190
360
  return 'getModifierState' in this.nativeEvent && this.nativeEvent.getModifierState(key);
191
361
  }
362
+ /**
363
+ * Not supported.
364
+ * @param _typeArg
365
+ * @param _canBubbleArg
366
+ * @param _cancelableArg
367
+ * @param _viewArg
368
+ * @param _detailArg
369
+ * @param _screenXArg
370
+ * @param _screenYArg
371
+ * @param _clientXArg
372
+ * @param _clientYArg
373
+ * @param _ctrlKeyArg
374
+ * @param _altKeyArg
375
+ * @param _shiftKeyArg
376
+ * @param _metaKeyArg
377
+ * @param _buttonArg
378
+ * @param _relatedTargetArg
379
+ * @deprecated since 7.0.0
380
+ */
381
+ // eslint-disable-next-line max-params
192
382
  initMouseEvent(_typeArg, _canBubbleArg, _cancelableArg, _viewArg, _detailArg, _screenXArg, _screenYArg, _clientXArg, _clientYArg, _ctrlKeyArg, _altKeyArg, _shiftKeyArg, _metaKeyArg, _buttonArg, _relatedTargetArg) {
193
383
  throw new Error('Method not implemented.');
194
384
  }
195
385
  }
196
386
 
387
+ /**
388
+ * A {@link FederatedEvent} for pointer events.
389
+ * @memberof events
390
+ */
197
391
  class FederatedPointerEvent extends FederatedMouseEvent {
198
392
  constructor() {
199
393
  super(...arguments);
394
+ /**
395
+ * The width of the pointer's contact along the x-axis, measured in CSS pixels.
396
+ * radiusX of TouchEvents will be represented by this value.
397
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/width
398
+ */
200
399
  this.width = 0;
400
+ /**
401
+ * The height of the pointer's contact along the y-axis, measured in CSS pixels.
402
+ * radiusY of TouchEvents will be represented by this value.
403
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/height
404
+ */
201
405
  this.height = 0;
406
+ /**
407
+ * Indicates whether or not the pointer device that created the event is the primary pointer.
408
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/isPrimary
409
+ */
202
410
  this.isPrimary = false;
203
411
  }
412
+ // Only included for completeness for now
204
413
  getCoalescedEvents() {
205
414
  if (this.type === 'pointermove' || this.type === 'mousemove' || this.type === 'touchmove') {
206
415
  return [this];
207
416
  }
208
417
  return [];
209
418
  }
419
+ // Only included for completeness for now
210
420
  getPredictedEvents() {
211
421
  throw new Error('getPredictedEvents is not supported!');
212
422
  }
213
423
  }
214
424
 
425
+ /**
426
+ * A {@link FederatedEvent} for wheel events.
427
+ * @memberof events
428
+ */
215
429
  class FederatedWheelEvent extends FederatedMouseEvent {
216
430
  constructor() {
217
431
  super(...arguments);
432
+ /** Units specified in pixels. */
218
433
  this.DOM_DELTA_PIXEL = 0;
434
+ /** Units specified in lines. */
219
435
  this.DOM_DELTA_LINE = 1;
436
+ /** Units specified in pages. */
220
437
  this.DOM_DELTA_PAGE = 2;
221
438
  }
222
439
  }
440
+ /** Units specified in pixels. */
223
441
  FederatedWheelEvent.DOM_DELTA_PIXEL = 0;
442
+ /** Units specified in lines. */
224
443
  FederatedWheelEvent.DOM_DELTA_LINE = 1;
444
+ /** Units specified in pages. */
225
445
  FederatedWheelEvent.DOM_DELTA_PAGE = 2;
226
446
 
447
+ // The maximum iterations used in propagation. This prevent infinite loops.
227
448
  const PROPAGATION_LIMIT = 2048;
228
449
  const tempHitLocation = new pixi_js.Point();
229
450
  const tempLocalMapping = new pixi_js.Point();
451
+ /**
452
+ * Event boundaries are "barriers" where events coming from an upstream scene are modified before downstream propagation.
453
+ *
454
+ * ## Root event boundary
455
+ *
456
+ * The {@link EventSystem#rootBoundary rootBoundary} handles events coming from the &lt;canvas /&gt;.
457
+ * {@link EventSystem} handles the normalization from native {@link https://dom.spec.whatwg.org/#event Events}
458
+ * into {@link FederatedEvent FederatedEvents}. The rootBoundary then does the hit-testing and event dispatch
459
+ * for the upstream normalized event.
460
+ *
461
+ * ## Additional event boundaries
462
+ *
463
+ * An additional event boundary may be desired within an application's scene graph. For example, if a portion of the scene is
464
+ * is flat with many children at one level - a spatial hash maybe needed to accelerate hit testing. In this scenario, the
465
+ * container can be detached from the scene and glued using a custom event boundary.
466
+ *
467
+ * ```ts
468
+ * import { Container } from 'pixi.js';
469
+ * import { EventBoundary } from 'pixi.js';
470
+ * import { SpatialHash } from 'pixi-spatial-hash';
471
+ *
472
+ * class HashedHitTestingEventBoundary
473
+ * {
474
+ * private spatialHash: SpatialHash;
475
+ *
476
+ * constructor(scene: Container, spatialHash: SpatialHash)
477
+ * {
478
+ * super(scene);
479
+ * this.spatialHash = spatialHash;
480
+ * }
481
+ *
482
+ * hitTestRecursive(...)
483
+ * {
484
+ * // TODO: If target === this.rootTarget, then use spatial hash to get a
485
+ * // list of possible children that match the given (x,y) coordinates.
486
+ * }
487
+ * }
488
+ *
489
+ * class VastScene extends Container
490
+ * {
491
+ * protected eventBoundary: EventBoundary;
492
+ * protected scene: Container;
493
+ * protected spatialHash: SpatialHash;
494
+ *
495
+ * constructor()
496
+ * {
497
+ * this.scene = new Container();
498
+ * this.spatialHash = new SpatialHash();
499
+ * this.eventBoundary = new HashedHitTestingEventBoundary(this.scene, this.spatialHash);
500
+ *
501
+ * // Populate this.scene with a ton of children, while updating this.spatialHash
502
+ * }
503
+ * }
504
+ * ```
505
+ * @memberof events
506
+ */
230
507
  class EventBoundary {
508
+ /**
509
+ * @param rootTarget - The holder of the event boundary.
510
+ */
231
511
  constructor(rootTarget) {
512
+ /**
513
+ * Emits events after they were dispatched into the scene graph.
514
+ *
515
+ * This can be used for global events listening, regardless of the scene graph being used. It should
516
+ * not be used by interactive libraries for normal use.
517
+ *
518
+ * Special events that do not bubble all the way to the root target are not emitted from here,
519
+ * e.g. pointerenter, pointerleave, click.
520
+ */
232
521
  this.dispatch = new EventEmitter__default();
522
+ /**
523
+ * This flag would emit `pointermove`, `touchmove`, and `mousemove` events on all Containers.
524
+ *
525
+ * The `moveOnAll` semantics mirror those of earlier versions of PixiJS. This was disabled in favor of
526
+ * the Pointer Event API's approach.
527
+ */
233
528
  this.moveOnAll = false;
529
+ /** Enables the global move events. `globalpointermove`, `globaltouchmove`, and `globalmousemove` */
234
530
  this.enableGlobalMoveEvents = true;
531
+ /**
532
+ * State object for mapping methods.
533
+ * @see EventBoundary#trackingData
534
+ */
235
535
  this.mappingState = {
236
536
  trackingData: {},
237
537
  };
538
+ /**
539
+ * The event pool maps event constructors to an free pool of instances of those specific events.
540
+ * @see EventBoundary#allocateEvent
541
+ * @see EventBoundary#freeEvent
542
+ */
238
543
  this.eventPool = new Map();
544
+ /** Every interactive element gathered from the scene. Only used in `pointermove` */
239
545
  this._allInteractiveElements = [];
546
+ /** Every element that passed the hit test. Only used in `pointermove` */
240
547
  this._hitElements = [];
548
+ /** Whether or not to collect all the interactive elements from the scene. Enabled in `pointermove` */
241
549
  this._isPointerMoveEvent = false;
242
550
  this.rootTarget = rootTarget;
243
551
  this.hitPruneFn = this.hitPruneFn.bind(this);
@@ -259,6 +567,18 @@ class EventBoundary {
259
567
  this.addEventMapping('pointerupoutside', this.mapPointerUpOutside);
260
568
  this.addEventMapping('wheel', this.mapWheel);
261
569
  }
570
+ /**
571
+ * Adds an event mapping for the event `type` handled by `fn`.
572
+ *
573
+ * Event mappings can be used to implement additional or custom events. They take an event
574
+ * coming from the upstream scene (or directly from the {@link EventSystem}) and dispatch new downstream events
575
+ * generally trickling down and bubbling up to {@link EventBoundary.rootTarget this.rootTarget}.
576
+ *
577
+ * To modify the semantics of existing events, the built-in mapping methods of EventBoundary should be overridden
578
+ * instead.
579
+ * @param type - The type of upstream event to map.
580
+ * @param fn - The mapping method. The context of this function must be bound manually, if desired.
581
+ */
262
582
  addEventMapping(type, fn) {
263
583
  if (!this.mappingTable[type]) {
264
584
  this.mappingTable[type] = [];
@@ -269,12 +589,21 @@ class EventBoundary {
269
589
  });
270
590
  this.mappingTable[type].sort((a, b) => a.priority - b.priority);
271
591
  }
592
+ /**
593
+ * Dispatches the given event
594
+ * @param e - The event to dispatch.
595
+ * @param type - The type of event to dispatch. Defaults to `e.type`.
596
+ */
272
597
  dispatchEvent(e, type) {
273
598
  e.propagationStopped = false;
274
599
  e.propagationImmediatelyStopped = false;
275
600
  this.propagate(e, type);
276
601
  this.dispatch.emit(type || e.type, e);
277
602
  }
603
+ /**
604
+ * Maps the given upstream event through the event boundary and propagates it downstream.
605
+ * @param e - The event to map.
606
+ */
278
607
  mapEvent(e) {
279
608
  if (!this.rootTarget) {
280
609
  return;
@@ -286,21 +615,39 @@ class EventBoundary {
286
615
  }
287
616
  }
288
617
  else {
618
+ // #if _DEBUG
289
619
  pixi_js.warn(`[EventBoundary]: Event mapping not defined for ${e.type}`);
620
+ // #endif
290
621
  }
291
622
  }
623
+ /**
624
+ * Finds the Container that is the target of a event at the given coordinates.
625
+ *
626
+ * The passed (x,y) coordinates are in the world space above this event boundary.
627
+ * @param x - The x coordinate of the event.
628
+ * @param y - The y coordinate of the event.
629
+ */
292
630
  hitTest(x, y) {
293
631
  EventsTicker.pauseUpdate = true;
632
+ // if we are using global move events, we need to hit test the whole scene graph
294
633
  const useMove = this._isPointerMoveEvent && this.enableGlobalMoveEvents;
295
634
  const fn = useMove ? 'hitTestMoveRecursive' : 'hitTestRecursive';
296
635
  const invertedPath = this[fn](this.rootTarget, this.rootTarget.eventMode, tempHitLocation.set(x, y), this.hitTestFn, this.hitPruneFn);
297
636
  return invertedPath && invertedPath[0];
298
637
  }
638
+ /**
639
+ * Propagate the passed event from from {@link EventBoundary.rootTarget this.rootTarget} to its
640
+ * target {@code e.target}.
641
+ * @param e - The event to propagate.
642
+ * @param type - The type of event to propagate. Defaults to `e.type`.
643
+ */
299
644
  propagate(e, type) {
300
645
  if (!e.target) {
646
+ // This usually occurs when the scene graph is not interactive.
301
647
  return;
302
648
  }
303
649
  const composedPath = e.composedPath();
650
+ // Capturing phase
304
651
  e.eventPhase = e.CAPTURING_PHASE;
305
652
  for (let i = 0, j = composedPath.length - 1; i < j; i++) {
306
653
  e.currentTarget = composedPath[i];
@@ -308,11 +655,13 @@ class EventBoundary {
308
655
  if (e.propagationStopped || e.propagationImmediatelyStopped)
309
656
  return;
310
657
  }
658
+ // At target phase
311
659
  e.eventPhase = e.AT_TARGET;
312
660
  e.currentTarget = e.target;
313
661
  this.notifyTarget(e, type);
314
662
  if (e.propagationStopped || e.propagationImmediatelyStopped)
315
663
  return;
664
+ // Bubbling phase
316
665
  e.eventPhase = e.BUBBLING_PHASE;
317
666
  for (let i = composedPath.length - 2; i >= 0; i--) {
318
667
  e.currentTarget = composedPath[i];
@@ -321,11 +670,21 @@ class EventBoundary {
321
670
  return;
322
671
  }
323
672
  }
673
+ /**
674
+ * Emits the event {@code e} to all interactive containers. The event is propagated in the bubbling phase always.
675
+ *
676
+ * This is used in the `globalpointermove` event.
677
+ * @param e - The emitted event.
678
+ * @param type - The listeners to notify.
679
+ * @param targets - The targets to notify.
680
+ */
324
681
  all(e, type, targets = this._allInteractiveElements) {
325
682
  if (targets.length === 0)
326
683
  return;
327
684
  e.eventPhase = e.BUBBLING_PHASE;
328
685
  const events = Array.isArray(type) ? type : [type];
686
+ // loop through all interactive elements and notify them of the event
687
+ // loop through targets backwards
329
688
  for (let i = targets.length - 1; i >= 0; i--) {
330
689
  events.forEach(event => {
331
690
  e.currentTarget = targets[i];
@@ -333,6 +692,11 @@ class EventBoundary {
333
692
  });
334
693
  }
335
694
  }
695
+ /**
696
+ * Finds the propagation path from {@link EventBoundary.rootTarget rootTarget} to the passed
697
+ * {@code target}. The last element in the path is {@code target}.
698
+ * @param target - The target to find the propagation path to.
699
+ */
336
700
  propagationPath(target) {
337
701
  const propagationPath = [target];
338
702
  for (let i = 0; i < PROPAGATION_LIMIT && target !== this.rootTarget && target.parent; i++) {
@@ -347,6 +711,7 @@ class EventBoundary {
347
711
  }
348
712
  hitTestMoveRecursive(currentTarget, eventMode, location, testFn, pruneFn, ignore = false) {
349
713
  let shouldReturn = false;
714
+ // only bail out early if it is not interactive
350
715
  if (this._interactivePrune(currentTarget))
351
716
  return null;
352
717
  if (currentTarget.eventMode === 'dynamic' || eventMode === 'dynamic') {
@@ -358,15 +723,21 @@ class EventBoundary {
358
723
  const child = children[i];
359
724
  const nestedHit = this.hitTestMoveRecursive(child, this._isInteractive(eventMode) ? eventMode : child.eventMode, location, testFn, pruneFn, ignore || pruneFn(currentTarget, location));
360
725
  if (nestedHit) {
726
+ // Its a good idea to check if a child has lost its parent.
727
+ // this means it has been removed whilst looping so its best
361
728
  if (nestedHit.length > 0 && !nestedHit[nestedHit.length - 1].parent) {
362
729
  continue;
363
730
  }
731
+ // Only add the current hit-test target to the hit-test chain if the chain
732
+ // has already started (i.e. the event target has been found) or if the current
733
+ // target is interactive (i.e. it becomes the event target).
364
734
  const isInteractive = currentTarget.isInteractive();
365
735
  if (nestedHit.length > 0 || isInteractive) {
366
736
  if (isInteractive)
367
737
  this._allInteractiveElements.push(currentTarget);
368
738
  nestedHit.push(currentTarget);
369
739
  }
740
+ // store all hit elements to be returned once we have traversed the whole tree
370
741
  if (this._hitElements.length === 0)
371
742
  this._hitElements = nestedHit;
372
743
  shouldReturn = true;
@@ -377,22 +748,43 @@ class EventBoundary {
377
748
  const isInteractiveTarget = currentTarget.isInteractive();
378
749
  if (isInteractiveTarget && isInteractiveTarget)
379
750
  this._allInteractiveElements.push(currentTarget);
751
+ // we don't carry on hit testing something once we have found a hit,
752
+ // now only care about gathering the interactive elements
380
753
  if (ignore || this._hitElements.length > 0)
381
754
  return null;
382
755
  if (shouldReturn)
383
756
  return this._hitElements;
757
+ // Finally, hit test this Container itself.
384
758
  if (isInteractiveMode && !pruneFn(currentTarget, location) && testFn(currentTarget, location)) {
759
+ // The current hit-test target is the event's target only if it is interactive. Otherwise,
760
+ // the first interactive ancestor will be the event's target.
385
761
  return isInteractiveTarget ? [currentTarget] : [];
386
762
  }
387
763
  return null;
388
764
  }
765
+ /**
766
+ * Recursive implementation for {@link EventBoundary.hitTest hitTest}.
767
+ * @param currentTarget - The Container that is to be hit tested.
768
+ * @param eventMode - The event mode for the `currentTarget` or one of its parents.
769
+ * @param location - The location that is being tested for overlap.
770
+ * @param testFn - Callback that determines whether the target passes hit testing. This callback
771
+ * can assume that `pruneFn` failed to prune the container.
772
+ * @param pruneFn - Callback that determiness whether the target and all of its children
773
+ * cannot pass the hit test. It is used as a preliminary optimization to prune entire subtrees
774
+ * of the scene graph.
775
+ * @returns An array holding the hit testing target and all its ancestors in order. The first element
776
+ * is the target itself and the last is {@link EventBoundary.rootTarget rootTarget}. This is the opposite
777
+ * order w.r.t. the propagation path. If no hit testing target is found, null is returned.
778
+ */
389
779
  hitTestRecursive(currentTarget, eventMode, location, testFn, pruneFn) {
780
+ // Attempt to prune this Container and its subtree as an optimization.
390
781
  if (this._interactivePrune(currentTarget) || pruneFn(currentTarget, location)) {
391
782
  return null;
392
783
  }
393
784
  if (currentTarget.eventMode === 'dynamic' || eventMode === 'dynamic') {
394
785
  EventsTicker.pauseUpdate = false;
395
786
  }
787
+ // Find a child that passes the hit testing and return one, if any.
396
788
  if (currentTarget.interactiveChildren && currentTarget.children) {
397
789
  const children = currentTarget.children;
398
790
  const relativeLocation = location;
@@ -400,9 +792,14 @@ class EventBoundary {
400
792
  const child = children[i];
401
793
  const nestedHit = this.hitTestRecursive(child, this._isInteractive(eventMode) ? eventMode : child.eventMode, relativeLocation, testFn, pruneFn);
402
794
  if (nestedHit) {
795
+ // Its a good idea to check if a child has lost its parent.
796
+ // this means it has been removed whilst looping so its best
403
797
  if (nestedHit.length > 0 && !nestedHit[nestedHit.length - 1].parent) {
404
798
  continue;
405
799
  }
800
+ // Only add the current hit-test target to the hit-test chain if the chain
801
+ // has already started (i.e. the event target has been found) or if the current
802
+ // target is interactive (i.e. it becomes the event target).
406
803
  const isInteractive = currentTarget.isInteractive();
407
804
  if (nestedHit.length > 0 || isInteractive)
408
805
  nestedHit.push(currentTarget);
@@ -412,7 +809,10 @@ class EventBoundary {
412
809
  }
413
810
  const isInteractiveMode = this._isInteractive(eventMode);
414
811
  const isInteractiveTarget = currentTarget.isInteractive();
812
+ // Finally, hit test this Container itself.
415
813
  if (isInteractiveMode && testFn(currentTarget, location)) {
814
+ // The current hit-test target is the event's target only if it is interactive. Otherwise,
815
+ // the first interactive ancestor will be the event's target.
416
816
  return isInteractiveTarget ? [currentTarget] : [];
417
817
  }
418
818
  return null;
@@ -421,17 +821,28 @@ class EventBoundary {
421
821
  return int === 'static' || int === 'dynamic';
422
822
  }
423
823
  _interactivePrune(container) {
824
+ // If container is a mask, invisible, or not renderable then it cannot be hit directly.
424
825
  if (!container || !container.visible || !container.renderable || !container.measurable) {
425
826
  return true;
426
827
  }
828
+ // If this Container is none then it cannot be hit by anything.
427
829
  if (container.eventMode === 'none') {
428
830
  return true;
429
831
  }
832
+ // If this Container is passive and it has no interactive children then it cannot be hit
430
833
  if (container.eventMode === 'passive' && !container.interactiveChildren) {
431
834
  return true;
432
835
  }
433
836
  return false;
434
837
  }
838
+ /**
839
+ * Checks whether the container or any of its children cannot pass the hit test at all.
840
+ *
841
+ * {@link EventBoundary}'s implementation uses the {@link Container.hitArea hitArea}
842
+ * and {@link Container._maskEffect} for pruning.
843
+ * @param container - The container to prune.
844
+ * @param location - The location to test for overlap.
845
+ */
435
846
  hitPruneFn(container, location) {
436
847
  if (container.hitArea) {
437
848
  container.worldTransform.applyInverse(location, tempLocalMapping);
@@ -452,8 +863,15 @@ class EventBoundary {
452
863
  }
453
864
  return false;
454
865
  }
866
+ /**
867
+ * Checks whether the container passes hit testing for the given location.
868
+ * @param container - The container to test.
869
+ * @param location - The location to test for overlap.
870
+ * @returns - Whether `container` passes hit testing for `location`.
871
+ */
455
872
  hitTestFn(container, location) {
456
873
  var _a;
874
+ // If the container failed pruning with a hitArea, then it must pass it.
457
875
  if (container.hitArea) {
458
876
  return true;
459
877
  }
@@ -461,14 +879,24 @@ class EventBoundary {
461
879
  container.worldTransform.applyInverse(location, tempLocalMapping);
462
880
  return container.containsPoint(tempLocalMapping);
463
881
  }
882
+ // TODO: Should we hit test based on bounds?
464
883
  return false;
465
884
  }
885
+ /**
886
+ * Notify all the listeners to the event's `currentTarget`.
887
+ *
888
+ * If the `currentTarget` contains the property `on<type>`, then it is called here,
889
+ * simulating the behavior from version 6.x and prior.
890
+ * @param e - The event passed to the target.
891
+ * @param type - The type of event to notify. Defaults to `e.type`.
892
+ */
466
893
  notifyTarget(e, type) {
467
894
  var _a;
468
895
  if (!e.currentTarget.isInteractive()) {
469
896
  return;
470
897
  }
471
898
  type = type !== null && type !== void 0 ? type : e.type;
899
+ // call the `on${type}` for the current target if it exists
472
900
  const handlerKey = `on${type}`;
473
901
  (_a = e.currentTarget[handlerKey]) === null || _a === void 0 ? void 0 : _a(e);
474
902
  const key = e.eventPhase === e.CAPTURING_PHASE || e.eventPhase === e.AT_TARGET ? `${type}capture` : type;
@@ -477,9 +905,17 @@ class EventBoundary {
477
905
  this._notifyListeners(e, type);
478
906
  }
479
907
  }
908
+ /**
909
+ * Maps the upstream `pointerdown` events to a downstream `pointerdown` event.
910
+ *
911
+ * `touchstart`, `rightdown`, `mousedown` events are also dispatched for specific pointer types.
912
+ * @param from - The upstream `pointerdown` event.
913
+ */
480
914
  mapPointerDown(from) {
481
915
  if (!(from instanceof FederatedPointerEvent)) {
916
+ // #if _DEBUG
482
917
  pixi_js.warn('EventBoundary cannot map a non-pointer event as a pointer event');
918
+ // #endif
483
919
  return;
484
920
  }
485
921
  const e = this.createPointerEvent(from);
@@ -495,10 +931,19 @@ class EventBoundary {
495
931
  trackingData.pressTargetsByButton[from.button] = e.composedPath();
496
932
  this.freeEvent(e);
497
933
  }
934
+ /**
935
+ * Maps the upstream `pointermove` to downstream `pointerout`, `pointerover`, and `pointermove` events, in that order.
936
+ *
937
+ * The tracking data for the specific pointer has an updated `overTarget`. `mouseout`, `mouseover`,
938
+ * `mousemove`, and `touchmove` events are fired as well for specific pointer types.
939
+ * @param from - The upstream `pointermove` event.
940
+ */
498
941
  mapPointerMove(from) {
499
942
  var _a, _b, _c;
500
943
  if (!(from instanceof FederatedPointerEvent)) {
944
+ // #if _DEBUG
501
945
  pixi_js.warn('EventBoundary cannot map a non-pointer event as a pointer event');
946
+ // #endif
502
947
  return;
503
948
  }
504
949
  this._allInteractiveElements.length = 0;
@@ -509,12 +954,16 @@ class EventBoundary {
509
954
  const isMouse = e.pointerType === 'mouse' || e.pointerType === 'pen';
510
955
  const trackingData = this.trackingData(from.pointerId);
511
956
  const outTarget = this.findMountedTarget(trackingData.overTargets);
957
+ // First pointerout/pointerleave
512
958
  if (((_a = trackingData.overTargets) === null || _a === void 0 ? void 0 : _a.length) > 0 && outTarget !== e.target) {
959
+ // pointerout always occurs on the overTarget when the pointer hovers over another element.
513
960
  const outType = from.type === 'mousemove' ? 'mouseout' : 'pointerout';
514
961
  const outEvent = this.createPointerEvent(from, outType, outTarget);
515
962
  this.dispatchEvent(outEvent, 'pointerout');
516
963
  if (isMouse)
517
964
  this.dispatchEvent(outEvent, 'mouseout');
965
+ // If the pointer exits overTarget and its descendants, then a pointerleave event is also fired. This event
966
+ // is dispatched to all ancestors that no longer capture the pointer.
518
967
  if (!e.composedPath().includes(outTarget)) {
519
968
  const leaveEvent = this.createPointerEvent(from, 'pointerleave', outTarget);
520
969
  leaveEvent.eventPhase = leaveEvent.AT_TARGET;
@@ -529,18 +978,23 @@ class EventBoundary {
529
978
  }
530
979
  this.freeEvent(outEvent);
531
980
  }
981
+ // Then pointerover
532
982
  if (outTarget !== e.target) {
983
+ // pointerover always occurs on the new overTarget
533
984
  const overType = from.type === 'mousemove' ? 'mouseover' : 'pointerover';
534
- const overEvent = this.clonePointerEvent(e, overType);
985
+ const overEvent = this.clonePointerEvent(e, overType); // clone faster
535
986
  this.dispatchEvent(overEvent, 'pointerover');
536
987
  if (isMouse)
537
988
  this.dispatchEvent(overEvent, 'mouseover');
989
+ // Probe whether the newly hovered Container is an ancestor of the original overTarget.
538
990
  let overTargetAncestor = outTarget === null || outTarget === void 0 ? void 0 : outTarget.parent;
539
991
  while (overTargetAncestor && overTargetAncestor !== this.rootTarget.parent) {
540
992
  if (overTargetAncestor === e.target)
541
993
  break;
542
994
  overTargetAncestor = overTargetAncestor.parent;
543
995
  }
996
+ // The pointer has entered a non-ancestor of the original overTarget. This means we need a pointerentered
997
+ // event.
544
998
  const didPointerEnter = !overTargetAncestor || overTargetAncestor === this.rootTarget.parent;
545
999
  if (didPointerEnter) {
546
1000
  const enterEvent = this.clonePointerEvent(e, 'pointerenter');
@@ -560,6 +1014,7 @@ class EventBoundary {
560
1014
  const allowGlobalPointerEvents = (_b = this.enableGlobalMoveEvents) !== null && _b !== void 0 ? _b : true;
561
1015
  this.moveOnAll ? allMethods.push('pointermove') : this.dispatchEvent(e, 'pointermove');
562
1016
  allowGlobalPointerEvents && allMethods.push('globalpointermove');
1017
+ // Then pointermove
563
1018
  if (e.pointerType === 'touch') {
564
1019
  this.moveOnAll ? allMethods.splice(1, 0, 'touchmove') : this.dispatchEvent(e, 'touchmove');
565
1020
  allowGlobalPointerEvents && allMethods.push('globaltouchmove');
@@ -577,10 +1032,18 @@ class EventBoundary {
577
1032
  trackingData.overTargets = e.composedPath();
578
1033
  this.freeEvent(e);
579
1034
  }
1035
+ /**
1036
+ * Maps the upstream `pointerover` to downstream `pointerover` and `pointerenter` events, in that order.
1037
+ *
1038
+ * The tracking data for the specific pointer gets a new `overTarget`.
1039
+ * @param from - The upstream `pointerover` event.
1040
+ */
580
1041
  mapPointerOver(from) {
581
1042
  var _a;
582
1043
  if (!(from instanceof FederatedPointerEvent)) {
1044
+ // #if _DEBUG
583
1045
  pixi_js.warn('EventBoundary cannot map a non-pointer event as a pointer event');
1046
+ // #endif
584
1047
  return;
585
1048
  }
586
1049
  const trackingData = this.trackingData(from.pointerId);
@@ -591,6 +1054,7 @@ class EventBoundary {
591
1054
  this.dispatchEvent(e, 'mouseover');
592
1055
  if (e.pointerType === 'mouse')
593
1056
  this.cursor = (_a = e.target) === null || _a === void 0 ? void 0 : _a.cursor;
1057
+ // pointerenter events must be fired since the pointer entered from upstream.
594
1058
  const enterEvent = this.clonePointerEvent(e, 'pointerenter');
595
1059
  enterEvent.eventPhase = enterEvent.AT_TARGET;
596
1060
  while (enterEvent.target && enterEvent.target !== this.rootTarget.parent) {
@@ -604,19 +1068,30 @@ class EventBoundary {
604
1068
  this.freeEvent(e);
605
1069
  this.freeEvent(enterEvent);
606
1070
  }
1071
+ /**
1072
+ * Maps the upstream `pointerout` to downstream `pointerout`, `pointerleave` events, in that order.
1073
+ *
1074
+ * The tracking data for the specific pointer is cleared of a `overTarget`.
1075
+ * @param from - The upstream `pointerout` event.
1076
+ */
607
1077
  mapPointerOut(from) {
608
1078
  if (!(from instanceof FederatedPointerEvent)) {
1079
+ // #if _DEBUG
609
1080
  pixi_js.warn('EventBoundary cannot map a non-pointer event as a pointer event');
1081
+ // #endif
610
1082
  return;
611
1083
  }
612
1084
  const trackingData = this.trackingData(from.pointerId);
613
1085
  if (trackingData.overTargets) {
614
1086
  const isMouse = from.pointerType === 'mouse' || from.pointerType === 'pen';
615
1087
  const outTarget = this.findMountedTarget(trackingData.overTargets);
1088
+ // pointerout first
616
1089
  const outEvent = this.createPointerEvent(from, 'pointerout', outTarget);
617
1090
  this.dispatchEvent(outEvent);
618
1091
  if (isMouse)
619
1092
  this.dispatchEvent(outEvent, 'mouseout');
1093
+ // pointerleave(s) are also dispatched b/c the pointer must've left rootTarget and its descendants to
1094
+ // get an upstream pointerout event (upstream events do not know rootTarget has descendants).
620
1095
  const leaveEvent = this.createPointerEvent(from, 'pointerleave', outTarget);
621
1096
  leaveEvent.eventPhase = leaveEvent.AT_TARGET;
622
1097
  while (leaveEvent.target && leaveEvent.target !== this.rootTarget.parent) {
@@ -632,9 +1107,21 @@ class EventBoundary {
632
1107
  }
633
1108
  this.cursor = null;
634
1109
  }
1110
+ /**
1111
+ * Maps the upstream `pointerup` event to downstream `pointerup`, `pointerupoutside`,
1112
+ * and `click`/`rightclick`/`pointertap` events, in that order.
1113
+ *
1114
+ * The `pointerupoutside` event bubbles from the original `pointerdown` target to the most specific
1115
+ * ancestor of the `pointerdown` and `pointerup` targets, which is also the `click` event's target. `touchend`,
1116
+ * `rightup`, `mouseup`, `touchendoutside`, `rightupoutside`, `mouseupoutside`, and `tap` are fired as well for
1117
+ * specific pointer types.
1118
+ * @param from - The upstream `pointerup` event.
1119
+ */
635
1120
  mapPointerUp(from) {
636
1121
  if (!(from instanceof FederatedPointerEvent)) {
1122
+ // #if _DEBUG
637
1123
  pixi_js.warn('EventBoundary cannot map a non-pointer event as a pointer event');
1124
+ // #endif
638
1125
  return;
639
1126
  }
640
1127
  const now = performance.now();
@@ -650,6 +1137,8 @@ class EventBoundary {
650
1137
  const trackingData = this.trackingData(from.pointerId);
651
1138
  const pressTarget = this.findMountedTarget(trackingData.pressTargetsByButton[from.button]);
652
1139
  let clickTarget = pressTarget;
1140
+ // pointerupoutside only bubbles. It only bubbles upto the parent that doesn't contain
1141
+ // the pointerup location.
653
1142
  if (pressTarget && !e.composedPath().includes(pressTarget)) {
654
1143
  let currentTarget = pressTarget;
655
1144
  while (currentTarget && !e.composedPath().includes(currentTarget)) {
@@ -665,8 +1154,11 @@ class EventBoundary {
665
1154
  currentTarget = currentTarget.parent;
666
1155
  }
667
1156
  delete trackingData.pressTargetsByButton[from.button];
1157
+ // currentTarget is the most specific ancestor holding both the pointerdown and pointerup
1158
+ // targets. That is - it's our click target!
668
1159
  clickTarget = currentTarget;
669
1160
  }
1161
+ // click!
670
1162
  if (clickTarget) {
671
1163
  const clickEvent = this.clonePointerEvent(e, 'click');
672
1164
  clickEvent.target = clickTarget;
@@ -700,9 +1192,22 @@ class EventBoundary {
700
1192
  }
701
1193
  this.freeEvent(e);
702
1194
  }
1195
+ /**
1196
+ * Maps the upstream `pointerupoutside` event to a downstream `pointerupoutside` event, bubbling from the original
1197
+ * `pointerdown` target to `rootTarget`.
1198
+ *
1199
+ * (The most specific ancestor of the `pointerdown` event and the `pointerup` event must the
1200
+ * `{@link EventBoundary}'s root because the `pointerup` event occurred outside of the boundary.)
1201
+ *
1202
+ * `touchendoutside`, `mouseupoutside`, and `rightupoutside` events are fired as well for specific pointer
1203
+ * types. The tracking data for the specific pointer is cleared of a `pressTarget`.
1204
+ * @param from - The upstream `pointerupoutside` event.
1205
+ */
703
1206
  mapPointerUpOutside(from) {
704
1207
  if (!(from instanceof FederatedPointerEvent)) {
1208
+ // #if _DEBUG
705
1209
  pixi_js.warn('EventBoundary cannot map a non-pointer event as a pointer event');
1210
+ // #endif
706
1211
  return;
707
1212
  }
708
1213
  const trackingData = this.trackingData(from.pointerId);
@@ -725,21 +1230,37 @@ class EventBoundary {
725
1230
  }
726
1231
  this.freeEvent(e);
727
1232
  }
1233
+ /**
1234
+ * Maps the upstream `wheel` event to a downstream `wheel` event.
1235
+ * @param from - The upstream `wheel` event.
1236
+ */
728
1237
  mapWheel(from) {
729
1238
  if (!(from instanceof FederatedWheelEvent)) {
1239
+ // #if _DEBUG
730
1240
  pixi_js.warn('EventBoundary cannot map a non-wheel event as a wheel event');
1241
+ // #endif
731
1242
  return;
732
1243
  }
733
1244
  const wheelEvent = this.createWheelEvent(from);
734
1245
  this.dispatchEvent(wheelEvent);
735
1246
  this.freeEvent(wheelEvent);
736
1247
  }
1248
+ /**
1249
+ * Finds the most specific event-target in the given propagation path that is still mounted in the scene graph.
1250
+ *
1251
+ * This is used to find the correct `pointerup` and `pointerout` target in the case that the original `pointerdown`
1252
+ * or `pointerover` target was unmounted from the scene graph.
1253
+ * @param propagationPath - The propagation path was valid in the past.
1254
+ * @returns - The most specific event-target still mounted at the same location in the scene graph.
1255
+ */
737
1256
  findMountedTarget(propagationPath) {
738
1257
  if (!propagationPath) {
739
1258
  return null;
740
1259
  }
741
1260
  let currentTarget = propagationPath[0];
742
1261
  for (let i = 1; i < propagationPath.length; i++) {
1262
+ // Set currentTarget to the next target in the path only if it is still attached to the
1263
+ // scene graph (i.e. parent still points to the expected ancestor).
743
1264
  if (propagationPath[i].parent === currentTarget) {
744
1265
  currentTarget = propagationPath[i];
745
1266
  }
@@ -749,6 +1270,14 @@ class EventBoundary {
749
1270
  }
750
1271
  return currentTarget;
751
1272
  }
1273
+ /**
1274
+ * Creates an event whose {@code originalEvent} is {@code from}, with an optional `type` and `target` override.
1275
+ *
1276
+ * The event is allocated using {@link EventBoundary#allocateEvent this.allocateEvent}.
1277
+ * @param from - The {@code originalEvent} for the returned event.
1278
+ * @param [type=from.type] - The type of the returned event.
1279
+ * @param target - The target of the returned event.
1280
+ */
752
1281
  createPointerEvent(from, type, target) {
753
1282
  var _a;
754
1283
  const event = this.allocateEvent(FederatedPointerEvent);
@@ -763,6 +1292,12 @@ class EventBoundary {
763
1292
  }
764
1293
  return event;
765
1294
  }
1295
+ /**
1296
+ * Creates a wheel event whose {@code originalEvent} is {@code from}.
1297
+ *
1298
+ * The event is allocated using {@link EventBoundary#allocateEvent this.allocateEvent}.
1299
+ * @param from - The upstream wheel event.
1300
+ */
766
1301
  createWheelEvent(from) {
767
1302
  const event = this.allocateEvent(FederatedWheelEvent);
768
1303
  this.copyWheelData(from, event);
@@ -773,6 +1308,13 @@ class EventBoundary {
773
1308
  event.target = this.hitTest(event.global.x, event.global.y);
774
1309
  return event;
775
1310
  }
1311
+ /**
1312
+ * Clones the event {@code from}, with an optional {@code type} override.
1313
+ *
1314
+ * The event is allocated using {@link EventBoundary#allocateEvent this.allocateEvent}.
1315
+ * @param from - The event to clone.
1316
+ * @param [type=from.type] - The type of the returned event.
1317
+ */
776
1318
  clonePointerEvent(from, type) {
777
1319
  const event = this.allocateEvent(FederatedPointerEvent);
778
1320
  event.nativeEvent = from.nativeEvent;
@@ -780,17 +1322,45 @@ class EventBoundary {
780
1322
  this.copyPointerData(from, event);
781
1323
  this.copyMouseData(from, event);
782
1324
  this.copyData(from, event);
1325
+ // copy propagation path for perf
783
1326
  event.target = from.target;
784
1327
  event.path = from.composedPath().slice();
785
1328
  event.type = type !== null && type !== void 0 ? type : event.type;
786
1329
  return event;
787
1330
  }
1331
+ /**
1332
+ * Copies wheel {@link FederatedWheelEvent} data from {@code from} into {@code to}.
1333
+ *
1334
+ * The following properties are copied:
1335
+ * + deltaMode
1336
+ * + deltaX
1337
+ * + deltaY
1338
+ * + deltaZ
1339
+ * @param from - The event to copy data from.
1340
+ * @param to - The event to copy data into.
1341
+ */
788
1342
  copyWheelData(from, to) {
789
1343
  to.deltaMode = from.deltaMode;
790
1344
  to.deltaX = from.deltaX;
791
1345
  to.deltaY = from.deltaY;
792
1346
  to.deltaZ = from.deltaZ;
793
1347
  }
1348
+ /**
1349
+ * Copies pointer {@link FederatedPointerEvent} data from {@code from} into {@code to}.
1350
+ *
1351
+ * The following properties are copied:
1352
+ * + pointerId
1353
+ * + width
1354
+ * + height
1355
+ * + isPrimary
1356
+ * + pointerType
1357
+ * + pressure
1358
+ * + tangentialPressure
1359
+ * + tiltX
1360
+ * + tiltY
1361
+ * @param from - The event to copy data from.
1362
+ * @param to - The event to copy data into.
1363
+ */
794
1364
  copyPointerData(from, to) {
795
1365
  if (!(from instanceof FederatedPointerEvent && to instanceof FederatedPointerEvent))
796
1366
  return;
@@ -805,6 +1375,28 @@ class EventBoundary {
805
1375
  to.tiltY = from.tiltY;
806
1376
  to.twist = from.twist;
807
1377
  }
1378
+ /**
1379
+ * Copies mouse {@link FederatedMouseEvent} data from {@code from} to {@code to}.
1380
+ *
1381
+ * The following properties are copied:
1382
+ * + altKey
1383
+ * + button
1384
+ * + buttons
1385
+ * + clientX
1386
+ * + clientY
1387
+ * + metaKey
1388
+ * + movementX
1389
+ * + movementY
1390
+ * + pageX
1391
+ * + pageY
1392
+ * + x
1393
+ * + y
1394
+ * + screen
1395
+ * + shiftKey
1396
+ * + global
1397
+ * @param from - The event to copy data from.
1398
+ * @param to - The event to copy data into.
1399
+ */
808
1400
  copyMouseData(from, to) {
809
1401
  if (!(from instanceof FederatedMouseEvent && to instanceof FederatedMouseEvent))
810
1402
  return;
@@ -819,6 +1411,17 @@ class EventBoundary {
819
1411
  to.shiftKey = from.shiftKey;
820
1412
  to.global.copyFrom(from.global);
821
1413
  }
1414
+ /**
1415
+ * Copies base {@link FederatedEvent} data from {@code from} into {@code to}.
1416
+ *
1417
+ * The following properties are copied:
1418
+ * + isTrusted
1419
+ * + srcElement
1420
+ * + timeStamp
1421
+ * + type
1422
+ * @param from - The event to copy data from.
1423
+ * @param to - The event to copy data into.
1424
+ */
822
1425
  copyData(from, to) {
823
1426
  to.isTrusted = from.isTrusted;
824
1427
  to.srcElement = from.srcElement;
@@ -830,6 +1433,11 @@ class EventBoundary {
830
1433
  to.layer.copyFrom(from.layer);
831
1434
  to.page.copyFrom(from.page);
832
1435
  }
1436
+ /**
1437
+ * @param id - The pointer ID.
1438
+ * @returns The tracking data stored for the given pointer. If no data exists, a blank
1439
+ * state will be created.
1440
+ */
833
1441
  trackingData(id) {
834
1442
  if (!this.mappingState.trackingData[id]) {
835
1443
  this.mappingState.trackingData[id] = {
@@ -840,6 +1448,13 @@ class EventBoundary {
840
1448
  }
841
1449
  return this.mappingState.trackingData[id];
842
1450
  }
1451
+ /**
1452
+ * Allocate a specific type of event from {@link EventBoundary#eventPool this.eventPool}.
1453
+ *
1454
+ * This allocation is constructor-agnostic, as long as it only takes one argument - this event
1455
+ * boundary.
1456
+ * @param constructor - The event's constructor.
1457
+ */
843
1458
  allocateEvent(constructor) {
844
1459
  if (!this.eventPool.has(constructor)) {
845
1460
  this.eventPool.set(constructor, []);
@@ -852,6 +1467,17 @@ class EventBoundary {
852
1467
  event.target = null;
853
1468
  return event;
854
1469
  }
1470
+ /**
1471
+ * Frees the event and puts it back into the event pool.
1472
+ *
1473
+ * It is illegal to reuse the event until it is allocated again, using `this.allocateEvent`.
1474
+ *
1475
+ * It is also advised that events not allocated from {@link EventBoundary#allocateEvent this.allocateEvent}
1476
+ * not be freed. This is because of the possibility that the same event is freed twice, which can cause
1477
+ * it to be allocated twice & result in overwriting.
1478
+ * @param event - The event to be freed.
1479
+ * @throws Error if the event is managed by another event boundary.
1480
+ */
855
1481
  freeEvent(event) {
856
1482
  if (event.manager !== this)
857
1483
  throw new Error('It is illegal to free an event not managed by this EventBoundary!');
@@ -861,6 +1487,12 @@ class EventBoundary {
861
1487
  }
862
1488
  this.eventPool.get(constructor).push(event);
863
1489
  }
1490
+ /**
1491
+ * Similar to {@link EventEmitter.emit}, except it stops if the `propagationImmediatelyStopped` flag
1492
+ * is set on the event.
1493
+ * @param e - The event to call each listener with.
1494
+ * @param type - The event key.
1495
+ */
864
1496
  _notifyListeners(e, type) {
865
1497
  const listeners = e.currentTarget._events[type];
866
1498
  if (!listeners)
@@ -887,11 +1519,47 @@ const TOUCH_TO_POINTER = {
887
1519
  touchmove: 'pointermove',
888
1520
  touchcancel: 'pointercancel',
889
1521
  };
1522
+ /**
1523
+ * 事件系统类
1524
+ *
1525
+ * EventSystem 负责处理所有 UI 交互事件(鼠标、触摸、指针等)。
1526
+ * 它将原生 DOM 事件转换为统一的 FederatedEvent,
1527
+ * 并通过事件边界(EventBoundary)将事件传播到场景图中的对象。
1528
+ *
1529
+ * 支持的事件类型:
1530
+ * - 指针事件:pointerdown、pointermove、pointerup 等
1531
+ * - 鼠标事件:mousedown、mousemove、mouseup 等
1532
+ * - 触摸事件:touchstart、touchmove、touchend 等
1533
+ * - 滚轮事件:wheel
1534
+ *
1535
+ * @example
1536
+ * ```typescript
1537
+ * const eventSystem = new EventSystem(renderer);
1538
+ * eventSystem.init({
1539
+ * eventMode: 'passive',
1540
+ * eventFeatures: {
1541
+ * move: true,
1542
+ * click: true,
1543
+ * wheel: true
1544
+ * }
1545
+ * });
1546
+ * ```
1547
+ */
890
1548
  class EventSystem {
1549
+ /**
1550
+ * @param {Renderer} renderer
1551
+ */
891
1552
  constructor(renderer) {
1553
+ /** Does the device support touch events https://www.w3.org/TR/touch-events/ */
892
1554
  this.supportsTouchEvents = 'ontouchstart' in globalThis;
1555
+ /** Does the device support pointer events https://www.w3.org/Submission/pointer-events/ */
893
1556
  this.supportsPointerEvents = !!globalThis.PointerEvent;
1557
+ /**
1558
+ * The DOM element to which the root event listeners are bound. This is automatically set to
1559
+ * the renderer's {@link Renderer#view view}.
1560
+ */
894
1561
  this.domElement = null;
1562
+ /** The resolution used to convert between the DOM client space into world space. */
895
1563
  this.resolution = 1;
896
1564
  this.renderer = renderer;
897
1565
  this.rootBoundary = new EventBoundary(null);
@@ -919,9 +1587,20 @@ class EventSystem {
919
1587
  this._onPointerOverOut = this._onPointerOverOut.bind(this);
920
1588
  this.onWheel = this.onWheel.bind(this);
921
1589
  }
1590
+ /**
1591
+ * The default interaction mode for all display objects.
1592
+ * @see Container.eventMode
1593
+ * @type {EventMode}
1594
+ * @readonly
1595
+ * @since 7.2.0
1596
+ */
922
1597
  static get defaultEventMode() {
923
1598
  return this._defaultEventMode;
924
1599
  }
1600
+ /**
1601
+ * Runner init called, view is available at this point.
1602
+ * @ignore
1603
+ */
925
1604
  init(options) {
926
1605
  var _a, _b;
927
1606
  const { canvas, resolution } = this.renderer;
@@ -931,38 +1610,55 @@ class EventSystem {
931
1610
  Object.assign(this.features, (_b = options.eventFeatures) !== null && _b !== void 0 ? _b : {});
932
1611
  this.rootBoundary.enableGlobalMoveEvents = this.features.globalMove;
933
1612
  }
1613
+ /**
1614
+ * Handle changing resolution.
1615
+ * @ignore
1616
+ */
934
1617
  resolutionChange(resolution) {
935
1618
  this.resolution = resolution;
936
1619
  }
1620
+ /** Destroys all event listeners and detaches the renderer. */
937
1621
  destroy() {
938
1622
  this.setTargetElement(null);
939
1623
  this.renderer = null;
940
1624
  this._currentCursor = null;
941
1625
  }
1626
+ /**
1627
+ * Sets the current cursor mode, handling any callbacks or CSS style changes.
1628
+ * @param mode - cursor mode, a key from the cursorStyles dictionary
1629
+ */
942
1630
  setCursor(mode) {
943
1631
  if (!mode) {
944
1632
  mode = 'default';
945
1633
  }
946
1634
  let applyStyles = true;
1635
+ // offscreen canvas does not support setting styles, but cursor modes can be functions,
1636
+ // in order to handle pixi rendered cursors, so we can't bail
947
1637
  if (globalThis.OffscreenCanvas && this.domElement instanceof OffscreenCanvas) {
948
1638
  applyStyles = false;
949
1639
  }
1640
+ // if the mode didn't actually change, bail early
950
1641
  if (this._currentCursor === mode) {
951
1642
  return;
952
1643
  }
953
1644
  this._currentCursor = mode;
954
1645
  const style = this.cursorStyles[mode];
1646
+ // only do things if there is a cursor style for it
955
1647
  if (style) {
956
1648
  switch (typeof style) {
957
1649
  case 'string':
1650
+ // string styles are handled as cursor CSS
958
1651
  if (applyStyles) {
959
1652
  this.domElement.style.cursor = style;
960
1653
  }
961
1654
  break;
962
1655
  case 'function':
1656
+ // functions are just called, and passed the cursor mode
963
1657
  style(mode);
964
1658
  break;
965
1659
  case 'object':
1660
+ // if it is an object, assume that it is a dictionary of CSS styles,
1661
+ // apply it to the interactionDOMElement
966
1662
  if (applyStyles) {
967
1663
  Object.assign(this.domElement.style, style);
968
1664
  }
@@ -972,17 +1668,34 @@ class EventSystem {
972
1668
  else if (applyStyles &&
973
1669
  typeof mode === 'string' &&
974
1670
  !Object.prototype.hasOwnProperty.call(this.cursorStyles, mode)) {
1671
+ // if it mode is a string (not a Symbol) and cursorStyles doesn't have any entry
1672
+ // for the mode, then assume that the dev wants it to be CSS for the cursor.
975
1673
  this.domElement.style.cursor = mode;
976
1674
  }
977
1675
  }
1676
+ /**
1677
+ * The global pointer event.
1678
+ * Useful for getting the pointer position without listening to events.
1679
+ * @since 7.2.0
1680
+ */
978
1681
  get pointer() {
979
1682
  return this._rootPointerEvent;
980
1683
  }
1684
+ /**
1685
+ * Event handler for pointer down events on {@link EventSystem#domElement this.domElement}.
1686
+ * @param nativeEvent - The native mouse/pointer/touch event.
1687
+ */
981
1688
  _onPointerDown(nativeEvent) {
982
1689
  if (!this.features.click)
983
1690
  return;
984
1691
  this.rootBoundary.rootTarget = this.renderer.lastObjectRendered;
985
1692
  const events = this._normalizeToPointerData(nativeEvent);
1693
+ /*
1694
+ * No need to prevent default on natural pointer events, as there are no side effects
1695
+ * Normalized events, however, may have the double mousedown/touchstart issue on the native android browser,
1696
+ * so still need to be prevented.
1697
+ */
1698
+ // Guaranteed that there will be at least one event in events, and all events must have the same pointer type
986
1699
  if (this.autoPreventDefault && events[0].isNormalized) {
987
1700
  const cancelable = nativeEvent.cancelable || !('cancelable' in nativeEvent);
988
1701
  if (cancelable) {
@@ -997,6 +1710,10 @@ class EventSystem {
997
1710
  }
998
1711
  this.setCursor(this.rootBoundary.cursor);
999
1712
  }
1713
+ /**
1714
+ * Event handler for pointer move events on on {@link EventSystem#domElement this.domElement}.
1715
+ * @param nativeEvent - The native mouse/pointer/touch events.
1716
+ */
1000
1717
  _onPointerMove(nativeEvent) {
1001
1718
  if (!this.features.move)
1002
1719
  return;
@@ -1009,6 +1726,10 @@ class EventSystem {
1009
1726
  }
1010
1727
  this.setCursor(this.rootBoundary.cursor);
1011
1728
  }
1729
+ /**
1730
+ * Event handler for pointer up events on {@link EventSystem#domElement this.domElement}.
1731
+ * @param nativeEvent - The native mouse/pointer/touch event.
1732
+ */
1012
1733
  _onPointerUp(nativeEvent) {
1013
1734
  if (!this.features.click)
1014
1735
  return;
@@ -1022,6 +1743,10 @@ class EventSystem {
1022
1743
  }
1023
1744
  this.setCursor(this.rootBoundary.cursor);
1024
1745
  }
1746
+ /**
1747
+ * Event handler for pointer over & out events on {@link EventSystem#domElement this.domElement}.
1748
+ * @param nativeEvent - The native mouse/pointer/touch event.
1749
+ */
1025
1750
  _onPointerOverOut(nativeEvent) {
1026
1751
  if (!this.features.click)
1027
1752
  return;
@@ -1033,6 +1758,10 @@ class EventSystem {
1033
1758
  }
1034
1759
  this.setCursor(this.rootBoundary.cursor);
1035
1760
  }
1761
+ /**
1762
+ * Passive handler for `wheel` events on {@link EventSystem.domElement this.domElement}.
1763
+ * @param nativeEvent - The native wheel event.
1764
+ */
1036
1765
  onWheel(nativeEvent) {
1037
1766
  if (!this.features.wheel)
1038
1767
  return;
@@ -1040,12 +1769,19 @@ class EventSystem {
1040
1769
  this.rootBoundary.rootTarget = this.renderer.lastObjectRendered;
1041
1770
  this.rootBoundary.mapEvent(wheelEvent);
1042
1771
  }
1772
+ /**
1773
+ * Sets the {@link EventSystem#domElement domElement} and binds event listeners.
1774
+ *
1775
+ * To deregister the current DOM element without setting a new one, pass {@code null}.
1776
+ * @param element - The new DOM element.
1777
+ */
1043
1778
  setTargetElement(element) {
1044
1779
  this._removeEvents();
1045
1780
  this.domElement = element;
1046
1781
  EventsTicker.domElement = element;
1047
1782
  this._addEvents();
1048
1783
  }
1784
+ /** Register event listeners on {@link Renderer#domElement this.domElement}. */
1049
1785
  _addEvents() {
1050
1786
  if (this._eventsAdded || !this.domElement) {
1051
1787
  return;
@@ -1068,6 +1804,10 @@ class EventSystem {
1068
1804
  id = key;
1069
1805
  }
1070
1806
  }
1807
+ /*
1808
+ * These events are added first, so that if pointer events are normalized, they are fired
1809
+ * in the same order as non-normalized events. ie. pointer event 1st, mouse / touch 2nd
1810
+ */
1071
1811
  EventSystem.eventsHandler[id] = {
1072
1812
  pointermove: this._onPointerMove.bind(this),
1073
1813
  pointerdown: this._onPointerDown.bind(this),
@@ -1086,12 +1826,14 @@ class EventSystem {
1086
1826
  EventSystem.eventsHandler[id]['wheel'] = this.onWheel.bind(this);
1087
1827
  this._eventsAdded = true;
1088
1828
  }
1829
+ /** Unregister event listeners on {@link EventSystem#domElement this.domElement}. */
1089
1830
  _removeEvents() {
1090
1831
  if (!this._eventsAdded || !this.domElement) {
1091
1832
  return;
1092
1833
  }
1093
1834
  EventsTicker.removeTickerListener();
1094
1835
  const style = this.domElement.style;
1836
+ // offscreen canvas does not have style, so check first
1095
1837
  if (style) {
1096
1838
  if (globalThis.navigator.msPointerEnabled) {
1097
1839
  style.msContentZooming = '';
@@ -1104,6 +1846,14 @@ class EventSystem {
1104
1846
  this.domElement = null;
1105
1847
  this._eventsAdded = false;
1106
1848
  }
1849
+ /**
1850
+ * Maps x and y coords from a DOM object and maps them correctly to the PixiJS view. The
1851
+ * resulting value is stored in the point. This takes into account the fact that the DOM
1852
+ * element could be scaled and positioned anywhere on the screen.
1853
+ * @param {PointData} point - the point that the result will be stored in
1854
+ * @param {number} x - the x coord of the position to map
1855
+ * @param {number} y - the y coord of the position to map
1856
+ */
1107
1857
  mapPositionToPoint(point, x, y, e) {
1108
1858
  const resolutionMultiplier = 1.0 / this.resolution;
1109
1859
  const rect = e.canvasRect || {
@@ -1118,12 +1868,34 @@ class EventSystem {
1118
1868
  point.x = (x - rect.left) * (domElement.width / rect.width) * resolutionMultiplier;
1119
1869
  point.y = (y - rect.top) * (domElement.height / rect.height) * resolutionMultiplier;
1120
1870
  }
1871
+ /**
1872
+ * Ensures that the original event object contains all data that a regular pointer event would have
1873
+ * @param event - The original event data from a touch or mouse event
1874
+ * @returns An array containing a single normalized pointer event, in the case of a pointer
1875
+ * or mouse event, or a multiple normalized pointer events if there are multiple changed touches
1876
+ */
1121
1877
  _normalizeToPointerData(event) {
1878
+ // @ts-ignore
1122
1879
  return event.normalizedEvents;
1123
1880
  }
1881
+ /**
1882
+ * Normalizes the native {@link https://w3c.github.io/uievents/#interface-wheelevent WheelEvent}.
1883
+ *
1884
+ * The returned {@link FederatedWheelEvent} is a shared instance. It will not persist across
1885
+ * multiple native wheel events.
1886
+ * @param nativeEvent - The native wheel event that occurred on the canvas.
1887
+ * @returns A federated wheel event.
1888
+ */
1124
1889
  normalizeWheelEvent(nativeEvent) {
1125
1890
  const event = this._rootWheelEvent;
1126
1891
  this._transferMouseData(event, nativeEvent);
1892
+ // When WheelEvent is triggered by scrolling with mouse wheel, reading WheelEvent.deltaMode
1893
+ // before deltaX/deltaY/deltaZ on Firefox will result in WheelEvent.DOM_DELTA_LINE (1),
1894
+ // while reading WheelEvent.deltaMode after deltaX/deltaY/deltaZ on Firefox or reading
1895
+ // in any order on other browsers will result in WheelEvent.DOM_DELTA_PIXEL (0).
1896
+ // Therefore, we need to read WheelEvent.deltaMode after deltaX/deltaY/deltaZ in order to
1897
+ // make its behavior more consistent across browsers.
1898
+ // @see https://github.com/pixijs/pixijs/issues/8970
1127
1899
  event.deltaX = nativeEvent.deltaX;
1128
1900
  event.deltaY = nativeEvent.deltaY;
1129
1901
  event.deltaZ = nativeEvent.deltaZ;
@@ -1135,6 +1907,11 @@ class EventSystem {
1135
1907
  event.type = nativeEvent.type;
1136
1908
  return event;
1137
1909
  }
1910
+ /**
1911
+ * Normalizes the `nativeEvent` into a federateed {@link FederatedPointerEvent}.
1912
+ * @param event
1913
+ * @param nativeEvent
1914
+ */
1138
1915
  _bootstrapEvent(event, nativeEvent, nEvent) {
1139
1916
  event.originalEvent = null;
1140
1917
  event.nativeEvent = nativeEvent;
@@ -1150,8 +1927,8 @@ class EventSystem {
1150
1927
  event.twist = nativeEvent.twist;
1151
1928
  this._transferMouseData(event, nativeEvent);
1152
1929
  this.mapPositionToPoint(event.screen, nativeEvent.clientX, nativeEvent.clientY, nEvent);
1153
- event.global.copyFrom(event.screen);
1154
- event.offset.copyFrom(event.screen);
1930
+ event.global.copyFrom(event.screen); // global = screen for top-level
1931
+ event.offset.copyFrom(event.screen); // EventBoundary recalculates using its rootTarget
1155
1932
  event.isTrusted = nativeEvent.isTrusted;
1156
1933
  if (event.type === 'pointerleave') {
1157
1934
  event.type = 'pointerout';
@@ -1164,6 +1941,11 @@ class EventSystem {
1164
1941
  }
1165
1942
  return event;
1166
1943
  }
1944
+ /**
1945
+ * Transfers base & mouse event data from the {@code nativeEvent} to the federated event.
1946
+ * @param event
1947
+ * @param nativeEvent
1948
+ */
1167
1949
  _transferMouseData(event, nativeEvent) {
1168
1950
  event.isTrusted = nativeEvent.isTrusted;
1169
1951
  event.srcElement = nativeEvent.srcElement;
@@ -1184,61 +1966,397 @@ class EventSystem {
1184
1966
  event.shiftKey = nativeEvent.shiftKey;
1185
1967
  }
1186
1968
  }
1969
+ /** @ignore */
1187
1970
  EventSystem.extension = {
1188
1971
  name: 'events',
1189
1972
  type: [pixi_js.ExtensionType.WebGLSystem, pixi_js.ExtensionType.CanvasSystem, pixi_js.ExtensionType.WebGPUSystem],
1190
1973
  priority: -1,
1191
1974
  };
1975
+ /** 画布映射表 */
1192
1976
  EventSystem.canvasMap = {};
1977
+ /** 事件处理器映射表 */
1193
1978
  EventSystem.eventsHandler = {};
1979
+ /**
1980
+ * 事件系统的默认功能配置
1981
+ * @since 7.2.0
1982
+ */
1194
1983
  EventSystem.defaultEventFeatures = {
1984
+ /** 启用指针移动相关事件 */
1195
1985
  move: true,
1986
+ /** 启用全局指针移动事件 */
1196
1987
  globalMove: true,
1988
+ /** 启用点击相关事件 */
1197
1989
  click: true,
1990
+ /** 启用滚轮事件 */
1198
1991
  wheel: true,
1199
1992
  };
1200
1993
 
1201
1994
  const FederatedContainer = {
1995
+ /**
1996
+ * Property-based event handler for the `click` event.
1997
+ * @memberof scene.Container#
1998
+ * @default null
1999
+ * @example
2000
+ * this.onclick = (event) => {
2001
+ * //some function here that happens on click
2002
+ * }
2003
+ */
1202
2004
  onclick: null,
2005
+ /**
2006
+ * Property-based event handler for the `mousedown` event.
2007
+ * @memberof scene.Container#
2008
+ * @default null
2009
+ * @example
2010
+ * this.onmousedown = (event) => {
2011
+ * //some function here that happens on mousedown
2012
+ * }
2013
+ */
1203
2014
  onmousedown: null,
2015
+ /**
2016
+ * Property-based event handler for the `mouseenter` event.
2017
+ * @memberof scene.Container#
2018
+ * @default null
2019
+ * @example
2020
+ * this.onmouseenter = (event) => {
2021
+ * //some function here that happens on mouseenter
2022
+ * }
2023
+ */
1204
2024
  onmouseenter: null,
2025
+ /**
2026
+ * Property-based event handler for the `mouseleave` event.
2027
+ * @memberof scene.Container#
2028
+ * @default null
2029
+ * @example
2030
+ * this.onmouseleave = (event) => {
2031
+ * //some function here that happens on mouseleave
2032
+ * }
2033
+ */
1205
2034
  onmouseleave: null,
2035
+ /**
2036
+ * Property-based event handler for the `mousemove` event.
2037
+ * @memberof scene.Container#
2038
+ * @default null
2039
+ * @example
2040
+ * this.onmousemove = (event) => {
2041
+ * //some function here that happens on mousemove
2042
+ * }
2043
+ */
1206
2044
  onmousemove: null,
2045
+ /**
2046
+ * Property-based event handler for the `globalmousemove` event.
2047
+ * @memberof scene.Container#
2048
+ * @default null
2049
+ * @example
2050
+ * this.onglobalmousemove = (event) => {
2051
+ * //some function here that happens on globalmousemove
2052
+ * }
2053
+ */
1207
2054
  onglobalmousemove: null,
2055
+ /**
2056
+ * Property-based event handler for the `mouseout` event.
2057
+ * @memberof scene.Container#
2058
+ * @default null
2059
+ * @example
2060
+ * this.onmouseout = (event) => {
2061
+ * //some function here that happens on mouseout
2062
+ * }
2063
+ */
1208
2064
  onmouseout: null,
2065
+ /**
2066
+ * Property-based event handler for the `mouseover` event.
2067
+ * @memberof scene.Container#
2068
+ * @default null
2069
+ * @example
2070
+ * this.onmouseover = (event) => {
2071
+ * //some function here that happens on mouseover
2072
+ * }
2073
+ */
1209
2074
  onmouseover: null,
2075
+ /**
2076
+ * Property-based event handler for the `mouseup` event.
2077
+ * @memberof scene.Container#
2078
+ * @default null
2079
+ * @example
2080
+ * this.onmouseup = (event) => {
2081
+ * //some function here that happens on mouseup
2082
+ * }
2083
+ */
1210
2084
  onmouseup: null,
2085
+ /**
2086
+ * Property-based event handler for the `mouseupoutside` event.
2087
+ * @memberof scene.Container#
2088
+ * @default null
2089
+ * @example
2090
+ * this.onmouseupoutside = (event) => {
2091
+ * //some function here that happens on mouseupoutside
2092
+ * }
2093
+ */
1211
2094
  onmouseupoutside: null,
2095
+ /**
2096
+ * Property-based event handler for the `pointercancel` event.
2097
+ * @memberof scene.Container#
2098
+ * @default null
2099
+ * @example
2100
+ * this.onpointercancel = (event) => {
2101
+ * //some function here that happens on pointercancel
2102
+ * }
2103
+ */
1212
2104
  onpointercancel: null,
2105
+ /**
2106
+ * Property-based event handler for the `pointerdown` event.
2107
+ * @memberof scene.Container#
2108
+ * @default null
2109
+ * @example
2110
+ * this.onpointerdown = (event) => {
2111
+ * //some function here that happens on pointerdown
2112
+ * }
2113
+ */
1213
2114
  onpointerdown: null,
2115
+ /**
2116
+ * Property-based event handler for the `pointerenter` event.
2117
+ * @memberof scene.Container#
2118
+ * @default null
2119
+ * @example
2120
+ * this.onpointerenter = (event) => {
2121
+ * //some function here that happens on pointerenter
2122
+ * }
2123
+ */
1214
2124
  onpointerenter: null,
2125
+ /**
2126
+ * Property-based event handler for the `pointerleave` event.
2127
+ * @memberof scene.Container#
2128
+ * @default null
2129
+ * @example
2130
+ * this.onpointerleave = (event) => {
2131
+ * //some function here that happens on pointerleave
2132
+ * }
2133
+ */
1215
2134
  onpointerleave: null,
2135
+ /**
2136
+ * Property-based event handler for the `pointermove` event.
2137
+ * @memberof scene.Container#
2138
+ * @default null
2139
+ * @example
2140
+ * this.onpointermove = (event) => {
2141
+ * //some function here that happens on pointermove
2142
+ * }
2143
+ */
1216
2144
  onpointermove: null,
2145
+ /**
2146
+ * Property-based event handler for the `globalpointermove` event.
2147
+ * @memberof scene.Container#
2148
+ * @default null
2149
+ * @example
2150
+ * this.onglobalpointermove = (event) => {
2151
+ * //some function here that happens on globalpointermove
2152
+ * }
2153
+ */
1217
2154
  onglobalpointermove: null,
2155
+ /**
2156
+ * Property-based event handler for the `pointerout` event.
2157
+ * @memberof scene.Container#
2158
+ * @default null
2159
+ * @example
2160
+ * this.onpointerout = (event) => {
2161
+ * //some function here that happens on pointerout
2162
+ * }
2163
+ */
1218
2164
  onpointerout: null,
2165
+ /**
2166
+ * Property-based event handler for the `pointerover` event.
2167
+ * @memberof scene.Container#
2168
+ * @default null
2169
+ * @example
2170
+ * this.onpointerover = (event) => {
2171
+ * //some function here that happens on pointerover
2172
+ * }
2173
+ */
1219
2174
  onpointerover: null,
2175
+ /**
2176
+ * Property-based event handler for the `pointertap` event.
2177
+ * @memberof scene.Container#
2178
+ * @default null
2179
+ * @example
2180
+ * this.onpointertap = (event) => {
2181
+ * //some function here that happens on pointertap
2182
+ * }
2183
+ */
1220
2184
  onpointertap: null,
2185
+ /**
2186
+ * Property-based event handler for the `pointerup` event.
2187
+ * @memberof scene.Container#
2188
+ * @default null
2189
+ * @example
2190
+ * this.onpointerup = (event) => {
2191
+ * //some function here that happens on pointerup
2192
+ * }
2193
+ */
1221
2194
  onpointerup: null,
2195
+ /**
2196
+ * Property-based event handler for the `pointerupoutside` event.
2197
+ * @memberof scene.Container#
2198
+ * @default null
2199
+ * @example
2200
+ * this.onpointerupoutside = (event) => {
2201
+ * //some function here that happens on pointerupoutside
2202
+ * }
2203
+ */
1222
2204
  onpointerupoutside: null,
2205
+ /**
2206
+ * Property-based event handler for the `rightclick` event.
2207
+ * @memberof scene.Container#
2208
+ * @default null
2209
+ * @example
2210
+ * this.onrightclick = (event) => {
2211
+ * //some function here that happens on rightclick
2212
+ * }
2213
+ */
1223
2214
  onrightclick: null,
2215
+ /**
2216
+ * Property-based event handler for the `rightdown` event.
2217
+ * @memberof scene.Container#
2218
+ * @default null
2219
+ * @example
2220
+ * this.onrightdown = (event) => {
2221
+ * //some function here that happens on rightdown
2222
+ * }
2223
+ */
1224
2224
  onrightdown: null,
2225
+ /**
2226
+ * Property-based event handler for the `rightup` event.
2227
+ * @memberof scene.Container#
2228
+ * @default null
2229
+ * @example
2230
+ * this.onrightup = (event) => {
2231
+ * //some function here that happens on rightup
2232
+ * }
2233
+ */
1225
2234
  onrightup: null,
2235
+ /**
2236
+ * Property-based event handler for the `rightupoutside` event.
2237
+ * @memberof scene.Container#
2238
+ * @default null
2239
+ * @example
2240
+ * this.onrightupoutside = (event) => {
2241
+ * //some function here that happens on rightupoutside
2242
+ * }
2243
+ */
1226
2244
  onrightupoutside: null,
2245
+ /**
2246
+ * Property-based event handler for the `tap` event.
2247
+ * @memberof scene.Container#
2248
+ * @default null
2249
+ * @example
2250
+ * this.ontap = (event) => {
2251
+ * //some function here that happens on tap
2252
+ * }
2253
+ */
1227
2254
  ontap: null,
2255
+ /**
2256
+ * Property-based event handler for the `touchcancel` event.
2257
+ * @memberof scene.Container#
2258
+ * @default null
2259
+ * @example
2260
+ * this.ontouchcancel = (event) => {
2261
+ * //some function here that happens on touchcancel
2262
+ * }
2263
+ */
1228
2264
  ontouchcancel: null,
2265
+ /**
2266
+ * Property-based event handler for the `touchend` event.
2267
+ * @memberof scene.Container#
2268
+ * @default null
2269
+ * @example
2270
+ * this.ontouchend = (event) => {
2271
+ * //some function here that happens on touchend
2272
+ * }
2273
+ */
1229
2274
  ontouchend: null,
2275
+ /**
2276
+ * Property-based event handler for the `touchendoutside` event.
2277
+ * @memberof scene.Container#
2278
+ * @default null
2279
+ * @example
2280
+ * this.ontouchendoutside = (event) => {
2281
+ * //some function here that happens on touchendoutside
2282
+ * }
2283
+ */
1230
2284
  ontouchendoutside: null,
2285
+ /**
2286
+ * Property-based event handler for the `touchmove` event.
2287
+ * @memberof scene.Container#
2288
+ * @default null
2289
+ * @example
2290
+ * this.ontouchmove = (event) => {
2291
+ * //some function here that happens on touchmove
2292
+ * }
2293
+ */
1231
2294
  ontouchmove: null,
2295
+ /**
2296
+ * Property-based event handler for the `globaltouchmove` event.
2297
+ * @memberof scene.Container#
2298
+ * @default null
2299
+ * @example
2300
+ * this.onglobaltouchmove = (event) => {
2301
+ * //some function here that happens on globaltouchmove
2302
+ * }
2303
+ */
1232
2304
  onglobaltouchmove: null,
2305
+ /**
2306
+ * Property-based event handler for the `touchstart` event.
2307
+ * @memberof scene.Container#
2308
+ * @default null
2309
+ * @example
2310
+ * this.ontouchstart = (event) => {
2311
+ * //some function here that happens on touchstart
2312
+ * }
2313
+ */
1233
2314
  ontouchstart: null,
2315
+ /**
2316
+ * Property-based event handler for the `wheel` event.
2317
+ * @memberof scene.Container#
2318
+ * @default null
2319
+ * @example
2320
+ * this.onwheel = (event) => {
2321
+ * //some function here that happens on wheel
2322
+ * }
2323
+ */
1234
2324
  onwheel: null,
2325
+ /**
2326
+ * Enable interaction events for the Container. Touch, pointer and mouse
2327
+ * @memberof scene.Container#
2328
+ */
1235
2329
  get interactive() {
1236
2330
  return this.eventMode === 'dynamic' || this.eventMode === 'static';
1237
2331
  },
1238
2332
  set interactive(value) {
1239
2333
  this.eventMode = value ? 'static' : 'passive';
1240
2334
  },
2335
+ /**
2336
+ * @ignore
2337
+ */
1241
2338
  _internalEventMode: undefined,
2339
+ /**
2340
+ * Enable interaction events for the Container. Touch, pointer and mouse.
2341
+ * There are 5 types of interaction settings:
2342
+ * - `'none'`: Ignores all interaction events, even on its children.
2343
+ * - `'passive'`: **(default)** Does not emit events and ignores all hit testing on itself and non-interactive children.
2344
+ * Interactive children will still emit events.
2345
+ * - `'auto'`: Does not emit events but is hit tested if parent is interactive. Same as `interactive = false` in v7
2346
+ * - `'static'`: Emit events and is hit tested. Same as `interaction = true` in v7
2347
+ * - `'dynamic'`: Emits events and is hit tested but will also receive mock interaction events fired from a ticker to
2348
+ * allow for interaction when the mouse isn't moving
2349
+ * @example
2350
+ * import { Sprite } from 'pixi.js';
2351
+ *
2352
+ * const sprite = new Sprite(texture);
2353
+ * sprite.eventMode = 'static';
2354
+ * sprite.on('tap', (event) => {
2355
+ * // Handle event
2356
+ * });
2357
+ * @memberof scene.Container#
2358
+ * @since 7.2.0
2359
+ */
1242
2360
  get eventMode() {
1243
2361
  var _a;
1244
2362
  return (_a = this._internalEventMode) !== null && _a !== void 0 ? _a : EventSystem.defaultEventMode;
@@ -1246,11 +2364,84 @@ const FederatedContainer = {
1246
2364
  set eventMode(value) {
1247
2365
  this._internalEventMode = value;
1248
2366
  },
2367
+ /**
2368
+ * Determines if the container is interactive or not
2369
+ * @returns {boolean} Whether the container is interactive or not
2370
+ * @memberof scene.Container#
2371
+ * @since 7.2.0
2372
+ * @example
2373
+ * import { Sprite } from 'pixi.js';
2374
+ *
2375
+ * const sprite = new Sprite(texture);
2376
+ * sprite.eventMode = 'static';
2377
+ * sprite.isInteractive(); // true
2378
+ *
2379
+ * sprite.eventMode = 'dynamic';
2380
+ * sprite.isInteractive(); // true
2381
+ *
2382
+ * sprite.eventMode = 'none';
2383
+ * sprite.isInteractive(); // false
2384
+ *
2385
+ * sprite.eventMode = 'passive';
2386
+ * sprite.isInteractive(); // false
2387
+ *
2388
+ * sprite.eventMode = 'auto';
2389
+ * sprite.isInteractive(); // false
2390
+ */
1249
2391
  isInteractive() {
1250
2392
  return this.eventMode === 'static' || this.eventMode === 'dynamic';
1251
2393
  },
2394
+ /**
2395
+ * Determines if the children to the container can be clicked/touched
2396
+ * Setting this to false allows PixiJS to bypass a recursive `hitTest` function
2397
+ * @memberof scene.Container#
2398
+ */
1252
2399
  interactiveChildren: true,
2400
+ /**
2401
+ * Interaction shape. Children will be hit first, then this shape will be checked.
2402
+ * Setting this will cause this shape to be checked in hit tests rather than the container's bounds.
2403
+ * @example
2404
+ * import { Rectangle, Sprite } from 'pixi.js';
2405
+ *
2406
+ * const sprite = new Sprite(texture);
2407
+ * sprite.interactive = true;
2408
+ * sprite.hitArea = new Rectangle(0, 0, 100, 100);
2409
+ * @member {IHitArea}
2410
+ * @memberof scene.Container#
2411
+ */
1253
2412
  hitArea: null,
2413
+ /**
2414
+ * Unlike `on` or `addListener` which are methods from EventEmitter, `addEventListener`
2415
+ * seeks to be compatible with the DOM's `addEventListener` with support for options.
2416
+ * @memberof scene.Container
2417
+ * @param type - The type of event to listen to.
2418
+ * @param listener - The listener callback or object.
2419
+ * @param options - Listener options, used for capture phase.
2420
+ * @example
2421
+ * // Tell the user whether they did a single, double, triple, or nth click.
2422
+ * button.addEventListener('click', {
2423
+ * handleEvent(e): {
2424
+ * let prefix;
2425
+ *
2426
+ * switch (e.detail) {
2427
+ * case 1: prefix = 'single'; break;
2428
+ * case 2: prefix = 'double'; break;
2429
+ * case 3: prefix = 'triple'; break;
2430
+ * default: prefix = e.detail + 'th'; break;
2431
+ * }
2432
+ *
2433
+ * console.log('That was a ' + prefix + 'click');
2434
+ * }
2435
+ * });
2436
+ *
2437
+ * // But skip the first click!
2438
+ * button.parent.addEventListener('click', function blockClickOnce(e) {
2439
+ * e.stopImmediatePropagation();
2440
+ * button.parent.removeEventListener('click', blockClickOnce, true);
2441
+ * }, {
2442
+ * capture: true,
2443
+ * });
2444
+ */
1254
2445
  addEventListener(type, listener, options) {
1255
2446
  const capture = (typeof options === 'boolean' && options) || (typeof options === 'object' && options.capture);
1256
2447
  const signal = typeof options === 'object' ? options.signal : undefined;
@@ -1271,6 +2462,14 @@ const FederatedContainer = {
1271
2462
  emitter.on(type, listenerFn, context);
1272
2463
  }
1273
2464
  },
2465
+ /**
2466
+ * Unlike `off` or `removeListener` which are methods from EventEmitter, `removeEventListener`
2467
+ * seeks to be compatible with the DOM's `removeEventListener` with support for options.
2468
+ * @memberof scene.Container
2469
+ * @param type - The type of event the listener is bound to.
2470
+ * @param listener - The listener callback or object.
2471
+ * @param options - The original listener options. This is required to deregister a capture phase listener.
2472
+ */
1274
2473
  removeEventListener(type, listener, options) {
1275
2474
  const capture = (typeof options === 'boolean' && options) || (typeof options === 'object' && options.capture);
1276
2475
  const context = typeof listener === 'function' ? undefined : listener;
@@ -1278,6 +2477,17 @@ const FederatedContainer = {
1278
2477
  listener = typeof listener === 'function' ? listener : listener.handleEvent;
1279
2478
  this.off(type, listener, context);
1280
2479
  },
2480
+ /**
2481
+ * Dispatch the event on this {@link Container} using the event's {@link EventBoundary}.
2482
+ *
2483
+ * The target of the event is set to `this` and the `defaultPrevented` flag is cleared before dispatch.
2484
+ * @memberof scene.Container
2485
+ * @param e - The event to dispatch.
2486
+ * @returns Whether the {@link FederatedEvent.preventDefault preventDefault}() method was not invoked.
2487
+ * @example
2488
+ * // Reuse a click event!
2489
+ * button.dispatchEvent(clickEvent);
2490
+ */
1281
2491
  dispatchEvent(e) {
1282
2492
  if (!(e instanceof FederatedEvent)) {
1283
2493
  throw new Error('Container cannot propagate events outside of the Federated Events API');
@@ -1290,6 +2500,101 @@ const FederatedContainer = {
1290
2500
  },
1291
2501
  };
1292
2502
 
2503
+ /* eslint-disable max-len */
2504
+ /**
2505
+ * PixiJS is primarily a rendering system, but it also includes support for interactivity.
2506
+ * Adding support for mouse and touch events to your project is simple and consistent.
2507
+ *
2508
+ * The new event-based system that replaced InteractionManager from v6 has expanded the definition of what a
2509
+ * Container means to be interactive. With this we have introduced `eventMode` which allows you to control
2510
+ * how an object responds to interaction events.
2511
+ * This is similar to the `interactive` property in v6 but with more options.
2512
+ *
2513
+ * <details id="enabling-interaction">
2514
+ * <summary>Enabling Interaction</summary>
2515
+ *
2516
+ * Any Container-derived object (Sprite, Container, etc.) can become interactive simply by setting its `eventMode` property to any of
2517
+ * the {@link events.EventMode} values. Doing so will cause the object to emit interaction events that can be responded to in order to drive your project's behavior.
2518
+ *
2519
+ * Check out the [interaction example code](/examples/events/click).
2520
+ *
2521
+ * Container-derived objects are based on {@link https://www.npmjs.com/package/eventemitter3|EventEmitter3}
2522
+ * so you can use `on()`, `once()`, `off()` to listen to events.
2523
+ *
2524
+ * For example to respond to clicks and taps, bind to an object ike so:
2525
+ *
2526
+ * ```javascript
2527
+ * let sprite = Sprite.from('/some/texture.png');
2528
+ *
2529
+ * sprite.eventMode = 'static'; // similar to `sprite.interactive = true` in v6
2530
+ * sprite.on('pointerdown', (event) => { alert('clicked!'); });
2531
+ * ```
2532
+ *
2533
+ * Check out the **EventTypes** section below for the full list of interaction events supported.
2534
+ * </details>
2535
+ *
2536
+ * <details id="event-modes">
2537
+ * <summary>Event Modes</summary>
2538
+ *
2539
+ * The new event-based system that replaced InteractionManager from v6 has expanded the definition of what a Container
2540
+ * means to be interactive. With this we have introduced `eventMode` which allows you to control how an object responds
2541
+ * to interaction events. This is similar to the `interactive` property in v6 but with more options.
2542
+ *
2543
+ * | event mode | Description |
2544
+ * |---|---|
2545
+ * | `none` | Ignores all interaction events, similar to CSS's `pointer-events: none`, good optimization for non-interactive children |
2546
+ * | `passive` | Does not emit events and ignores hit testing on itself but does allow for events and hit testing only its interactive children. If you want to be compatible with v6, set this as your default `eventMode` (see options in Renderer, Application, etc) |
2547
+ * | `auto` | Does not emit events and but is hit tested if parent is interactive. Same as `interactive = false` in v7 |
2548
+ * | `static` | Emit events and is hit tested. Same as `interaction = true` in v7, useful for objects like buttons that do not move. |
2549
+ * | `dynamic` | Emits events and is hit tested but will also receive mock interaction events fired from a ticker to allow for interaction when the mouse isn't moving. This is useful for elements that independently moving or animating. |
2550
+ * </details>
2551
+ *
2552
+ * <details id="event-types">
2553
+ * <summary>Event Types</summary>
2554
+ *
2555
+ * Pixi supports the following event types for interactive objects:
2556
+ *
2557
+ * | Event Type | Fired When |
2558
+ * |---|---|
2559
+ * | `pointercancel` | Pointer device button is released outside the display object
2560
+ * that initially registered a pointerdown. |
2561
+ * | `pointerdown` | Pointer device button is pressed on the display object. |
2562
+ * | `pointerenter` | Pointer device enters the display object. |
2563
+ * | `pointerleave` | Pointer device leaves the display object. |
2564
+ * | `pointermove` | Pointer device is moved while over the display object. |
2565
+ * | `globalpointermove` | Pointer device is moved, regardless of hit-testing the current object. |
2566
+ * | `pointerout` | Pointer device is moved off the display object. |
2567
+ * | `pointerover` | Pointer device is moved onto the display object. |
2568
+ * | `pointertap` | Pointer device is tapped twice on the display object. |
2569
+ * | `pointerup` | Pointer device button is released over the display object. |
2570
+ * | `pointerupoutside` | Pointer device button is released outside the display object
2571
+ * that initially registered a pointerdown. |
2572
+ * | `mousedown ` | Mouse button is pressed on the display object. |
2573
+ * | `mouseenter` | Mouse cursor enters the display object. |
2574
+ * | `mouseleave` | Mouse cursor leaves the display object. |
2575
+ * | `mousemove ` | Mouse cursor is moved while over the display object. |
2576
+ * | `globalmousemove` | Mouse is moved, regardless of hit-testing the current object. |
2577
+ * | `mouseout ` | Mouse cursor is moved off the display object. |
2578
+ * | `mouseover ` | Mouse cursor is moved onto the display object. |
2579
+ * | `mouseup ` | Mouse button is released over the display object. |
2580
+ * | `mouseupoutside ` | Mouse button is released outside the display object that initially registered a mousedown. |
2581
+ * | `click ` | Mouse button is clicked (pressed and released) over the display object. |
2582
+ * | `touchcancel ` | Touch point is removed outside of the display object that initially registered a touchstart. |
2583
+ * | `touchend ` | Touch point is removed from the display object. |
2584
+ * | `touchendoutside ` | Touch point is removed outside of the display object that initially registered a touchstart. |
2585
+ * | `touchmove ` | Touch point is moved along the display object. |
2586
+ * | `globaltouchmove` | Touch point is moved, regardless of hit-testing the current object. |
2587
+ * | `touchstart ` | Touch point is placed on the display object. |
2588
+ * | `tap ` | Touch point is tapped twice on the display object. |
2589
+ * | `wheel ` | Mouse wheel is spun over the display object. |
2590
+ * | `rightclick ` | Right mouse button is clicked (pressed and released) over the display object. |
2591
+ * | `rightdown ` | Right mouse button is pressed on the display object. |
2592
+ * | `rightup ` | Right mouse button is released over the display object. |
2593
+ * | `rightupoutside ` | Right mouse button is released outside the display object that initially registered a rightdown. |
2594
+ * </details>
2595
+ * @namespace events
2596
+ */
2597
+ /* eslint-enable max-len */
1293
2598
  const init = () => {
1294
2599
  pixi_js.extensions.add(EventSystem);
1295
2600
  pixi_js.extensions.mixin(pixi_js.Container, FederatedContainer);