javascriptp5.js

How to customize p5.js default loading animation in preload()?


In p5.js, when you load images/sounds using the preload function, a default loading screen is shown. It looks like this:

image depicting p5.js's default loading screen

This is fine, but in my game, this text blends in with the black background of my game, and I feel as though the player might think the game is broken if the game takes too long to load, since they are seeing a pure black screen. I want to be able to replace this loading screen with my own, so it is actually indicated to the player that the game is loading.

I tried looking through the p5.js documentation, but couldn't find anything. Any help would be greatly appreciated. Please note that I'm new to JavaScript.


Solution

  • See the docs:

    By default the text "loading..." will be displayed. To make your own loading page, include an HTML element with id "p5_loading" in your page. More information here.

    Go to the "here" link and see:

    Loading Screen

    As mentioned above, if your sketch has large media dependencies such as images, audio or videos, these should be loaded into your sketch using the preload() function. Since loading large files can take some time, you might want to display a loading screen to your users. This will convey that your sketch is indeed running — it just has a lot of cool things to load first. To add a loading screen to your p5.js sketch, all you need to do is include an HTML element on your page with the id p5_loading. It would look something like the following:

    <div id="p5_loading" class="loadingclass">
      this could be some sweet graphics loading lots of bits.
    </div>
    

    P5.js looks through your HTML to see if you have included an element with the id p5_loading. P5.js will use this element and its content as the loading screen for your sketch. Since the loading element is included in your HTML, you can add any additional classes and/or style the element anyway you see fit.

    Example:

    let img;
    
    function preload() {
      img = loadImage(`https://picsum.photos/1000/1000?cache=${random()}`);
    }
    
    function setup() {
      createCanvas(1000, 1000);
      noLoop();
    }
    
    function draw() {
      image(img, 0, 0);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.js"></script>
    <h1 id="p5_loading">
      Custom loading element
    </h1>

    If that doesn't work for your use case, you can always bypass P5 and add some arbitrary vanilla DOM element that you remove in setup() (this could even be another p5 app using instance mode), or do your loading from setup() per this tip from the docs link:

    If asynchronous loading is preferred, the load methods can instead be called in setup() or anywhere else with the use of a callback parameter.

    An example of this is on discourse. Here's a modified version of that:

    let img;
    let loaded = false;
    
    function setup() {
      createCanvas(1000, 1000);
    
      img = loadImage(
        `https://picsum.photos/1000/1000?cache=${random()}`,
        () => loaded = true
      );
    }
    
    function draw() {
      clear();
    
      if (loaded) {
        image(img, 0, 0);
      }
      else {
        background("red");
      }
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.js"></script>

    If you have multiple assets to load, you could use a counter rather than a boolean to determine when they're all loaded.

    Instead of using an if, you can also assign a different function to window.draw to run when the assets load, which is a bit simpler to maintain.