# How can I use p5.js sketch as loader for website?

**URL:** https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890
**Category:** Coding Questions
**Created:** [May 5, 2021, 2:41pm UTC](https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890 "2021-05-05T14:41:22Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![cn13](https://avatars.discourse-cdn.com/v4/letter/c/e9c0ed/32.png) [@cn13](https://discourse.processing.org/u/cn13)
#### Post date: [May 5, 2021, 2:41pm UTC](https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890/1 "2021-05-05T14:41:22Z")

</div>

hi there,

i have created a p5.js sketch and tried to implement it on my website as a loader… the problem is, that i have to load the p5.js sketch in the body part of my HTML because the sketch would still be visible after loading the page, if i put it in the head…

```auto
<body onload="myLoader()" style="margin:0;">

<div id="loader">
  <script src="sketch-loader.js"></script>
</div>

<div style="display:none;" id="myDiv" class="animate-bottom">
  //content of my website
</div>

<script>
var myVar;

function myLoader() {
  myVar = setTimeout(showPage, 3000);
}

function showPage() {
  document.getElementById("loader").style.display = "none";
  document.getElementById("myDiv").style.display = "block";
}
</script>

</body>

```

thank you for helping!

---

<div class="post-metadata">

### Author: ![micuat](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micuat/32/19407_2.png) [@micuat](https://discourse.processing.org/u/micuat)
#### Post date: [May 5, 2021, 7:49pm UTC](https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890/2 "2021-05-05T19:49:06Z")

</div>

Hi! Welcome to the forum!

It’s hard to guess what exactly want to do from the snippet - but I think what you need is `parent` to attach p5 sketch canvas to a specific div

[https://p5js.org/reference/#/p5.Element/parent](https://p5js.org/reference/#/p5.Element/parent)

because

```auto
<div id="loader">
  <script src="sketch-loader.js"></script>
</div>

```

actually doesn’t mean that the sketch goes into `#loader`.

---

<div class="post-metadata">

### Author: ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)
#### Post date: [May 5, 2021, 8:01pm UTC](https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890/3 "2021-05-05T20:01:38Z")

</div>

@micuat is spot on that you are not actually attaching the p5js canvas to the “loader” div. And there are several ways to fix that, one is using parent property, another is using [instance mode](https://github.com/processing/p5.js/wiki/p5.js-overview#instantiation--namespace) via the [p5 constructor](https://p5js.org/reference/#/p5/p5), which takes an argument specifying the parent element for the canvas.

However, one other thing that bears noting, just hiding the div is potentially still going to leave the p5js sketch running and consuming resources. You would do well to also call [remove()](https://p5js.org/reference/#/p5/remove) to completely stop the sketch.

I’ve made a simple example [on jsfiddle](https://jsfiddle.net/sflanker/kmq2o60s/1/).

```auto
<!DOCTYPE html>
<html lang="en">

  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.min.js"></script>
    <style>
      #loading_screen {
        position: fixed;
        left: 0;
        right: 0;
        top: 0;
        bottom: 0;
      }
      
      body.loaded #loading_screen {
        display: none;
      }

    </style>
    <!-- if you include other heafty javascript files here, use the defer attribute -->
  </head>

  <body>
    <div id="root">
      <!-- this is where your SPA content will show up -->
      NOTHING TO SEE HERE YET
    </div>
    <div id="loading_screen">
      <!-- this is where the p5js loading screen canvas will be -->
    </div>
    <script>
      function LoadingScreen(p) {
        p.setup = function() {
          p.createCanvas(p.windowWidth, p.windowHeight);
        }

        p.draw = function() {
          p.background(200, 200, 200, 20);
          p.circle(
            p.width / 2 + p.cos(p.millis() / 400) * 100,
            p.height / 2 + p.sin(p.millis() / 400) * 100,
            100
          );
        }
      }

      let sketch = new p5(LoadingScreen, 'loading_screen');
      document.addEventListener('appLoaded', () => {
        // Make the loading screen go away
        sketch.remove(); // This removes the canvas
        document.body.classList.add('loaded'); // This stops displaying the div
      });

    </script>

    <script>
      <!-- Imagine this is some script that runs once your app is done bootstrapping 
      -->
    <!-- Where exactly this code goes depends on your SPA framework -->

    setTimeout(
      () => {
        let root = document.getElementById('root');
        root.innerHTML = 'Hooray our app has loaded!';

        document.dispatchEvent(new CustomEvent('appLoaded'));
      },
      5000 // simulate the app taking 5 seconds to load
    );
    </script>
  </body>

</html>

```

---

<div class="post-metadata">

### Author: ![cn13](https://avatars.discourse-cdn.com/v4/letter/c/e9c0ed/32.png) [@cn13](https://discourse.processing.org/u/cn13)
#### Post date: [May 6, 2021, 5:54pm UTC](https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890/4 "2021-05-06T17:54:57Z")

</div>

Hi @KumuPaul  
Yeah that’s exactly what i tried to do! Thank you so much for your help!  
I have only one Question: Where should I put the content of my Website?

Because if I put it in the root div its only visible before the loader appears

```auto
<div id="root">
      <!-- this is where your SPA content will show up -->
      NOTHING TO SEE HERE YET
    </div>

```

Because everything I put here overlaps with the root div:

```auto
root.innerHTML = 'Hooray our app has loaded!';

```

and I have too much content to put everything in the innerHTML function…

---

<div class="post-metadata">

### Author: ![micuat](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micuat/32/19407_2.png) [@micuat](https://discourse.processing.org/u/micuat)
#### Post date: [May 6, 2021, 6:25pm UTC](https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890/5 "2021-05-06T18:25:40Z")

</div>

can’t you add contents to a div inside `#root`, make it `display: none` by default and take the `display` property out when the sketch is gone?

---

<div class="post-metadata">

### Author: ![cn13](https://avatars.discourse-cdn.com/v4/letter/c/e9c0ed/32.png) [@cn13](https://discourse.processing.org/u/cn13)
#### Post date: [May 6, 2021, 6:34pm UTC](https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890/6 "2021-05-06T18:34:30Z")

</div>

Oh yes that should work… Thank you!

---

<div class="post-metadata">

### Author: ![cn13](https://avatars.discourse-cdn.com/v4/letter/c/e9c0ed/32.png) [@cn13](https://discourse.processing.org/u/cn13)
#### Post date: [May 6, 2021, 8:19pm UTC](https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890/7 "2021-05-06T20:19:57Z")

</div>

I tried to implement the code of @KumuPaul in my website but i have still 3 issues with it…

1. I tried to implement my p5.js sketch into your script tag, but made a some bugs in doing so… where should i put the p. if i have a variable in front of it?

```auto
myText.p.splice(space, 0, '');

```

1. I have a second p5.js sketch, which should display when the site is loaded… i tried to put it in the head section with the defer attribute, somehow it doesn’t work everytime i reload…

2. I have an Accordion, which broke when I tried to implement your code… somehow it works if I resize the screen…

If you could help me again with these issues I would be soo thankful!

Maybe it helps if you could have a look on [my project](https://test.cianjochem.ch) and the [loader sketch](https://editor.p5js.org/cn13/sketches/vlFFWe3eg):

---

<div class="post-metadata">

### Author: ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)
#### Post date: [May 6, 2021, 8:57pm UTC](https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890/8 "2021-05-06T20:57:27Z")

</div>

When using p5js in instance mode you only need to use the `p` variable when accessing global/static p5.js functions and constants (like `createCanvas()` or `text()` or `width`). It looks like you’re conflating the p5.js static splice function and the built in javascript instance function on arrays. It also looks like you may be trying to use splice with a string which won’t work since it only works on arrays. And the p5.js splice function is deprecated in any case.

Is your project hosted on Glitch? I saw a glitch cdn URL in there which is why I ask. If you can share a link to your project I might be able to help you out (I’m [@KumuPaul](https://glitch.com/@KumuPaul) on glitch if it’s private).

---

<div class="post-metadata">

### Author: ![cn13](https://avatars.discourse-cdn.com/v4/letter/c/e9c0ed/32.png) [@cn13](https://discourse.processing.org/u/cn13)
#### Post date: [May 6, 2021, 10:24pm UTC](https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890/9 "2021-05-06T22:24:04Z")

</div>

Yeah i tried to uploaded it on github, but i’m not sure how it will work because its made with Kirby CMS…  
but sent you an invitation if you want to have a look 🙂

---

<div class="post-metadata">

### Author: ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)
#### Post date: [May 7, 2021, 4:00am UTC](https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890/10 "2021-05-07T04:00:13Z")

</div>

Ugh, I hate CMSs, they’re all terrible. Here you go:

> **[Glitch](https://glitch.com/edit/#!/cianjochem-porfolio-debug?path=index.html:57:51)**
>
> Combining automated deployment, instant hosting & collaborative editing, Glitch gets you straight to coding so you can build full-stack web apps, fast

Things I had to change:

1. Moved the loading screen div and the loading screen script up to the top of the file.
  - this is important because the browser loads page content in linear order, and you want that loading screen to show up ASAP.

2. Inlined the loading screen sketch into the loading screen script block:

```auto
    <!-- Put this at the top of the body so it is loaded and executed first thing -->
    <div id="loading_screen">
      <!-- this is where the p5js loading screen canvas will be -->
    </div>
    <script>
      console.log(`${new Date()} starting loading screen...`);

      function loadingScreen(p) {
        let font;
        let space;
        let amount = 40;
        let state = [amount];
        let myText = ["C", "I", "A", "N", "", "J", "O", "C", "H", "E", "M"];

        p.preload = function() {
          console.log(`${new Date()} Preloading font`);
          font = p.loadFont(
            "https://cdn.glitch.com/ba7ae563-6481-4d92-8b25-48f6cd661df0%2FEverettMono-Regular-web.ttf?v=1617819670199"
          );
        };

        p.setup = function() {
          p.createCanvas(p.windowWidth, p.windowHeight);
          p.background(247);
          p.frameRate(10);
          console.log(`${new Date()} Loading screen setup complete`);
        };

        p.draw = function() {
          p.background(247, 20);
          p.textFont(font);
          p.fill(0);
          p.textSize(16);

          myText = ["C", "I", "A", "N", "", "J", "O", "C", "H", "E", "M"];

          for (let i = 0; i < 29; i++) {
            space = p.floor(p.random(1, 11 + i));
            myText.splice(space, 0, "");
          }

          let tileW = (p.width - 80) / amount;

          for (let x = 0; x < amount; x++) {
            p.push();
            p.translate(40 + x * tileW, 60 + (p.frameCount % 30) * 30);
            p.text(myText[x], 0, 0);
            p.pop();
          }
        };
      }

      let sketch = new p5(loadingScreen, "loading_screen");

      document.addEventListener("appLoaded", () => {
        sketch.remove(); // This removes the loading screen canvas
      });
    </script>

```

1. Converted the header sketch to also be an instance mode sketch and inlined it into the script block at the end of the file:

```javascript
console.log(`${new Date()} creating loading timeout.`);
setTimeout(
  () => {
    console.log(`${new Date()} loading complete.`);
    // Signal the loading sketch to stop, and the header sketch to start
    document.dispatchEvent(new CustomEvent("appLoaded"));
    // Stop displaying the loading div, start displaying the content
    document.body.classList.add("loaded");
  },
  7000 // simulate the app taking 7 seconds to load
);

function headerSketch(p) {
  let font;
  let space;
  let myCanvas;
  let amount = 40;
  let myText = ["C", "I", "A", "N", "", "J", "O", "C", "H", "E", "M"];

  p.preload = function() {
    font = p.loadFont(
      "https://cdn.glitch.com/ba7ae563-6481-4d92-8b25-48f6cd661df0%2FEverettMono-Regular-web.ttf?v=1617819670199"
    );
  };

  p.setup = function() {
    myCanvas = p.createCanvas(p.windowWidth, p.windowHeight);
    myCanvas.position(40, 0);
    myCanvas.style("z-index", "-999");

    for (let i = 0; i < 29; i++) {
      if (p.mouseX < p.width / 2) {
        space = p.floor(p.random(1, 11 + i));
      } else if (p.mouseX > p.width / 2) {
        space = p.floor(p.random(1, 11 + i));
      }
      myText.splice(space, 0, "");
    }
  };

  p.draw = function() {
    p.background(247, 50);
    p.textFont(font);
    p.fill(0);
    p.textSize(16);

    let tileW = (p.width - 80) / amount;
    for (let x = 0; x < amount; x++) {
      p.push();
      p.translate(x * tileW, 60);
      p.text(myText[x], 0, 0);
      p.pop();
    }
  };

  p.windowResized = function() {
    p.resizeCanvas(p.windowWidth, p.windowHeight);
  };
}

let header = new p5(headerSketch, "header");

```

For some reason I haven’t been able to determine, p5.js sometimes takes its sweet time getting the loading screen up and running. I’m not sure what can be done about that.

---

<div class="post-metadata">

### Author: ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)
#### Post date: [May 7, 2021, 5:46am UTC](https://discourse.processing.org/t/how-can-i-use-p5-js-sketch-as-loader-for-website/29890/11 "2021-05-07T05:46:35Z")

</div>

Oh, I forgot, I made some tweaks to the CSS as well.

```css
#loading_screen {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}

body.loaded #loading_screen {
  display: none;
}

/* Use the loaded CSS class for everything instead of manipulating styles.
   This simplifies the code and makes it easier to customize the display with
   alternate stylesheets (i.e. for printing) */
body:not(.loaded) #content {
  /* Use visibility instead of display because I think the browser does more
     of the layout work if with visibility: hidden. With display: none it might 
     just ignore the content completely. Not 100% sure about this though. */
  visibility: hidden;
}

body.loaded #content {
  visibility: visible;
}

```
