Skip to content

Pixi Solid

PixiJS and SolidJS. An excellent combination for high performance interactive 2D graphics on the web.

Pixi Solid is a library that provides SolidJS components and hooks for working with PixiJS.

  • 💙 Lightweight and flexible SolidJS library for creating PixiJS applications.
  • 🎁 Provides a set of custom SolidJS components that create PixiJS objects instead of HTML elements.
  • 📦 Supports all PixiJS objects, such as Filter, Container, Sprite, Graphics, Text, etc.
  • 🧑‍💻 The convenience and speed of SolidJS stores and signals to manage state.
  • ✨ All events emitted by PixiJS objects are supported.
  • 😎 No limitations. Break out of SolidJS any time and interact directly with PixiJS.
  • 💫 Useful helper utilities included.
  • 🤩 Full Typescript support for type safety and auto completion.

Terminal window
npm i pixi-solid pixi.js solid-js

Peer dependencies of

{
"pixi.js": "^8.14.3",
"solid-js": "^1.9.10"
}

  • Declarative PixiJS scene graph: Using SolidJS’s JSX templating means we get declarative control over the scene graph. No longer necessary to imperatively add and remove children.

  • Lifecycle hooks in our PixiJS components: SolidJS rendering PixiJS components means we can take advantage of the built in lifecycle methods in SolidJS onMount and onCleanup as well as few extra custom hooks so we can automatically subscribe and unsubscribe from the ticker.

  • Shared State and Reactivity: Pixi Solid leverages SolidJS’s reactivity system to automatically update PixiJS components when SolidJS signals or stores change. HTML elements and PixiJS graphics can stay in sync effortlessly.

  • Composability: Pixi Solid components can be easily composed together to create complex scenes and animations out of reusable components.

  • SolidJS is a thin wrapper: While Pixi Solid provides a nice abstraction over PixiJS it still provides access to all the properties and events of PixiJS objects directly.

  • SolidJS is really fast: SolidJS is on of the fatsest front-end frameworks out there so the overhead is very minimal.

  • SolidJS is fully featured: It has stores, signals, suspense, error boundaries, resource fetching and more. It’s a great feature set for simple or complex applications and you won’t have to reach for other libraries to manage templating or state.


import type * as Pixi from "pixi.js";
import { Assets, BlurFilter, Rectangle } from "pixi.js";
import { CRTFilter } from "pixi-filters";
import { Container, getPixiApp, onTick, PixiApplication, PixiCanvas, PixiStage, Sprite } from "pixi-solid";
import { objectFit } from "pixi-solid/utils";
import { createResource, onCleanup, Show } from "solid-js";
import { Character } from "./character";
import { Controls } from "./controls";
import { createAppStore } from "./create-app-store";
import { Ground } from "./ground";
import { loadSceneAssets } from "./load-scene-assets";
export const DemoApp = () => {
const appStore = createAppStore();
const [textureResource] = createResource(loadSceneAssets);
const sceneBounds = new Rectangle(0, 0, 200, 133);
const blurFilter = new BlurFilter({ strength: 8 });
const crtFilter = new CRTFilter({
curvature: 3,
lineContrast: 0.1,
vignetting: 0.1,
noise: 0.04,
noiseSize: 2,
});
onCleanup(() => {
blurFilter.destroy();
crtFilter.destroy();
});
return (
<div style={{ position: "relative" }}>
<PixiApplication>
<Controls
isRunning={appStore.state.isRunning}
direction={appStore.state.direction}
onToggleDirectionClicked={appStore.toggleDirection}
onToggleRunningClicked={appStore.toggleRunning}
/>
<PixiCanvas
style={{
"aspect-ratio": `${sceneBounds.width}/${sceneBounds.height}`,
overflow: "hidden",
"border-radius": "10px",
}}
>
<Show when={textureResource()}>
<PixiStage filters={crtFilter}>
<Container
ref={(container) => {
const app = getPixiApp();
onTick((ticker) => {
objectFit(container, app.renderer, "cover");
crtFilter.seed = Math.random() * 10;
crtFilter.time += ticker.deltaTime * 0.3;
});
}}
>
<Sprite label="Sky" texture={Assets.get<Pixi.Texture>("sky")} filters={blurFilter} />
<Ground
movementSpeed={appStore.state.isRunning ? 1.3 : 0}
direction={appStore.state.direction}
width={sceneBounds.width}
height={sceneBounds.height * 0.3}
position={{ x: 0, y: sceneBounds.height * 0.7 }}
/>
<Character
direction={appStore.state.direction}
isRunning={appStore.state.isRunning}
position={{ x: sceneBounds.width * 0.5, y: sceneBounds.height * 0.5 }}
/>
</Container>
</PixiStage>
</Show>
</PixiCanvas>
</PixiApplication>
</div>
);
};