Skip to main content

事件/交互

¥Events / Interaction

PixiJS 主要是一个渲染库,但它提供了一个灵活且高性能的事件系统,专为鼠标和触摸输入而设计。该系统用统一的、类似 DOM 的联合事件模型取代了以前版本中遗留的 InteractionManager

¥PixiJS is primarily a rendering library, but it provides a flexible and performant event system designed for both mouse and touch input. This system replaces the legacy InteractionManager from previous versions with a unified, DOM-like federated event model.

const sprite = new Sprite(texture);
sprite.eventMode = 'static';
sprite.on('pointerdown', () => {
console.log('Sprite clicked!');
});

事件模式

¥Event Modes

要使用事件系统,请设置 Container(或其子类,例如 Sprite)的 eventMode 并订阅事件监听器。

¥To use the event system, set the eventMode of a Container (or its subclasses like Sprite) and subscribe to event listeners.

eventMode 属性控制对象与事件系统的交互方式:

¥The eventMode property controls how an object interacts with the event system:

模式描述
none忽略所有交互事件,包括子对象。针对非交互元素进行了优化。
passive(默认)忽略自身碰撞测试,不触发事件,但可交互的子对象仍会接收事件。
auto仅当父级可交互时才参与命中测试。不触发事件。
static触发事件并进行命中测试。适用于按钮等非移动交互元素。
dynamicstatic 相同,但在指针空闲时还会接收合成事件。适用于动画或移动目标。

事件类型

¥Event Types

PixiJS 支持丰富的类似 DOM 的事件类型,涵盖鼠标、触摸和指针输入。以下是分类列表。

¥PixiJS supports a rich set of DOM-like event types across mouse, touch, and pointer input. Below is a categorized list.

¥Pointer Events (Recommended for general use)

事件类型描述
pointerdown当指针(鼠标、笔或触摸)在显示对象上按下时触发。
pointerup当指针在显示对象上释放时触发。
pointerupoutside当指针在接收 pointerdown 的对象之外释放时触发。
pointermove当指针移到显示对象上时触发。
pointerover当指针进入显示对象边界时触发。
pointerout当指针离开显示对象边界时触发。
pointerenter当指针进入显示对象时触发(不冒泡)。
pointerleave当指针离开显示对象时触发(不冒泡)。
pointercancel当指针交互取消(例如触摸丢失)时触发。
pointertap当指针快速点击时触发。
globalpointermove每次指针移动时触发,无论是否点击显示对象。

鼠标事件(已使用用于鼠标特定输入)

¥Mouse Events (Used for mouse-specific input)

事件类型描述
mousedown在显示对象上按下鼠标按钮时触发。
mouseup在对象上方释放鼠标按钮时触发。
mouseupoutside在接收 mousedown 的对象外部释放鼠标按钮时触发。
mousemove当鼠标移到显示对象上时触发。
mouseover当鼠标进入显示对象时触发。
mouseout鼠标离开显示对象时触发。
mouseenter当鼠标进入对象时触发,不冒泡。
mouseleave鼠标离开对象时触发,不会冒泡。
click当鼠标点击(按下并释放)对象时触发。
rightdown当在显示对象上按下鼠标右键时触发。
rightup鼠标右键在对象上松开时触发。
rightupoutside当在接收 rightdown 的对象之外释放鼠标右键时触发。
rightclick当鼠标右键单击(按下并释放)对象时触发。
globalmousemove每次鼠标移动时触发,无论是否点击显示对象。
wheel当鼠标滚轮在显示对象上滚动时触发。

触摸事件

¥Touch Events

事件类型描述
touchstart当新的触摸点放置在显示对象上时触发。
touchend当触摸点从显示对象上抬起时触发。
touchendoutside当触摸点在接收 touchstart 的对象之外结束时触发。
touchmove当触摸点在显示对象上移动时触发。
touchcancel当触摸交互取消(例如设备手势)时触发。
tap当触摸点点击显示对象时触发。
globaltouchmove每次触摸移动时触发,无论显示对象是否处于触摸之下。

全局事件

¥Global Events

在 PixiJS 的早期版本中,当画布捕获任何移动事件时,即使指针不在显示对象上,也会触发 pointermovemousemovetouchmove 等事件。此行为在 v8 中发生了变化,现在只有当指针位于显示对象上时才会触发这些事件。

¥In previous versions of PixiJS, events such as pointermove, mousemove, and touchmove were fired when any move event was captured by the canvas, even if the pointer was not over a display object. This behavior changed in v8 and now these events are fired only when the pointer is over a display object.

要保留旧行为,你可以使用 globalpointermoveglobalmousemoveglobaltouchmove 事件。这些事件会在每次指针/触摸移动时触发,无论是否有任何显示对象被点击。

¥To maintain the old behavior, you can use the globalpointermove, globalmousemove, and globaltouchmove events. These events are fired on every pointer/touch move, regardless of whether any display object is hit.

