4

Context

I like to use pixi.js for a game I have in mind. Over the years I always used React and next.js.

So what I want to do it use pixi.js inside React / Next.

There are 2 packages out there that integrate into react fiber to render component like but they are outdated and give so many errors to me (for example doesn't work with react 18 and also have poor documentations). (@inlet/react-pixi and react-pixi-fiber)

So I decided to go the useRef route.

Here is some code that works fine:

import { useRef, useEffect } from "react";
import { Application, Sprite, Texture } from "pixi.js";
import bunnyImg from "../public/negx.jpg";

const app = new Application({
  width: 800,
  height: 600,
  backgroundColor: 0x5bba6f,
});

const Pixi = () => {
  const ref = useRef();

  useEffect(() => {
    // On first render add app to DOM
    ref.current.appendChild(app.view);
    // Start the PixiJS app
    app.start();

    const texture = Texture.from(bunnyImg.src);
    const bunny = new Sprite(texture);
    bunny.anchor.set(0.5);
    bunny.x = 0;
    bunny.y = 0;
    bunny.width = 100;
    bunny.height = 100;

    app.stage.addChild(bunny);

    return () => {
      // On unload stop the application
      app.stop();
    };
  }, []);

  return <div ref={ref} />;
};

export default Pixi;

The Problem

The only problem I have with this is, that hot reload doesn't work. So if I change something in the useEffect hook, I have to go into the browser and manually refresh the page. So basically hot reloading doesn't work.

I think since it uses a ref that basically never changes.

The question

Is there a better way of coding pixi.js inside react / next?

GeraltDieSocke
  • 1,524
  • 3
  • 20
  • 51

3 Answers3

1

It's probably unrelated to react-pixi. It looks like the default behavior of hot reloading as described on the Github repo.

Hooks would be auto updated on HMR if they should be. There is only one condition for it - a non zero dependencies list.

and

❄️ useEffect(effect, []); // "on mount" hook. "Not changing the past"

The code in the question is using such an empty dependency list, so the behavior is as expected.

Please post the full setup including the hot reload configuration if this is not the issue.

inwerpsel
  • 2,677
  • 1
  • 14
  • 21
1

You can use the official library for react: https://pixijs.io/pixi-react (https://github.com/pixijs/pixi-react)

For it to work correctly with Next.js (v13+), you need to put "use client" in your page. Here's an example:

"use client";

import { BlurFilter } from "pixi.js";
import { Stage, Container, Sprite, Text } from "@pixi/react";
import { useMemo } from "react";

export default function Home() {
  const blurFilter = useMemo(() => new BlurFilter(4), []);

  return (
    <Stage>
      <Sprite image="https://pixijs.io/pixi-react/img/bunny.png" x={400} y={270} anchor={{ x: 0.5, y: 0.5 }} />

      <Container x={400} y={330}>
        <Text text="Hello World" anchor={{ x: 0.5, y: 0.5 }} filters={[blurFilter]} />
      </Container>
    </Stage>
  );
}
Shahriar
  • 1,855
  • 2
  • 21
  • 45
0

If you want Pixi/Canvas gets auto refreshed on the rendering cycle, you probably need to define those values with react states and add those states to the useEffect dependencies

For example:

const [bunnyProps, setBunnyProps] = React.useState({
  anchor: 0.5,
  x: 0,
  y: 0,
  width: 100,
  height: 100,
})

React.useEffect(() => {
  // ...
  bunny.x = bunnyProps.x;
  bunny.y = bunnyProps.y;
  // ...
}, [bunnyProps])
MarkoCen
  • 2,189
  • 13
  • 24