Here at Rincon Strategies, we are big fans ReactJS and PixiJS. The former gives
you a new way to build your web applications, with a focus on performance and a declarative style. The latter is a blazing
fast and feature rich webGL rendering engine for games and multimedia in the browser.
Both have their strengths and weaknesses, so when needed, we love the pattern of mixing both in a project
and utilizing the React Component Life Cycle to
to wrap our PixiJS game component and gain some added benefits of a declarative ReactJS application.
Let's say you have a webapp that will mix some React components
with a Game canvas and you need to keep some shared state in both. e.g. Control button states, inventory etc. Drawing buttons
and handling various click, hover, and toggled states is a very imperative process in PixiJS.
So if your interactive components don't need to be in the canvas, move them out and let React handle those elements, and pass props
to the Pixi game, which can in turn, update what needs to be updated via the Component Life Cycle hooks.
PixiJS Canvas Component
To show how we do this at Rincon, let's setup a simple app to zoom the PixiJS Canvas from a button outside the game scene-
In this section, we setup our Canvas component to accept a very simple zoomLevelPropType,
render a container to hold our game canvas, and then use the lifecycle method componentDidMount to hook up our PixiJS Renderer. The important
piece here is that we have to use componentDidMount to setup the Pixi Canvas, since that method runs when the DOM
has been rendered on the client and we can access the required node via refs.
The next step is to start the PixiJS game loop.
We accomplish this by making a simple animation function, which we pre-bind in the constructor. This function is called
once in componentDidMount and recursively renders our stage with the PixiJS renderer. Now that the plumbing is out of the
way, lets have it do something interesting.
Here we created a new function updateZoomLevel, bound it in the constructor, and called it when we receive new props. One
important thing to notice here, is we used two new component life cycle methods, shouldComponentUpdate and componentWillReceiveProps.
shouldComponentUpdate is used to determine whether we should bother running making any Pixi updates, by comparing the new
zoom level to the old zoom level. This could technically be done inside the updateZoomLevel function, but it's a good practice to keep the
methods as simple as possible. Finally, componentWillReceiveProps is used to call
our various imperative methods to update the game scene.
React Application Component
Voila! Now, our React application can easily use this game Canvas and externally control the zoom level of the Pixi game using
React's wonderful declarative style and synthetic event system.
As with a lot of React JS examples, the benefits of this approach might not become clear until you application grows. However,
we have used this pattern in large applications and it certainly helps reign in the complexity of the very imperative (but powerful) style of
writing a PixiJS application.
Wanna follow along and are having trouble getting PixiJS to work with Webpack? Michael Jackson
posted a great tweet on how to get this working.