Package Exports
- @pixi/react
Readme
Pixi React
Simply the best way to write PixiJS applications in React
Write PixiJS applications using React declarative style 👌
Pixi React is an open-source, production-ready library to render high performant PixiJS applications in React.
Features
- React v17 and v18 support
- PixiJS v8 support
Getting Started
Quick Start
If you want to start a new React project from scratch then we recommend Create React App, but Pixi React should work with any React application (Remix, Next.js, etc). To add to an existing React application, just install the dependencies:
Install Pixi React Dependencies
npm install pixi.js@^8.2.1 @pixi/reactPixie React Usage
import {
Application,
extend,
} from '@pixi/react'
import {
Container,
Graphics,
} from 'pixi.js'
import { useCallback } from 'react'
extend({
Container,
Graphics,
})
const MyComponent = () => {
const drawCallback = useCallback(graphics => {
graphics.clear()
graphics.setFillStyle({ color: 'red' })
graphics.rect(0, 0, 100, 100)
graphics.fill()
}, [])
return (
<Application>
<container x={100} y={100}>
<graphics draw={drawCallback} />
</container>
</Application>
)
}Docs
extend
One of the most important concepts to understand with Pixi React v7 is extend. Normally, Pixi React would have to import all pf Pixi.js to be able to provide the full library as JSX components. Instead, we use an internal catalogue of components populated by the extend API. This allows you to define exactly which parts of Pixi.js you want to import, keeping your bundle sizes small.
To allow Pixi React to use a Pixi.js component, pass it to the extend API:
import { Container } from 'pixi.js'
import { extend } from '@pixi/react'
extend({ Container })
const MyComponent = () => (
<container />
)[!CAUTION] Attempting to use components that haven't been passed to the
extendAPI will result in errors.
Components
<Application>
The <Application> component is used to wrap your Pixi React app. The <Application> component can take all props that can be set on PIXI.Application.
Example Usage
import { Application } from '@pixi/react'
const MyComponent = () => {
return (
<Application
autoStart
sharedTicker />
)
}[!NOTE]
The
<Application>component supports theresizeToproperty, with some additional functionality: it can accept a Reactref. As an example:import { Application } from '@pixi/react' import { useRef } from 'react' const MyComponent = () => { const parentRef = useRef(null) return ( <div ref={parentRef}> <Application resizeTo={parentRef} /> </div> ) }
All Other Components
All other Pixi React components should be included in your IDE's intellisense/autocomplete once you've installed/imported @pixi/react. If it's exported from Pixi.js, it's supported as a component in Pixi React. The only difference is that Pixi React components will always start with lowercase characters. Here's a selection of commonly used components:
<container />
<graphics />
<sprite />
<animatedSprite />
<text />
<htmlText />
<filter />The only component with custom functionality is the graphics component. To avoid having to use a ref to draw to the Graphics context, the <graphics> component has an additional draw property. draw takes a callback which receives the Graphics context, allowing drawing to happen on every tick.
const MyComponent = () => {
return (
<graphics draw={graphics => {
graphics.clear()
graphics.setFillStyle({ color: 'red' })
graphics.rect(0, 0, 100, 100)
graphics.fill()
}} />
)
}[!IMPORTANT] You may run into some components that conflict with others. For example, the
<text>component often conflicts with the<text>component that's built-in to React for use in SVGs. To address this issue, all components are available with thepixiprefix. For example, you can replace the<text>component with the<pixiText>component. It will have the same functionality with none of the collisions.
Hooks
useApp
useApp allows access to the parent PIXI.Application created by the <Application> component. This hook will not work outside of an <Application> component. Additionally, the parent application is passed via React Context. This means useApp will only work appropriately in child components, and not directly in the component that contains the <Application> component.
For example, the following example useApp will not be able to access the parent application:
import {
Application,
useApp,
} from '@pixi/react'
const ParentComponent = () => {
// This will cause an invariant violation.
const app = useApp()
return (
<Application />
)
}Here's a working example where useApp will be able to access the parent application:
import {
Application,
useApp,
} from '@pixi/react'
const ChildComponent = () => {
const app = useApp()
console.log(app)
return (
<container />
)
}
const ParentComponent = () => (
<Application>
<ChildComponent />
</Application>
)useAsset
The useAsset hook wraps the functionality of Pixi's Asset loader and cache into a convenient React hook. The hook can accept either an UnresolvedAsset or a url.
import { useAsset } from '@pixi/react'
const MyComponent = () => {
const bunnyTexture = useAsset('https://pixijs.com/assets/bunny.png')
const bunnyTexture2 = useAsset({
alias: 'bunny',
src: 'https://pixijs.com/assets/bunny.png',
})
return (
<container>
<sprite texture={bunnyTexture}>
<sprite texture={bunnyTexture2}>
</container>
)
}Tracking Progress
useAsset can optionally accept a ProgressCallback as a second argument. This callback will be called by the asset loader as the asset is loaded.
const bunnyTexture = useAsset('https://pixijs.com/assets/bunny.png', progress => {
console.log(`We have achieved ${progress * 100}% bunny.`)
})[!TIP] The
useAssethook also supports React Suspense! If given a suspense boundary, it's possible to prevent components from rendering until they've finished loading their assets:import { Application, useAsset, } from '@pixi/react' import { Suspense } from 'react'; const BunnySprite = () => { const bunnyTexture = useAsset('https://pixijs.com/assets/bunny.png') return ( <sprite texture={bunnyTexture} /> ) } const LoadingText = () => ( <pixiText text={'Loading...'} /> ) const MyApp = () => ( <Application> <Suspense fallback={<LoadingText />}> <BunnySprite /> </Suspense> </Application> )
useExtend
useExtend allows the extend API to be used as a React hook. Additionally, the useExtend hook is memoised, while the extend function is not.
import { Container } from 'pixi.js'
import { useExtend } from '@pixi/react'
const MyComponent = () => {
useExtend({ Container })
return (
<container />
)
}useTick
useTick allows a callback to be attached to the Ticker on the parent application.
import { useTick } from '@pixi/react'
const MyComponent = () => {
useTick(() => console.log('This will be logged on every tick'))
}useTick optionally takes a boolean as a second argument. Setting this boolean to false will cause the callback to be disabled until the argument is set to true again.
import { useState } from 'react'
import { useTick } from '@pixi/react'
const MyComponent = () => {
const [isEnabled, setIsEnabled] = useState(false)
useTick(() => console.log('This will be logged on every tick as long as `isEnabled` is `true`'), )
return (
<sprite onClick={setIsEnabled(previousState => !previousState)}>
)
}