const sprite = new Sprite(texture);
sprite.eventMode = 'static';
sprite.on('globalpointermove', (event) => {
console.log('Pointer moved globally!', event);
});

命中测试的工作原理

¥How Hit Testing Works

当发生输入事件(鼠标移动、点击等)时,PixiJS 会遍历显示树,以查找指针下方最顶层的交互元素:

¥When an input event occurs (mouse move, click, etc.), PixiJS walks the display tree to find the top-most interactive element under the pointer:

  • 如果 Container 上的 interactiveChildrenfalse,则将跳过其子元素。

    ¥If interactiveChildren is false on a Container, its children will be skipped.

  • 如果设置了 hitArea,它将覆盖基于边界的命中测试。

    ¥If a hitArea is set, it overrides bounds-based hit testing.

  • 如果 eventMode'none',则将跳过该元素及其子元素。

    ¥If eventMode is 'none', the element and its children are skipped.

找到最顶层的交互元素后,事件就会被发送给它。如果事件冒泡,它将沿着显示树向上传播。如果事件未被处理,它将继续冒泡到父容器,直到到达根节点。

¥Once the top-most interactive element is found, the event is dispatched to it. If the event bubbles, it will propagate up the display tree. If the event is not handled, it will continue to bubble up to parent containers until it reaches the root.

自定义命中区域

¥Custom Hit Area

可以使用 hitArea 属性定义自定义命中区域。此属性可以在任何场景对象上设置,包括 SpriteContainerGraphics

¥Custom hit areas can be defined using the hitArea property. This property can be set on any scene object, including Sprite, Container, and Graphics.

使用自定义点击区域允许你定义特定的交互区域,该区域可以与对象的边界框不同。它还可以通过减少需要检查交互的对象数量来提高性能。

¥Using a custom hit area allows you to define a specific area for interaction, which can be different from the object's bounding box. It also can improve performance by reducing the number of objects that need to be checked for interaction.

import { Rectangle, Sprite } from 'pixi.js';

const sprite = new Sprite(texture);
sprite.hitArea = new Rectangle(0, 0, 100, 100);
sprite.eventMode = 'static';

监听事件

¥Listening to Events

PixiJS 支持 on()/off()addEventListener()/removeEventListener() 以及用于添加和删除事件监听器的事件回调 (onclick: ()=> {})。大多数情况下都推荐使用 on() 方法,因为它在 PixiJS 中使用的不同事件类型之间提供了更一致的 API。

¥PixiJS supports both on()/off() and addEventListener()/removeEventListener() and event callbacks (onclick: ()=> {}) for adding and removing event listeners. The on() method is recommended for most use cases as it provides a more consistent API across different event types used throughout PixiJS.

使用 on()(来自 EventEmitter)

¥Using on() (from EventEmitter)

const eventFn = (e) => console.log('clicked');
sprite.on('pointerdown', eventFn);
sprite.once('pointerdown', eventFn);
sprite.off('pointerdown', eventFn);

使用 DOM 样式事件

¥Using DOM-style Events

sprite.addEventListener(
'click',
(event) => {
console.log('Clicked!', event.detail);
},
{ once: true },
);

使用回调

¥Using callbacks

sprite.onclick = (event) => {
console.log('Clicked!', event.detail);
};

检查交互性

¥Checking for Interactivity

你可以使用 isInteractive() 方法检查 SpriteContainer 是否可交互。如果对象是交互式的并且可以接收事件,则此方法返回 true

¥You can check if a Sprite or Container is interactive by using the isInteractive() method. This method returns true if the object is interactive and can receive events.

if (sprite.isInteractive()) {
// true if eventMode is static or dynamic
}

自定义光标

¥Custom Cursors

PixiJS 允许你使用 cursor 属性为交互式对象设置自定义光标。此属性接受表示 CSS 光标类型的字符串。

¥PixiJS allows you to set a custom cursor for interactive objects using the cursor property. This property accepts a string representing the CSS cursor type.

const sprite = new Sprite(texture);
sprite.eventMode = 'static';
sprite.cursor = 'pointer'; // Set the cursor to a pointer when hovering over the sprite
const sprite = new Sprite(texture);
sprite.eventMode = 'static';
sprite.cursor = 'url(my-cursor.png), auto'; // Set a custom cursor image

默认自定义光标

¥Default Custom Cursors

你还可以设置所有交互对象使用的默认值。

¥You can also set default values to be used for all interactive objects.

// CSS style for icons
const defaultIcon = 'url(\'https://pixi.nodejs.cn/assets/bunny.png\'),auto';
const hoverIcon = 'url(\'https://pixi.nodejs.cn/assets/bunny_saturated.png\'),auto';

// Add custom cursor styles
app.renderer.events.cursorStyles.default = defaultIcon;
app.renderer.events.cursorStyles.hover = hoverIcon;

const sprite = new Sprite(texture);
sprite.eventMode = 'static';
sprite.cursor = 'hover';

API 参考

¥API Reference