pixijs: Need Documentation on JSON format - Online examples don't work

I am trying to follow along with the guide provided here:

https://pixijs.github.io/examples/#/demos/animatedsprite-demo.js

To get an example up of a simple animated sprite. The issue that I am having is that I am following along almost exactly and I am getting an error - if the example online is not working it might need to be updated.

The example has:

var app = new PIXI.Application();
document.body.appendChild(app.view);

app.stop();

PIXI.loader
    .add('spritesheet', 'required/assets/mc.json')
    .load(onAssetsLoaded);

function onAssetsLoaded() {

    // create an array to store the textures
    var explosionTextures = [],
        i;

    for (i = 0; i < 26; i++) {
         var texture = PIXI.Texture.fromFrame('Explosion_Sequence_A ' + (i+1) + '.png');
         explosionTextures.push(texture);
    }

Where I have:

  componentDidMount(){
    this.renderer = PIXI.autoDetectRenderer(1366, 768);
    this.refs.gameCanvas.appendChild(this.renderer.view);
    this.stage = new PIXI.Container();
    this.stage.width = 400;
    this.stage.height = 400;

    console.log(littlemarioforwardwalkjson)

    PIXI.loader
        .add(littlemarioforwardwalkpng, littlemarioforwardwalkjson)
        .load(()=>this.spriteLoaded());

    // console.log(PIXI.utils.TextureCache);

  }

  spriteLoaded(){
    console.log('yolo');
    var frames = [];
    var index = 0;
    console.log('hello there sailor');
    console.log(PIXI.utils.TextureCache)
    for (var i = 0; i < 3; i++) {
          index = i+46;
          var texture = PIXI.Texture.fromFrame("mario_characters1_"+index+".png");
          marioTextures.push(texture);
     }
  }

The error I am getting is:

Error: the frameId “mario_characters1_46.png” does not exist in the texture cache

This is frustrating as my texturepacker json file is displaying correctly:

{"frames": {

"mario_characters1_46.png":
{
	"frame": {"x":0,"y":0,"w":12,"h":15},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":12,"h":15},
	"sourceSize": {"w":12,"h":15},
	"pivot": {"x":0.5,"y":0.5}
},
"mario_characters1_47.png":
{
	"frame": {"x":12,"y":0,"w":11,"h":16},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":11,"h":16},
	"sourceSize": {"w":11,"h":16},
	"pivot": {"x":0.5,"y":0.5}
},
"mario_characters1_48.png":
{
	"frame": {"x":23,"y":0,"w":15,"h":16},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":15,"h":16},
	"sourceSize": {"w":15,"h":16},
	"pivot": {"x":0.5,"y":0.5}
}},
"meta": {
	"app": "http://www.codeandweb.com/texturepacker",
	"version": "1.0",
	"image": "littlemarioforwardwalk.png",
	"format": "RGBA8888",
	"size": {"w":38,"h":16},
	"scale": "1",
	"smartupdate": "$TexturePacker:SmartUpdate:ae9c1a55b9f5884f4a4c0182ea720ca9:80c341baf7877296bb8143f4c51a5998:383ea93646790c53db2201f0624e779e$"
}
}

If I console.log(PIXI.utils.TextureCache) I get:

{data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAQCAYAAAB6Hg0eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABUUlEQVRIx6VVPZqFIAxM/DwE1+B1WL5j0NrucWxtPcYr106uwS2yxQobMWB0aVSciTP5QYRikTVU7mGI+BT3lIdXJCmIFqcRVeP1fHN9xXzvrP/dCws46wG/FryLK9cdXpduvkegBE7Xg9vJE02etLhy/y6vE52F5eCMP2txkrg7POSOJDc1UVe4YT72rzZ+4qGU0mpjsj7Q4p7GF13lrGwG1leEYQakyVMiZvf7+1qWWnH5MEi8QwY0ZSsxrY+k7NQ4tUnNzZ8CcIKmRBk/vsFtBtxmxFI5689ZGd85RjbHDJxKc3Xw1coiYfOE7YZaByyPP8yAfesDYllZXznrAez+Yv60h+Xi1CdriJe1KzMg/U74M4aIJxNM1NNfUbn6v4aNhylaoTExISKBIdg+pwaGcJ7IFeKhIlx8TbRqvCVxUqYlPMfVjhO1MM3SiP+PuB9QuQ5f9MhyUAAAAABJRU5ErkJggg==: Texture}

So it would seem that the error is saying that the Texture Cache is only seeing one image blob - however, calling Texture.fromFrame is how the example on the website says to get it to work, and I think I am reproducing the code very closely.

I do not normally post errors in github repos but there seems to be a problem either with the documentation or something is broken - the example as it is can’t be reproduced in a “hello world” style animation.

Please advise.

NOTE: I have also made a stackoverflow question here: https://stackoverflow.com/questions/45654490/cant-get-a-sprite-animation-run-in-pixijs-on-react

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 24 (5 by maintainers)

Most upvoted comments

OK, so here is how your configuration is loading the json/png resources for Blog 2. It is actually inlining the image as a data-uri, and the json file is being loaded from disk, parsed, and inserted into your source as an object.

This is because your config says to load images as base64-encoded data-uris (via the url-loader):

const assets = () => () => ({
  module: {
    rules: [
      { test: /\.(png|mov|m4v|jpe?g|svg|pdf|woff2?|gif|ttf|eot)$/, loader: 'url-loader?limit=8000' },
    ],
  },
})

And json is loaded by default as the object in v2 of webpack:

When no loader has been configured for a JSON file, webpack will automatically try to load the JSON file with the json-loader.

Ok. Now that we know that, we know that you don’t need to use the loader to load your resources. They are being inlined by webpack for you.

Because of that, instead of loading these assets lets just use them!

// imports that will be resolved by webpack according to the config
import * as PIXI from 'pixi.js';
import littlemarioforwardwalkpng from '../../../../../public/mario_characters/littlemarioforwardwalk.png';
import littlemarioforwardwalkjson from '../../../../../public/mario_characters/littlemarioforwardwalk.json';

// boilerplate setup stuffs
var renderer = PIXI.autoDetectRenderer();
var stage = new PIXI.Container();

// create a base texture from the data-uri that webpack gives you
var baseTexture = PIXI.BaseTexture.fromImage(littlemarioforwardwalkpng);

// use the JS Object that webpack parsed from the json file to create a spritesheet
var spritesheet = new PIXI.Spritesheet(baseTexture, littlemarioforwardwalkjson);

// parse the object data and the base texture to create textures for each frame
spritesheet.parse(() => {
    // `spritesheet.textures` now has a texture for each frame, but in an object keyed
    // by the name of the frame. This transforms that object into an array of frames so
    // we can pass it directly into an animated sprite
    var textures = Object.keys(spritesheet.textures).map((t) => spritesheet.textures[t]);

    // create the animated sprite
    var animatedSprite = new PIXI.extras.AnimatedSprite(textures);

    // slow down the anim speed a bit, and play the animation
    animatedSprite.animationSpeed = 0.25;
    animatedSprite.play();

    // add it to the stage and render!
    stage.addChild(animatedSprite);
    animate();
});

function animate() {
  requestAnimationFrame(animate);
  renderer.render(stage);
}

Note that the spritesheet parsing I am doing here is very similar to what the loader’s middleware for handling spritesheets does: https://github.com/pixijs/pixi.js/blob/574174abbb432e16f98f7ce31708412aaed95f95/src/loaders/spritesheetParser.js#L35-L46

After these changes it animates as expected. Hopefully this helps explain what is going on in your webpack config, and how you can integrate with PixiJS.

I’ve created a Pull Request to your repository that contains the changes I explain above, so you can see it working for yourself.

Thank you it now works.

Note - I’ve found that this is a deal breaker for me. Examples should work and here they do not. I am going to be switching to a different animation library.

NOTE: I’ve gone back and looked at the example again. Take a look how the PIXI.loader is defined:

PIXI.loader
    .add('spritesheet', 'required/assets/mc.json')
    .load(onAssetsLoaded);

It mentions ‘spritesheet’ but provides no path to where it is so I can’t test what format the image is in, or if it is a base64 blob like in my example. In fact, I can’t find it anywhere in the examples repository when searching (I’ve searched and come up empty, not searched and had an overwhelming list). This means that the example is not clear enough to debug the above problem without further input.