-
Notifications
You must be signed in to change notification settings - Fork 180
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
React Pixi + Viewport and issues with v5 #438
React Pixi + Viewport and issues with v5 #438
Comments
The issue seems to be related to this change: ee8f2dd#diff-ddb343831b1574d25562089f63f1222cde16e19c841c1a400e5e5d0f1ad176f0R54 https://pixijs.download/release/docs/PIXI.EventSystem.html#domElement
Automatically, but I'm not really sure when (or if) that happens. PS: Passing a brand new instance of |
Have you tried simply importing And in your viewport's instantiator, use Without the import, it wasn't working for me (vanillajs, not in React) and adding the import solved it. |
@sergioisidoro i've setup react pixi (first time) and so this fixed it: const PixiComponentViewport = PixiComponent("Viewport", {
create: (props: PixiComponentViewportProps) => {
// Install EventSystem, if not already
// (PixiJS 6 doesn't add it by default)
if (!("events" in props.app.renderer))
props.app.renderer.addSystem(PIXI.EventSystem, "events");
const { width, height } = props;
const { ticker } = props.app;
const { events } = props.app.renderer;
const viewport = new PixiViewport({
screenWidth: width,
screenHeight: height,
worldWidth: width,
worldHeight: height,
ticker: ticker,
events: events,
});
viewport
.drag()
.pinch()
.wheel()
.clamp({ direction: "all" })
.clampZoom({ minScale: 0.5, maxScale: 1 })
.decelerate();
return viewport;
},
}); |
I'm having some problems with the migration too, I updated the interaction, the viewport is working but when I go to the next page, it gives me a destruction error. on my error it fails to access 'next' inside let listener = this._head.next in the same error he also complains about the destroy(t) function my project is: https://github.com/MatzeStudios/mazeonline/blob/mouse-fix/frontend/src/components/GameScreen/index.js |
I have tried the approach from @lazharichir and can confirm that this allows me to use pixi-viewport with pixi-react. I think manually adding the event system is key (even if there is no error message related to it). It would be great if this could be addressed. When navigating away from the page that contains my pixi-viewport app, I can confirm that I also receive the error mentioned by @LouisGusta, namely:
Also see this thread, where the problem is discussed as well: #441 (comment) Please can this be looked into? As is, this problem prevents me from using pixi-viewport in production. |
Hey all, I am still struggling with this, managed to work around all errors, see the full Viewport.tsx react wrapper on the bottom. The main finding, is that the ticker is already destroyed by the Stage, and there is fortunately a
This is with versions |
I have tried the suggestion from @Balinth, i.e. adding
However, I now get a different error:
Update: I realised that I only changed |
Didn't see that one yet. How / when is that happening for you? |
Here is mine, which is currently working (but throwing me for a loop about wheel-to-zoom not working as expected, but that's another matter). import { PixiComponent, useApp } from '@pixi/react'
import { Viewport as PixiViewport } from 'pixi-viewport'
import * as PIXI from 'pixi.js'
import { ReactNode } from 'react'
export interface ViewportProps {
children?: ReactNode
}
export interface PixiComponentViewportProps extends ViewportProps {
app: PIXI.Application
}
const PixiViewportComponent = PixiComponent('Viewport', {
create: ({ app }: PixiComponentViewportProps) => {
// fix from https://github.com/davidfig/pixi-viewport/issues/438
const events = new PIXI.EventSystem(app.renderer)
events.domElement = app.renderer.view as any
const viewport = new PixiViewport({
events: events,
ticker: app.ticker,
allowPreserveDragOutside: true,
// passiveWheel: false,
})
viewport
.drag({
clampWheel: false,
})
.wheel({
percent: 0.1,
trackpadPinch: true,
})
.decelerate()
.clampZoom({
minScale: 0.25,
maxScale: 5,
})
viewport.on('wheel', e => {
console.log(e)
})
return viewport
},
willUnmount: (viewport: PixiViewport) => {
// @ts-ignore Hack to get around pixi-viewport bug when destroying
viewport.options.noTicker = true
viewport.destroy({ children: true, texture: true, baseTexture: true })
},
})
const Viewport = props => <PixiViewportComponent app={useApp()} {...props} />
export default Viewport |
I have tried the code samples shared above and found the following. (A) Suggestion from @lazharichir - does not work for me. import { EventSystem } from '@pixi/events';
if (!("events" in props.pixiApp.renderer)) {
props.pixiApp.renderer.addSystem(EventSystem, 'events');
}
const { events } = props.pixiApp.renderer; PS: Another test that could potentially be done here is to use (B) Suggestion from @Balinth - does work for me. import { EventSystem } from '@pixi/events';
const events = new EventSystem(props.pixiApp.renderer);
events.domElement = props.pixiApp.renderer.view as any; (C) Suggestions from @Heilemann - does work for me. import * as PIXI from 'pixi.js'
const events = new PIXI.EventSystem(props.pixiApp.renderer);
events.domElement = props.pixiApp.renderer.view as any; Update: I just upgraded to:
and had some problems with the above. So now I am using: import { EventSystem } from "pixi.js";
const events = new EventSystem(props.pixiApp.renderer);
events.domElement = props.pixiApp.renderer.view as any; |
I got things working by directly patching "@pixi/react": "^7.1.1",
"pixi-viewport": "^5.0.2",
"pixi.js": "^7.3.2",
--- a/node_modules/@pixi/react/dist/index.es-dev.js
+++ b/node_modules/@pixi/react/dist/index.es-dev.js
import PropTypes from 'prop-types';
+import '@pixi/events'; and/or similarly in
--- a/node_modules/pixi-viewport/dist/pixi_viewport.js
+++ b/node_modules/pixi-viewport/dist/pixi_viewport.js
destroy() {
- this.viewport.options.events.domElement.removeEventListener("wheel", this.wheelFunction);
+ this.viewport.options.events.domElement?.removeEventListener("wheel", this.wheelFunction);
} and/or similarly in // Viewport.tsx
import React from "react";
import type PIXI from "pixi.js";
import { PixiComponent, useApp } from "@pixi/react";
import { Viewport as PixiViewport } from "pixi-viewport";
const PixiComponentViewport = PixiComponent("Viewport", {
create: ({ app }: PixiComponentViewportProps) => {
app.renderer.events.domElement = app.renderer.view as any;
const viewport = new PixiViewport({
passiveWheel: false,
events: app.renderer.events,
ticker: app.ticker,
});
viewport.drag({
wheel: false,
}).wheel({
wheelZoom: true,
}).pinch().clampZoom({
maxScale: 4,
minScale: 1/4,
});
return viewport;
},
willUnmount: (viewport: PixiViewport) => {
viewport.options.noTicker = true; // fix the `ticker` option above
viewport.destroy({ children: true });
},
});
export default function Viewport(props: ViewportProps) {
const app = useApp();
return <PixiComponentViewport app={app} {...props} />;
}
export interface ViewportProps {
children?: React.ReactNode;
}
export interface PixiComponentViewportProps extends ViewportProps {
app: PIXI.Application;
} Then we can do e.g. return (
<Stage>
<Viewport>
<Sprite
x={250}
y={250}
anchor={[0.5, 0.5]}
interactive={true}
image="https://s3-us-west-2.amazonaws.com/s.cdpn.io/693612/IaUrttj.png"
pointerdown={(e) => {
console.log("pointerdown", e);
}}
/>
</Viewport>
</Stage>
); To support resolve: {
alias: {
'pixi.js': path.resolve(__dirname, 'node_modules/pixi.js/dist/cjs/pixi.min.js'),
'@pixi/react': path.resolve(__dirname, `node_modules/@pixi/react/dist/index.cjs${process.env.NODE_ENV === 'production' ? '' : '-dev'}.js`),
'pixi-viewport': path.resolve(__dirname, 'node_modules/pixi-viewport/dist/pixi_viewport.umd.cjs'),
},
} |
@rob-myers thanks for idea. I found that such way does not optimal for me and there is my alternative approach. As I could see the // ...
class PixiViewportPatch extends PixiViewport {
private renderedDOMElement?: HTMLElement;
constructor(options: IViewportOptions) {
super(options);
this.lockDOMElement();
}
lockDOMElement() {
this.renderedDOMElement = this.options.events.domElement;
return this;
}
patchEvents() {
if (this.renderedDOMElement) {
this.options.events.domElement = this.renderedDOMElement;
}
}
releaseDOMElement() {
this.renderedDOMElement = undefined;
}
}
const PixiComponentViewport = PixiComponent("Viewport", {
create: (props: PixiComponentViewportProps) => {
const {events} = props.app.renderer;
const instance = new PixiViewportPatch({
// ...
events: events,
});
// ...
return instance;
},
willUnmount: (instance: PixiViewportPatch) => {
// workaround because the ticker is already destroyed by this point by the stage
instance.options.noTicker = true;
// workaround DOMElement: the domElement has been removed from events before willUnmount()
instance.patchEvents();
instance.destroy({children: true, texture: true, baseTexture: true});
// workaround DOMElement: restore changes after patch
instance.releaseDOMElement();
}
});
const Viewport = forwardRef<null, ViewportProps>(function Viewport(props: ViewportProps, ref: React.Ref<PixiViewportPatch>) {
const app = useApp();
return <PixiComponentViewport ref={ref} app={app} {...props} />;
});
export default Viewport; |
@OxCom wow, that solved a somewhat unrelated problem I was having where the zoom and center was resetting pretty much every time I |
I'm trying to port the simplest version of the React Pixi Viewport from here:
https://codesandbox.io/s/react-pixi-viewport-9ngfd and https://codepen.io/inlet/pen/yLVmPWv
According to the latest breaking change from v5
interaction: props.app.renderer.plugins.interaction
should beevents: props.app.renderer.events
I've tried a couple of things but could not get anything to work.
I wonder if something else has recently changed in v5? On 4.38.0 of pixi-viewport things still work ok.
Documentation on the new usage of the events is also quite scarce, with most examples still pointing to interactions (including official docs)
Disclaimer, I'm super new to Pixi.js.
Reproduction:
https://codesandbox.io/s/react-pixi-viewport-forked-5gt5bl?file=/src/Viewport.tsx:712-720
(Note how changing the pixi-viewport to 4.38 fixes the issue)
Edit: Full trace:
(Note that
Viewport
component is my own wrapper of pixi-viewport)The text was updated successfully, but these errors were encountered: