diff --git a/README.md b/README.md
index ea5ddbb3..9e7b37af 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,18 @@ With your support, I can make pixi-viewport even better! Please consider making
+## v5+
+Moves pixi-viewport to pixi.js v7 (thanks [@cuire](https://github.com/cuire)!).
+
+NOTE: there is a breaking change since pixi-viewport moved to pixi's new event system. `options.interaction` is removed and you need pass `options.events` to the viewport for it to work properly. The events object can be found at pixi's `renderer.events` or `app.renderer.events`.
+
+```js
+const viewport = new Viewport({ events: renderer.events });
+
+// or
+// const viewport = new Viewport({ events: app.renderer.events });
+```
+
## v4.30.0+
This project was migrated to Typescript (thanks [@ShukantPal](https://github.com/ShukantPal)!). All functionality should be the same. The live Example has been updated.
@@ -40,7 +52,7 @@ const viewport = new Viewport({
worldWidth: 1000,
worldHeight: 1000,
- interaction: app.renderer.plugins.interaction // the interaction module is important for wheel to work properly when renderer.view is placed or scaled
+ events: app.renderer.events // the interaction module is important for wheel to work properly when renderer.view is placed or scaled
})
// add the viewport to the stage
@@ -118,9 +130,6 @@ viewport.plugins.add('name', plugin, index)
PRs are more than welcome!
-## v4.30.0+
-This project was migrated to Typescript (thanks [@sukantpal](https://github.com/SukantPal)!). All functionality should be the same. The live Example has been updated.
-
## Other Libraries
If you liked pixi-viewport, please try my other open source libraries:
* [pixi-scrollbox](https://github.com/davidfig/pixi-scrollbox) - pixi.js scrollbox: a masked box that can scroll vertically or horizontally with scrollbars (uses pixi-viewport)
@@ -129,4 +138,4 @@ If you liked pixi-viewport, please try my other open source libraries:
## license
MIT License
-(c) 2021 [YOPEY YOPEY LLC](https://yopeyopey.com/) by David Figatner (david@yopeyopey.com)
+(c) 2023 [YOPEY YOPEY LLC](https://yopeyopey.com/) by David Figatner (david@yopeyopey.com)
diff --git a/docs/src/code.js b/docs/src/code.js
index 86474958..456fa6b4 100644
--- a/docs/src/code.js
+++ b/docs/src/code.js
@@ -25,7 +25,7 @@ let _fps, _application, _viewport, _object, _stars = [], domEase
function viewport() {
_viewport = _application.stage.addChild(new Viewport(
{
- interaction: _application.renderer.plugins.interaction,
+ events: _application.renderer.events,
passiveWheel: false,
stopPropagation: true
}))
diff --git a/index.d.ts b/index.d.ts
index eed726b6..6550a156 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -1,13 +1,14 @@
import { Container } from '@pixi/display';
import type { DisplayObject } from '@pixi/display';
+import type { EventSystem } from '@pixi/events';
+import type { FederatedEvent } from '@pixi/events';
+import type { FederatedPointerEvent } from '@pixi/events';
import type { IDestroyOptions } from '@pixi/display';
-import type { IHitArea } from '@pixi/interaction';
-import type { InteractionEvent } from '@pixi/interaction';
-import type { InteractionManager } from '@pixi/interaction';
-import { IPointData } from '@pixi/math';
-import { Point } from '@pixi/math';
-import { Rectangle } from '@pixi/math';
-import { Ticker } from '@pixi/ticker';
+import type { IHitArea } from '@pixi/events';
+import { IPointData } from '@pixi/core';
+import { Point } from '@pixi/core';
+import { Rectangle } from '@pixi/core';
+import { Ticker } from '@pixi/core';
export declare class Animate extends Plugin_2 {
readonly options: IAnimateOptions & {
@@ -95,10 +96,7 @@ export declare class Decelerate extends Plugin_2 {
down(): boolean;
isActive(): boolean;
move(): boolean;
- protected moved(data: {
- type: 'clamp-x' | 'clamp-y';
- original: Point;
- }): void;
+ protected handleMoved(e: MovedEvent): void;
up(): boolean;
activate(options: {
x?: number;
@@ -127,12 +125,12 @@ export declare class Drag extends Plugin_2 {
destroy(): void;
protected mouseButtons(buttons: string): void;
protected parseUnderflow(): void;
- protected checkButtons(event: InteractionEvent): boolean;
- protected checkKeyPress(event: InteractionEvent): boolean;
- down(event: InteractionEvent): boolean;
+ protected checkButtons(event: FederatedPointerEvent): boolean;
+ protected checkKeyPress(event: FederatedPointerEvent): boolean;
+ down(event: FederatedPointerEvent): boolean;
get active(): boolean;
- move(event: InteractionEvent): boolean;
- up(event: InteractionEvent): boolean;
+ move(event: FederatedPointerEvent): boolean;
+ up(event: FederatedPointerEvent): boolean;
wheel(event: WheelEvent): boolean;
resume(): void;
clamp(): void;
@@ -264,11 +262,11 @@ export declare class InputManager {
constructor(viewport: Viewport);
private addListeners;
destroy(): void;
- down(event: InteractionEvent): void;
+ down(event: FederatedPointerEvent): void;
clear(): void;
checkThreshold(change: number): boolean;
- move(event: InteractionEvent): void;
- up(event: InteractionEvent): void;
+ move(event: FederatedPointerEvent): void;
+ up(event: FederatedPointerEvent): void;
getPointerPosition(event: WheelEvent): Point;
handleWheel(event: WheelEvent): void;
pause(): void;
@@ -324,11 +322,9 @@ export declare interface IViewportOptions {
stopPropagation?: boolean;
forceHitArea?: Rectangle | null;
noTicker?: boolean;
- interaction?: InteractionManager | null;
+ events: EventSystem;
disableOnContextMenu?: boolean;
- divWheel?: HTMLElement;
ticker?: Ticker;
- useDivWheelForInputManager?: boolean;
}
export declare interface IViewportTouch {
@@ -369,13 +365,19 @@ export declare class MouseEdges extends Plugin_2 {
constructor(parent: Viewport, options?: IMouseEdgesOptions);
resize(): void;
down(): boolean;
- move(event: InteractionEvent): boolean;
+ move(event: FederatedPointerEvent): boolean;
private decelerateHorizontal;
private decelerateVertical;
up(): boolean;
update(): void;
}
+declare type MovedEvent = {
+ viewport: Viewport;
+ type: 'wheel' | 'pinch' | 'animate' | 'ensureVisible' | 'snap' | 'mouse-edges' | 'follow' | 'drag' | 'decelerate' | 'clamp-x' | 'clamp-y' | 'bounce-x' | 'bounce-y';
+ original?: Point_2;
+};
+
export declare class Pinch extends Plugin_2 {
readonly options: Required;
active: boolean;
@@ -386,7 +388,7 @@ export declare class Pinch extends Plugin_2 {
down(): boolean;
isAxisX(): boolean;
isAxisY(): boolean;
- move(e: InteractionEvent): boolean;
+ move(e: FederatedPointerEvent): boolean;
up(): boolean;
}
@@ -395,9 +397,9 @@ declare class Plugin_2 {
paused: boolean;
constructor(parent: Viewport);
destroy(): void;
- down(_e: InteractionEvent): boolean;
- move(_e: InteractionEvent): boolean;
- up(_e: InteractionEvent): boolean;
+ down(_e: FederatedEvent): boolean;
+ move(_e: FederatedEvent): boolean;
+ up(_e: FederatedEvent): boolean;
wheel(_e: WheelEvent): boolean | undefined;
update(_delta: number): void;
resize(): void;
@@ -434,9 +436,9 @@ export declare class PluginManager {
pause(name: string): void;
resume(name: string): void;
sort(): void;
- down(event: InteractionEvent): boolean;
- move(event: InteractionEvent): boolean;
- up(event: InteractionEvent): boolean;
+ down(event: FederatedEvent): boolean;
+ move(event: FederatedEvent): boolean;
+ up(event: FederatedEvent): boolean;
wheel(e: WheelEvent): boolean;
}
@@ -493,9 +495,7 @@ export declare class Viewport extends Container {
readonly plugins: PluginManager;
zooming?: boolean;
lastViewport?: IViewportTransformState | null;
- readonly options: ICompleteViewportOptions & {
- divWheel: HTMLElement;
- };
+ readonly options: ICompleteViewportOptions;
private _dirty?;
private _forceHitArea?;
private _hitAreaDefault?;
@@ -504,7 +504,7 @@ export declare class Viewport extends Container {
private _worldWidth?;
private _worldHeight?;
private _disableOnContextMenu;
- constructor(options?: IViewportOptions);
+ constructor(options: IViewportOptions);
destroy(options?: IDestroyOptions): void;
update(elapsed: number): void;
resize(screenWidth?: number, screenHeight?: number, worldWidth?: number, worldHeight?: number): void;
diff --git a/package.json b/package.json
index 298b4c88..7dd959f8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "pixi-viewport",
- "version": "4.38.0",
+ "version": "5.0.0",
"description": "A highly configurable viewport/2D camera designed to work with pixi.js. Features include dragging, pinch-to-zoom, mouse wheel zooming, decelerated dragging, follow target, snap to point, snap to zoom, clamping, bouncing on edges, and move on mouse edges.",
"main": "dist/cjs/viewport.js",
"module": "dist/esm/viewport.es.js",
@@ -23,7 +23,7 @@
"docs": "vite build && rimraf ./js && tsc -p ./tsconfig-docs.json --outDir js && rimraf ./docs/dist/jsdoc/ && jsdoc -c .jsdoc.json && node ./scripts/copy",
"docs:serve": "vite preview --outDir dist/",
"upgrade": "yarn upgrade-interactive --latest",
- "prepublishOnly": "yarn build && yarn builds && yarn build:types && yarn docs"
+ "prepublishOnly": "yarn build && yarn docs"
},
"repository": {
"type": "git",
diff --git a/src/InputManager.ts b/src/InputManager.ts
index 81532fe4..993a1949 100644
--- a/src/InputManager.ts
+++ b/src/InputManager.ts
@@ -51,7 +51,7 @@ export class InputManager
this.viewport.on('pointercancel', this.up, this);
this.viewport.on('pointerout', this.up, this);
this.wheelFunction = (e) => this.handleWheel(e);
- this.viewport.options.divWheel.addEventListener(
+ this.viewport.options.events.domElement.addEventListener(
'wheel',
this.wheelFunction as any,
{ passive: this.viewport.options.passiveWheel });
@@ -64,7 +64,7 @@ export class InputManager
*/
public destroy(): void
{
- this.viewport.options.divWheel.removeEventListener('wheel', this.wheelFunction as any);
+ this.viewport.options.events.domElement.removeEventListener('wheel', this.wheelFunction as any);
}
/**
@@ -207,22 +207,7 @@ export class InputManager
{
const point = new Point();
- if (this.viewport.options.interaction)
- {
- this.viewport.options.interaction.mapPositionToPoint(point, event.clientX, event.clientY);
- }
- else if (this.viewport.options.useDivWheelForInputManager && this.viewport.options.divWheel)
- {
- const rect = this.viewport.options.divWheel.getBoundingClientRect();
-
- point.x = event.clientX - rect.left;
- point.y = event.clientY - rect.top;
- }
- else
- {
- point.x = event.clientX;
- point.y = event.clientY;
- }
+ this.viewport.options.events.mapPositionToPoint(point, event.clientX, event.clientY);
return point;
}
@@ -235,13 +220,6 @@ export class InputManager
return;
}
- // do not handle events coming from other elements
- if (this.viewport.options.interaction
- && (this.viewport.options.interaction as any).interactionDOMElement !== event.target)
- {
- return;
- }
-
// only handle wheel events where the mouse is over the viewport
const point = this.viewport.toLocal(this.getPointerPosition(event));
diff --git a/src/Viewport.ts b/src/Viewport.ts
index 33cd92c6..40a382e5 100644
--- a/src/Viewport.ts
+++ b/src/Viewport.ts
@@ -69,36 +69,21 @@ export interface IViewportOptions
noTicker?: boolean;
/**
- * EventSystem, available from instantiated `WebGLRenderer/CanvasRenderer.plugins.interaction`
- *
- * It's used to calculate pointer postion relative to canvas location on screen
+ * EventSystem is required now
*/
- interaction?: EventSystem | null;
+ events: EventSystem;
/**
- * Remove oncontextmenu=() => {} from the divWheel element
+ * Remove oncontextmenu=() => {} from options.events.domElement
*/
disableOnContextMenu?: boolean;
- /**
- * div to attach the wheel event
- *
- * @default document.body
- */
- divWheel?: HTMLElement;
-
/**
* Use this PIXI.ticker for updates
*
* @default PIXI.Ticker.shared
*/
ticker?: Ticker;
-
- /**
- * Uses divWheel definition for InputManager to calculate positioning relative to containing div
- * this is used only if options.interaction is not defined
- */
- useDivWheelForInputManager?: boolean;
}
export interface ICompleteViewportOptions extends IViewportOptions
@@ -120,7 +105,7 @@ export interface IViewportTransformState
scaleY: number;
}
-const DEFAULT_VIEWPORT_OPTIONS: ICompleteViewportOptions = {
+const DEFAULT_VIEWPORT_OPTIONS: Partial = {
screenWidth: window.innerWidth,
screenHeight: window.innerHeight,
worldWidth: null,
@@ -130,7 +115,6 @@ const DEFAULT_VIEWPORT_OPTIONS: ICompleteViewportOptions = {
stopPropagation: false,
forceHitArea: null,
noTicker: false,
- interaction: null,
disableOnContextMenu: false,
ticker: Ticker.shared,
};
@@ -192,7 +176,7 @@ export class Viewport extends Container
public lastViewport?: IViewportTransformState | null;
/** The options passed when creating this viewport, merged with the default values */
- public readonly options: ICompleteViewportOptions & { divWheel: HTMLElement };
+ public readonly options: ICompleteViewportOptions;
private _dirty?: boolean;
private _forceHitArea?: IHitArea | null;
@@ -218,21 +202,17 @@ export class Viewport extends Container
* @param {HitArea} [options.forceHitArea] change the default hitArea from world size to a new value
* @param {boolean} [options.noTicker] set this if you want to manually call update() function on each frame
* @param {PIXI.Ticker} [options.ticker=PIXI.Ticker.shared] use this PIXI.ticker for updates
- * @param {PIXI.EventSystem} [options.interaction=null] EventSystem, available from instantiated
- * WebGLRenderer/CanvasRenderer.plugins.interaction - used to calculate pointer position relative to canvas
+ * @param {PIXI.EventSystem} [options.events] EventSystem available from app.events or added manually and passed here
* location on screen
- * @param {HTMLElement} [options.divWheel=document.body] div to attach the wheel event
- * @param {boolean} [options.disableOnContextMenu] remove oncontextmenu=() => {} from the divWheel element
+ * @param {boolean} [options.disableOnContextMenu] remove oncontextmenu=() => {} from the pixi's events.domElement
*/
- constructor(options: IViewportOptions = {})
+ constructor(options: IViewportOptions)
{
super();
- this.options = Object.assign(
- {},
- { divWheel: document.body },
- DEFAULT_VIEWPORT_OPTIONS,
- options
- );
+ this.options = {
+ ...DEFAULT_VIEWPORT_OPTIONS,
+ ...options,
+ } as ICompleteViewportOptions;
this.screenWidth = this.options.screenWidth;
this.screenHeight = this.options.screenHeight;
@@ -242,11 +222,9 @@ export class Viewport extends Container
this.forceHitArea = this.options.forceHitArea;
this.threshold = this.options.threshold;
- this.options.divWheel = this.options.divWheel || document.body;
-
if (this.options.disableOnContextMenu)
{
- this.options.divWheel.addEventListener('contextmenu', this._disableOnContextMenu);
+ this.options.events.domElement.addEventListener('contextmenu', this._disableOnContextMenu);
}
if (!this.options.noTicker)
{
@@ -267,7 +245,7 @@ export class Viewport extends Container
}
if (this.options.disableOnContextMenu)
{
- this.options.divWheel.removeEventListener('contextmenu', this._disableOnContextMenu);
+ this.options.events.domElement.removeEventListener('contextmenu', this._disableOnContextMenu);
}
this.input.destroy();
@@ -1177,8 +1155,7 @@ export class Viewport extends Container
/**
* Zoom using mouse wheel
*
- * NOTE: the default event listener for 'wheel' event is document.body. Use `Viewport.options.divWheel` to
- * change this default
+ * NOTE: the default event listener for 'wheel' event is the options.events.domElement.
*
* @param {IWheelOptions} [options]
* @param {number} [options.percent=0.1] - percent to scroll with each spin