davidfig/pixi-viewport

React Pixi + Viewport and issues with v5

sergioisidoro opened this issue ยท 14 comments

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 be events: 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:

    "@pixi/react": "^7.0.3",
    "pixi-viewport": "^5.0.1",
    "pixi.js": "^7.2.2",

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:

react-reconciler.development.js:9860 The above error occurred in the <Viewport> component:

    at Viewport
    at Viewport (http://localhost:3000/static/js/bundle.js:366:66)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
logCapturedError @ react-reconciler.development.js:9860
update.callback @ react-reconciler.development.js:9893
callCallback @ react-reconciler.development.js:5094
commitUpdateQueue @ react-reconciler.development.js:5115
commitLayoutEffectOnFiber @ react-reconciler.development.js:15019
commitLayoutMountEffects_complete @ react-reconciler.development.js:16366
commitLayoutEffects_begin @ react-reconciler.development.js:16352
commitLayoutEffects @ react-reconciler.development.js:16290
commitRootImpl @ react-reconciler.development.js:18966
commitRoot @ react-reconciler.development.js:18825
performSyncWorkOnRoot @ react-reconciler.development.js:18225
flushSyncCallbacks @ react-reconciler.development.js:2936
(anonymous) @ react-reconciler.development.js:17756
pixi_viewport.js:1138 Uncaught TypeError: Cannot read properties of undefined (reading 'domElement')
    at $.addListeners (pixi_viewport.js:1138:1)
    at new $ (pixi_viewport.js:1135:1)
    at new ht (pixi_viewport.js:1343:1)
    at Object.create (PixiViewport.tsx:18:1)
    at createElement (element.js:60:1)
    at completeWork (react-reconciler.development.js:13604:1)
    at completeUnitOfWork (react-reconciler.development.js:18739:1)
    at performUnitOfWork (react-reconciler.development.js:18711:1)
    at workLoopSync (react-reconciler.development.js:18609:1)
    at renderRootSync (react-reconciler.development.js:18577:1)
addListeners @ pixi_viewport.js:1138
$ @ pixi_viewport.js:1135
ht @ pixi_viewport.js:1343
create @ PixiViewport.tsx:18
createElement @ element.js:60
completeWork @ react-reconciler.development.js:13604
completeUnitOfWork @ react-reconciler.development.js:18739
performUnitOfWork @ react-reconciler.development.js:18711
workLoopSync @ react-reconciler.development.js:18609
renderRootSync @ react-reconciler.development.js:18577
recoverFromConcurrentError @ react-reconciler.development.js:17958
performSyncWorkOnRoot @ react-reconciler.development.js:18204
flushSyncCallbacks @ react-reconciler.development.js:2936
(anonymous) @ react-reconciler.development.js:17756
pixi_viewport.js:1349 Uncaught TypeError: Cannot read properties of undefined (reading 'update')
    at ht.update (pixi_viewport.js:1349:1)
    at options.noTicker.tickerFunction [as fn] (pixi_viewport.js:1343:1)
    at TickerListener.emit (TickerListener.ts:71:1)
    at _Ticker.update (Ticker.ts:427:1)
    at _tick (Ticker.ts:129:1)

(Note that Viewport component is my own wrapper of pixi-viewport)

The issue seems to be related to this change: ee8f2dd#diff-ddb343831b1574d25562089f63f1222cde16e19c841c1a400e5e5d0f1ad176f0R54

https://pixijs.download/release/docs/PIXI.EventSystem.html#domElement

The DOM element to which the root event listeners are bound. This is automatically set to the renderer's view.
Default Value: undefined

Automatically, but I'm not really sure when (or if) that happens.

PS: Passing a brand new instance ofEventSystem also does not work events: new PIXI.EventSystem(props.app.renderer)

Have you tried simply importing import { EventSystem } from "@pixi/events"; without using it directly?

And in your viewport's instantiator, use events: app.renderer.events, (or props... for you).

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
at Ticker.ts

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 as well. However, I am not clear why we have to manually add the event system. It would be great if this could be explained?

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:

Cannot read properties of null (reading 'next')
at _Ticker.remove

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.