davidfig / pixi-viewport

A highly configurable viewport/2D camera designed to work with pixi.js
https://davidfig.github.io/pixi-viewport/
MIT License
1.04k stars 174 forks source link

`import "pixi-viewport"` won't import properly in NextJS #474

Open shipurjan opened 7 months ago

shipurjan commented 7 months ago

Hello, I'm using NextJS inside Tauri.

I set all components (and all pages in the router + layout) to client, however I still can't import pixi-viewport, because it references window

✓ Compiled / in 5.5s (1299 modules)
 ⨯ node_modules\.pnpm\pixi-viewport@5.0.2\node_modules\pixi-viewport\dist\pixi_viewport.js (1307:15) @ window
 ⨯ ReferenceError: window is not defined
    at __webpack_require__ (C:\Users\niar-windows\Documents\repos\bioparallel\.next\server\webpack-runtime.js:33:42)
    at eval (./src/components/pixi/viewport/viewport.tsx:8:71)
    at (ssr)/./src/components/pixi/viewport/viewport.tsx (C:\Users\niar-windows\Documents\repos\bioparallel\.next\server\app\page.js:195:1)
    at __webpack_require__ (C:\Users\niar-windows\Documents\repos\bioparallel\.next\server\webpack-runtime.js:33:42)
    at eval (./src/components/pixi/canvas/canvas.tsx:8:92)
    at (ssr)/./src/components/pixi/canvas/canvas.tsx (C:\Users\niar-windows\Documents\repos\bioparallel\.next\server\app\page.js:184:1)
    at __webpack_require__ (C:\Users\niar-windows\Documents\repos\bioparallel\.next\server\webpack-runtime.js:33:42)
    at eval (./src/app/page.tsx:7:88)
    at (ssr)/./src/app/page.tsx (C:\Users\niar-windows\Documents\repos\bioparallel\.next\server\app\page.js:162:1)
    at __webpack_require__ (C:\Users\niar-windows\Documents\repos\bioparallel\.next\server\webpack-runtime.js:33:42)
    at JSON.parse (<anonymous>)
null
 ✓ Compiled in 215ms (656 modules)

The lines causing this seem to be below, because if I change them to fixed values the error disappears

const et = {
  screenWidth: window.innerWidth, // this
  screenHeight: window.innerHeight, // this
  worldWidth: null,
  worldHeight: null,
  threshold: 5,
  passiveWheel: !0,
  stopPropagation: !1,
  forceHitArea: null,
  noTicker: !1,
  disableOnContextMenu: !1,
  ticker: O.shared,
  allowPreserveDragOutside: !1
};

in \node_modules\.pnpm\pixi-viewport@5.0.2\node_modules\pixi-viewport\dist\pixi_viewport.js

Here is the code I'm using:

"use client";

import { PixiComponent, useApp } from "@pixi/react";
import { Viewport as PixiViewport } from "pixi-viewport"; // I think this causes error
import * as PIXI from "pixi.js";
import { ReactNode } from "react";

export type ViewportProps = {
    children?: ReactNode;
};

export type PixiComponentViewportProps = ViewportProps & {
    app: PIXI.Application;
};

const PixiViewportComponent = PixiComponent("Viewport", {
    create: ({ app }: PixiComponentViewportProps) => {
        const events = new PIXI.EventSystem(app.renderer);
        events.domElement = app.renderer.view as HTMLCanvasElement;

        const viewport = new PixiViewport({
            events: app.renderer.events,
            ticker: app.ticker,
            passiveWheel: false,
            allowPreserveDragOutside: true,
        });

        viewport
            .drag({
                wheel: false,
            })
            .wheel({
                wheelZoom: true,
            })
            .pinch()
            .clampZoom({
                minScale: 1 / 4,
                maxScale: 4,
            });

        return viewport;
    },
    willUnmount: (viewport: PixiViewport) => {
        // eslint-disable-next-line no-param-reassign
        viewport.options.noTicker = true;
        viewport.destroy({ children: true });
    },
});

export function Viewport({
    ...props
}: Omit<PixiComponentViewportProps, "app">) {
    const app = useApp();
    return <PixiViewportComponent app={app} {...props} />;
}

Changing these lines to

  screenWidth: typeof window === 'undefined' ? 0 : window.innerWidth,
  screenHeight: typeof window === 'undefined' ? 0 : window.innerHeight,

seems to fix it.

pietrovismara commented 7 months ago

The thing is the issue was already solved in this commit but it seems the change was never published with a new version on npm.

@davidfig Am I correct? Any chance you could publish a new version?

picheli20 commented 7 months ago

For now, I managed to by-pass importing the lib only when is rendered by the browser.

    if (isPlatformBrowser(this.platformId)) { // <--- angular validation to check if the platform is browser
      const { Viewport } = await import('pixi-viewport');

      this.viewPort = new Viewport({
        worldWidth: this.app.stage.width,
        worldHeight: this.app.stage.height,
        screenWidth: this.app.renderer.width,
        screenHeight: this.app.renderer.height,
        events: this.app.renderer.events,
      });
    }
jerrygreen commented 4 months ago

Facing the same issue with window object used wihtin pixi-viewport. Not using Tauri but similar approach as yours.

The first thing I did was also this:

const { Viewport } = await import('pixi-viewport')

But then I'm now facing an error when trying to:

viewport.addChild(bunny)

It raises a runtime error:

TypeError: Cannot set properties of undefined (setting '_parentID')

Not completely sure if this is consecutive issue of another. Or they're two separate things.

Additionally, it raises an error in tsc:

Argument of type 'Sprite' is not assignable to parameter of type 'DisplayObject'

In other threads they say to re-install node_modules but this doesn't help: still wrong types.

Were you able to make it all work? Successfully draw a bunny or something?

shipurjan commented 4 months ago

@jerrygreen Yeah I made it work for 5.0.2 (I didn't upgrade to 5.1.0 yet) by using patch command in pnpm:

https://github.com/shipurjan/bioparallel/blob/master/patches/pixi-viewport%405.0.2.patch

pnpm applies this patch every time I install packages and I haven't had problems ever since

nightgrey commented 4 months ago

The problem seems to be this: https://github.com/davidfig/pixi-viewport/issues/487