[Phaser 3] How to scale SVG atlas in the preload

Hi all,
Phaser allows to scale an svg image in the preload, simply by using the load.svg() function. However, to scale an svg atlas (image + json), we need some extra work.

We need to do three things:

  1. Load and scale the image of the atlas in the preload.
  2. Load and scale the json file of the atlas.
  3. Create the frames in the texture generated in step 1, from the json.
    Phaser has two functions that do not explicitly appear in the documentation in the name space “Phaser.Textures.Parsers”: JSONArray() and JSONHash(). These functions allow us to generate frames in a texture from the json of our atlas.

A possible implementation would be:

// In the scene
loadAtlasSVG(key, svgURL, jsonURL, scale){
      scale = scale || 1;
      // Step 1
      this.load.svg(key, svgURL, {scale: scale});

      // Step 2
      this.load.json(key, jsonURL);

      this.load.on('complete', () => {
          const jsonData = this.cache.json.get(key);
          const frameKeys = Object.keys(jsonData.frames);

          frameKeys.forEach( frameKey => {
            const frame = jsonData.frames[frameKey].frame;
            for(const prop in frame){
              frame[prop] = frame[prop] * scale;
            }
          });
          
          // Step 3
          // For JSON Array format you must use JSONArray function
          Phaser.Textures.Parsers.JSONHash(this.textures.get(key), 0, jsonData);
      });
  }

The above function should be used in the scene preload.
Here a working example: https://codepen.io/jjcapellan/pen/vYXgraz

Hope you like it.

P.S.: This is the first way I’ve found to do it, but maybe there are other ways.

3 Likes

how will it work if used in tiles? for each tile will the full map be used, only with the desired fragment visible? or is the desired fragment cut out from the general atlas?

it’s a performance issue. Hope I put it right.