PixiJS is the fastest, most lightweight 2D library available for the web, working
across all devices and allowing you to create rich, interactive graphics and cross-platform applications using WebGL and WebGPU.
Setup
It's easy to get started with PixiJS! Just use our PixiJS Create CLI and get set up in just one command:
npm create pixi.js@latest
or to add it to an existing project:
npm install pixi.js
Usage
import{Application,Assets,Sprite}from'pixi.js';(async()=>{// Create a new applicationconstapp=newApplication();// Initialize the applicationawaitapp.init({background: '#1099bb',resizeTo: window});// Append the application canvas to the document bodydocument.body.appendChild(app.canvas);// Load the bunny textureconsttexture=awaitAssets.load('https://pixijs.com/assets/bunny.png');// Create a bunny Spriteconstbunny=newSprite(texture);// Center the sprite's anchor pointbunny.anchor.set(0.5);// Move the sprite to the center of the screenbunny.x=app.screen.width/2;bunny.y=app.screen.height/2;app.stage.addChild(bunny);// Listen for animate updateapp.ticker.add((time)=>{// Just for fun, let's rotate mr rabbit a little.// * Delta is 1 if running at 100% performance *// * Creates frame-independent transformation *bunny.rotation+=0.1*time.deltaTime;});})();
Contribute
Want to be part of the PixiJS project? Great! All are welcome! We will get there quicker
together :) Whether you find a bug, have a great feature request, or you fancy owning a task
from the road map above, feel free to get in touch.
We're passionate about making PixiJS the best graphics library possible. Our dedication comes from our love for the project and community. If you'd like to support our efforts, please consider contributing to our open collective.
Talk to me about tilemaps, grapefruit uses the Tiled Editor json format for tilemaps. But I am less worried about specifics for that format, talk to me more about how you think tilemaps should render using Pixi.
I was thinking about having a Map (extends DisplayObjectContainer) with Layers (each extending DisplayObjectContainer). The Layers each generate and add one PIXI.Sprite for each "tile" on the map. I was thinking they would each share a PIXI.Texture instance for the texture holding all the tiles, and do some offset fancyness to make that work.
Is there a better way to do tilemaps in Pixi? How would you do it? I cam move this to the forums if it would be more appropriate there.
When I load a texture into a sprite, and then ask for the sprite's width, I get a value of 1. Only after going through the animation loop a couple times does the width become valid. Is there a reliable way to check the dimensions of a loaded texture?
var stage = new PIXI.Stage(0x66FF99);
var renderer = new PIXI.CanvasRenderer(800, 600);
document.body.appendChild(renderer.view);
var texture = PIXI.Texture.fromImage("stone.png");
var stone = new PIXI.Sprite(texture);
console.log(stone.width + ', ' + stone.height);
stage.addChild(stone);
console.log(stone.width + ', ' + stone.height);
requestAnimFrame( animate );
console.log(stone.width + ', ' + stone.height);
renderer.render(stage);
console.log(stone.width + ', ' + stone.height);
All of those console.log()s log "1, 1" even though it should be 128, 128. If I put that console.log() in the animation loop, it does start to output 128, 128.
I have two stages, A loader stage and a gameWorld stage. Every frame I call .render on the WebGLRenderer instance. passing it the current stage. During asset loading the stage passed is the loader stage, which renders a loading screen with a few sprites. Once asset loading is complete, the current stage is set to the gameWorld stage, with a large number of various sprites.
The issue is that when the stage is replaced, sprites from the previous stage are not removed from the webGL context. Instead they are rendered above everything else.
I'm trying out a Pixi WebGL demo, based on one of the Photon Storm ones. I'm running it in Chrome 25.0.1364.152 through Xampp local server.
When I'm updating the JavaScript, saving & refreshing, every so often the renderer seems to get confused and drops the resolution of all Sprites by about half. Upon refreshing again, it does it again until all assets are completely invisible. Booting the page up in an incognito window seems to solve it, but I thought I'd mention it.
We've implemented an open source HTML5 2D Molecular Dynamics simulation framework and are using SVG and D3.js to render the particles.
Performance is reasonable but there has recently been a terrible SVG performance regression in Firefox.
So we wrote a simple benchmark test to help us evaluate Pixi.js, KineticJS) + Shape Caching, and SVG using D3.js
The results were very confusing ... I'm sharing this here because I thought you would be interested ... in general Pixi.js is very good ...but also there seems to serious relative performance issues on Safari, Mobile Safari, and Android browsers.
Here are the three versions of the benchmark test:
Anyway here's the very confusing "executive summary" ... following this are the data I collected if you want to dig deeper.
I've collected performance data from three of Piotr's red-circle animation benchmarks from iPad, Android, Mac OS X 10.6.8, 10.8.3, and Windows 7.
Tested on all platforms:
D3 SVG request AnimationFrame
Canvas KineticJS + Shape Caching
Pixi.js Canvas Renderer
The results are bizarre.
The only consistent results are where WebGL is available Pixi.js WebglRenderer is the fastest by far.
On all the Safari-based browsers (including Mobile Safari on the iPad) the D3 SVG rendering is faster.
Chrome on Android was recently updated from v18 to v25. Chrome v25 now appears to be at least three times slower rendering SVG than Chrome 18.
The stock Android browser is 3x faster rendering SVG than Chrome 25.
On all versions of Safari the Pixi.js Canvas renderer is much slower than than Canvas KineticJS + Shape Caching.
On all the other browsers the Pixi.js Canvas renderer is much faster than Canvas KineticJS + Shape Caching.
EXCEPT on the stock Android browser where the Pixi.js Canvas renderer is 4x slower than Canvas KineticJS + Shape Caching.
On all versions of Firefox Pixi.js CanvasRenderer is much faster than Canvas KineticJS + Shape Caching which in turn is much faster than D3 SVG request AnimationFrame.
On all versions of Chromw (except on Android) Pixi.js CanvasRenderer is about twice as fast as either Canvas KineticJS + Shape Caching or D3 SVG request AnimationFrame (which are about the same).
Caching for PIXI.Texture.fromCanvas() return first cached texture.
it is wrong to use 'canvas' as key for TextureCache[] and BaseTextureCache[]
Also I it think caching for canvas is bad idea, because canvas can change content.
I love the philosophy of pixi.js and the demos are impressive. So I'd really like to teach my students JavaScript through pixi.js. However, it won't run locally (entering file:///C:/etc in the address bar of Chrome) for me. I have to host the HTML/JavaScript code to get the examples to run.
I know I can install a simple local webserver, but then we lose out on live editing (which WebStorm beautifully supports), simplicity and other conveniences. Is there any way I can use pixi.js locally? I get the following error for the Basics example:
Uncaught Error: SecurityError: DOM Exception 18 pixi.js:58
PIXI.WebGLRenderer.updateTexture pixi.js:58
PIXI.WebGLRenderer.render pixi.js:56
animate index.html:51
Hi. I've been playing a bit with Pixi, and enjoying it a lot so far.
I was wondering about setting the frame of a texture. It did not work for me at first, and I had to look around in the source to find the "noFrame" flag. Is this expected / normal? There was no mention of it in the docs for setFrame().
(Whoops, had to edit this issue because I accidentally prematurely posted it :/)
Annyways, I noticed you guys included some built files in the repo. I was wondering if you could include some instructions in the README to create our own builds.
For example, I would love to make a build that is not minified, to be able to explore the source a bit more.
Android browser canvas implementation bugs rendering alternative
Specially with the CSS3 Shaders, we can do some very interesting effects.
I just made a demo to prove the point here, which you can try on your iOS here.
If you press the 3rd button, you can see a CSS3 Grayscale Shader in action, in all 60fps glory.
I'm attempting to render a pixi stage (PIXI.autoDetectRenderer) into a canvas element, then via a separate JS remove the stage by selecting it's container in jquery and emptying out the respective canvas element.
When I try to render the same pixi stage again, I run into a bunch of WebGL related errors like this:
WebGL: INVALID_OPERATION: bindTexture: object not from this context
I assume this is because I'm merely emptying out the canvas element, but the related WebGL objects still exist somewhere in memory.
Is there an easy way to be able toggle the existence of a pixi stage?
It would be nice to mention in documentation, that Texture can be only created from BaseTexture, not from another Texture.
For example: I have own spritesheet, which loads with PIXI.Texture.fromImage. This method returns Texture and this blocks me from creating sprites directly from that object.
It can be easly avoided by getting baseTexture property from loaded image, or (like in SpriteSheetLoader.js:84) by additing listeners on loaded event and pass it higher.
Would be nice to be able to tell the movieclip to play x-number of frames, and at the completion of showing those frames, call a callback that may switch the textures, etc.
e.g. if I click on an element, switch from "idle" frames to "you touched me" frames, then at the completion of showing those frames, call the callback that switches back to the "idle" frames.
Unless I'm mistaken, I have not seen this in the api yet.
Hi, this goes for Android in general, but I need to have a rendering engine that works on all the 2.x~ 4.x Android devices.
I was just trying Run pixi run on a Samsung Galaxy S3's default browser (the most popular handset yet) and it has serious rendering bugs that it makes the game unplayable.
I can't attach the JSON file to test with, but this sprite sheet renders correctly in Firefox/IE/Chrome but flickers in Safari on windows. Also, to make it run I had to comment out the line:
throw new Error("Texture Error: frame does not fit inside the base Texture dimensions " + this);
on 3624 of pixe.dev.js because it kept throwing an error there, even though the sprite sheet seems valid. If I remove that validation check the frames appear to be animating correctly.
The validation error happens across all browsers.
Let me know if you'd like me to email you the files I am working with.
Setting the width and height of an image sprite as a background using
var background = PIXI.Sprite.FromImage('someurl');
then setting the width and height using
background.width = 800;
background.height = 600;
it sometimes works correctly ... and sometimes it doesn't work at all ... do I have to use the assets loader class and import image data with json ? like the image url , the width and height , position ?
Or there is some turnaround that could be done ? :)
Looks like we get mouseup, mousedown, mouseover, and mouseout events called on Sprites (per the docs). I want to allow dragging in grapefruit, is there anyway we can also get mousemove events so I can drag stuff around?
This would be really useful if possible - but possibly a fair bit of refactoring.
At the moment, when loading pixi via a module loader (like requireJS), with a shim opening up the global to scripts, it works ok, but one of the dependencies (namely gl-matrix-min) is a 'proper' self contained AMD module. This confuses a little, as that is what gets returned if you follow the standard loading pattern as the code currently stands.
I'm currently doing a project assignment for a game using pixi.js and I viewed much of your examples attached with the project's folder ( pixi.js ) and found a problem when viewing it in chrome nor comodo dragon and it's working fine with firefox and IE ....
it displays the following error :
107
Uncaught Error: SecurityError: DOM Exception 18 pixi.js:1887
299
Uncaught Error: SecurityError: DOM Exception 18 pixi.js:1887
I tried to surround the line with a try and catch .. it showed some kind of a rectangle for the image's sprite but didn't show it. I guess maybe there is a cross browser problem or maybe I need some guidance on how to use it
Thanks guys and good job 👍 :)
p.s when I finish the game ... looking forward to send you a link to play it ;)
This means that if I use requirejs on a page that I include pixi.js in, then I get mat3 undefined errors.
ReferenceError: mat3 is not defined
I'm not sure what the best way to tackle this is. The hack-around I have used in the past is to wrap the included code in a closure in which I shadow off the exporters so it thinks to use global despite the environment:
(function(){varrequire=define=exports=module=undefined;/** Include Brandon's code here **/})();
So that works, but obviously isn't ideal. I am currently having to do this when I include your library.
when a new sprite is added to stage,pixi look for the closet previous sprite and next sprite and then insert after or insert before one of the both.Is it to let the Web GLBatch draw order and display tree order consistent?but I think it doesn't gurantee that all the sprites with the same texture and blend mode were group into the same WebGLBatch.so may it affect efficiency?
var max = soul.fileList.length;
trace("the max looks like " + max );
for ( var i = 0; i < max; i++ )
{
var texture = PIXI.Texture.fromImage( soul.fileList[i] );
if ( texture != null ) textureList.push( texture );
}
soul.display = new PIXI.MovieClip( textureList );
soul.display.setInteractive(true);
It's kind of weird that the data presented in "mouseup" callback are the same with those presented in "mousedown" callback, which means I can't get any new information about the cursor when "mouseup" callback is called.
When there's a collision I want to remove a sprite from the game. How do I do this? Intuitively, from the docs, I tried stage.removeChild(mySprite), but got this error:
Uncaught Error: [object Object] The supplied DisplayObject must be a child of the caller [object Object] pixi.js:7
PIXI.DisplayObjectContainer.removeChild pixi.js:7
mySprite is in fact a child of stage:
var stage = new PIXI.Stage(0x66FF99);
var mySprite = new PIXI.Sprite(PIXI.Texture.fromImage("stone.png"));
mySprite.anchor.x = 0.5;
mySprite.anchor.y = 0.5;
mySprite.position.x = 1000;
mySprite.position.y = 300;
stage.addChild(mySprite);
The sprite does disappear and everything else freezes when I get this error.
I created a CanvasRenderer and tried to save a big rendered map to texture to optimize it a bit since it was a static map. However it only seemed to work when I was using a WebGLRenderer.
I am creating tilemaps in the way we discussed before (in #48), using a single sprite for each "tile" all which share the tileset texture as their base texture. However, there is a small issue with scaling.
Without scaling it all looks great:
Once I make the scale 2, it scales up using Linear scaling due to lines 241/242 in the WebGLRenderer. Unfortunately linear scaling does not guarantee that textures will stay the same size so we get:
If I patch those lines to use gl.NEAREST for the filter we get:
So the ideal situation here is if I could set the filter type for a texture either in the ctor or with some property so that it would use the proper filtering when rendered.
Event outside the case where I need tiles to fit together, scaling any kind of "pixel-art" game will require gl.NEAREST scaling to look half decent.
When I have more than one pixi stage on a page that uses textured sprites, the first stage renders the sprite just fine, however the second throws the error:
WebGL: INVALID_OPERATION: bindTexture: object not from this context
I have one more proposal for Sprite , I spot it when create sprites that dont have texture ready .
Sprite ctor :
this.width = 0;
this.height = 0;
// this will inform that Sprite dont have texture and size set
function setTexture :
this.width = this.width || texture.frame.width;
this.height = this.height || texture.frame.height;
// if width or height was set by user before texture was set , it will stay . If width/height is default 0 , it will set texture size .