Omri
September 21, 2022, 2:53pm
1
Hi all, I’m using the function preload
in my p5 project, because of that I have a couple of seconds of a white page at the beginning, so I want to create a loading screen.
I tried to do the following here:
p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Proces...
and instead of the this could be some sweet graphics loading lots of bits
I put a p5 sketch like that:
<div id="p5_loading" class="loadingclass"><script src="loading.js"></script></div>
now I this problem:
My code in loading.js
is like that:
size = 0;
function setup(){
createCanvas(window.innerWidth, window.innerHeight);
background(38);
}
function draw(){
background(38);
fill(187);
circle(width/2,height/2,sin(size)*50);
size+=0.05;
}
the project gets stuck with this page (all you can see is the circle gets big and small in the background) and it doesn’t move to the main project after the reload.
what to do? Is possible at all to do something like that?
and if animations are possible, can I load image to the loading screen? that’s mean I need to use preload to there as well? (smells like recursion )
thanks
josephh
September 21, 2022, 3:39pm
2
Hi @Omri ,
Well you are spicing stuff a bit!
So you want to display a loading screen that is basically a p5 sketch itself.
Basically since loadImage
can be asynchronous and accepts a callback, you can call it in setup()
and in draw()
display your loader if not loaded:
let bigImage;
let loaded = false;
function setup() {
createCanvas(400, 400);
bigImage = loadImage(
"https://images.pexels.com/photos/358457/pexels-photo-358457.jpeg",
() => loaded = true
);
}
function draw() {
if (!loaded) {
background(0);
// Your spinner here
} else {
background(220);
}
}
1 Like
I believe they’ve meant styling the element w/ CSS stuff, not another p5js sketch.
Besides only 1 global mode sketch can be active within a single web frame.
For extra global mode sketches you’ll have to place them inside separate <iframe>
:
https://developer.Mozilla.org/en-US/docs/Web/HTML/Element/iframe
I believe you can include an <img>
element as the <div>
content:
1 Like
Omri
September 21, 2022, 4:26pm
4
@josephh thanks again for the help
your solution is working for me for the sound file (with loadSound).
but I have in my sketch also shaders and video.
for the video I’m using createVideo, so this is counting as loading something? does it have a callback to use your option with?
for the shade as I can see here:
it does have a callback, but something weird is happening when I try your method: the set is started running in a loop. do you have any idea why is that? I’m doing the same as I did with the loadSound
@GoToLoop
So if I can use only CSS that’s means I cannot do animation at the loading screen?
p5js got a default loading <div>
element which we can replace w/ our own.
I dunno the full extent of what an HTML element can do, but I believe they can be styled w/ some CSS animation:
1 Like
josephh
September 21, 2022, 5:13pm
6
Yes it has a callback:
createVideo(src, [callback])
Here is a code that loads an image and a video asynchronously using promises and Promise.all
to wait for multiple asynchronous tasks to finish:
let bigImage;
let video;
let loaded = false;
let loadingError = false;
let timeValue = 0;
function promiseLoadImage(url) {
return new Promise((resolve, reject) =>
loadImage(url, resolve, reject)
)
}
function promiseCreateVideo(url) {
return new Promise((resolve, reject) => {
const video = createVideo(url, () => resolve(video));
})
}
function easeOutCubic(x) {
return 1 - Math.pow(1 - x, 3);
}
function setup() {
createCanvas(400, 400);
Promise.all([
promiseLoadImage(
"https://images.pexels.com/photos/358457/pexels-photo-358457.jpeg"
),
promiseCreateVideo("https://upload.wikimedia.org/wikipedia/commons/transcoded/6/60/Wikipedia_logo_puzzle_globe_spins_horizontally_and_vertically%2C_revealing_the_contents_of_all_of_its_puzzle_pieces_%284K_resolution%29_%28VP9%29.webm/Wikipedia_logo_puzzle_globe_spins_horizontally_and_vertically%2C_revealing_the_contents_of_all_of_its_puzzle_pieces_%284K_resolution%29_%28VP9%29.webm.120p.vp9.webm")
]).then((results) => {
[img, vid] = results;
bigImage = img;
video = vid;
video.play();
video.loop();
loaded = true
}).catch(e => loadingError = true)
}
function loader() {
push();
translate(width / 2, height / 2);
noFill();
strokeWeight(10);
stroke(50, 200, 0);
const endOffset = (period) => easeOutCubic((sin(timeValue + period) + 1) / 2)
arc(0, 0, 100, 100, timeValue + endOffset(0) * HALF_PI, timeValue + PI + endOffset(HALF_PI) * HALF_PI);
pop();
}
function draw() {
background(200);
if (loadingError) {
stroke(255, 0, 0);
strokeWeight(5);
line(width - 50, 50, 50, height - 50);
line(50, 50, width - 50, height - 50);
noLoop();
return;
}
if (!loaded) {
loader();
} else {
image(bigImage, 0, 0);
}
timeValue += 0.1;
}
2 Likes
Omri
September 21, 2022, 5:42pm
7
@josephh you’re the best!
do you have any idea about the loadShader problem?
1 Like
josephh
September 22, 2022, 7:16am
8
Again this in the reference :
Syntax:
loadShader(vertFilename, fragFilename, [callback], [errorCallback])
Have fun!
Omri
September 22, 2022, 12:13pm
9
@josephh
that’s what I tried, but look at something strange, If I run this code:
let theShader;
function preload() {
theShader = loadShader('shader.vert', 'shader.frag');
}
function setup() {
pixelDensity(1);
createCanvas(windowWidth, windowHeight, WEBGL);
noStroke();
console.log("DONE SET UP")
}
function draw() {
theShader.setUniform('u_resolution', [width, height]);
shader(theShader);
rect(0, 0, width, height);
}
everything looks good:
But, when I try to use the callback:
let theShader;
let loaded = false;
function setup() {
pixelDensity(1);
createCanvas(windowWidth, windowHeight, WEBGL);
theShader = loadShader('shader.vert', 'shader.frag',
() => loaded = true
);
noStroke();
console.log("DONE SET UP")
}
function draw() {
if (!loaded) {
background(200);
fill(20)
circle(width/2, height/2, 200);
} else {
theShader.setUniform('u_resolution', [width, height]);
shader(theShader);
rect(0, 0, width, height);
}
}
I get that:
It looks like it running the setup() function a lot of times
have you ever seen something like that? am I using the callback wrong?
I used now the simplest shader so I don’t think the problem is with the shader.vert or the shader.frag
josephh
September 22, 2022, 1:04pm
10
Yes it’s strange, maybe it’a a bug…
You should either load it in the setup()
or preload()
but not in both because it makes no sense.
Omri
September 22, 2022, 1:14pm
11
Oh, that was a mistake when I copied it here, I didn’t use preload()
the second time.
Do you know what can I do about that bug?
josephh
September 22, 2022, 3:13pm
12
This works fine for me:
let theShader;
let loaded = false;
function setup() {
pixelDensity(1);
createCanvas(windowWidth, windowHeight, WEBGL);
theShader = loadShader('shader.vert', 'shader.frag',
() => {
loaded = true
console.log("SHADER LOADED")
}
);
noStroke();
console.log("DONE SET UP")
}
function draw() {
if (!loaded) {
background(200);
fill(20)
circle(width / 2, height / 2, 200);
} else {
theShader.setUniform('u_resolution', [width, height]);
shader(theShader);
rect(0, 0, width, height);
}
}
with those shaders: p5.js shaders
Omri
September 22, 2022, 3:18pm
13
Thanks, I just tried your code and it is the same:
here is the code in the p5 web editor:
A web editor for p5.js, a JavaScript library with the goal of making coding accessible to artists, designers, educators, and beginners.
in your computer it’s working fine?
josephh
September 22, 2022, 3:21pm
14
Ok this is really strange, thanks for sharing the editor link. Did you try locally on your own computer rather than on the online editor?
Omri
September 22, 2022, 3:35pm
15
yep, the same problem.
Do you maybe know where is the code of loadShader() at the p5js code?
maybe I’ll look up if I can notice what causing the bug there
josephh
September 22, 2022, 3:38pm
16
You forgot to link the GitHub issue there
opened 01:27PM - 22 Sep 22 UTC
Bug
Area:WebGL
### Most appropriate sub-area of p5.js?
- [ ] Accessibility
- [ ] Color
- [ ] C… ore/Environment/Rendering
- [ ] Data
- [ ] DOM
- [ ] Events
- [ ] Image
- [ ] IO
- [ ] Math
- [ ] Typography
- [ ] Utilities
- [X] WebGL
- [ ] Build Process
- [ ] Unit Testing
- [ ] Internalization
- [ ] Friendly Errors
- [ ] Other (specify if possible)
### p5.js version
v1.4.1
### Web browser and version
105.0.5195.127
### Operating System
Windows
### Steps to reproduce this
### Steps:
1. load the shader on the setup and use a callback to know when it's done
2. console log a message on the setup()
3. run the sketch and see its not stop running the setup()
### Snippet:
```js
let theShader;
let loaded = false;
function setup() {
pixelDensity(1);
createCanvas(windowWidth, windowHeight, WEBGL);
theShader = loadShader('shader.vert', 'shader.frag',
() => loaded = true
);
noStroke();
console.log("DONE SET UP")
}
function draw() {
if (!loaded) {
background(20);
fill(200)
circle(width/2, height/2, 200);
} else {
theShader.setUniform('u_resolution', [width, height]);
shader(theShader);
rect(0, 0, width, height);
}
}
```
1 Like
Omri
September 22, 2022, 3:44pm
17
haha ya, I wanted to know if it’s really a bug on p5 or it’s just me
looks like it’s a bug
if you have any idea how to fix it pls let me know.
thanks for all the help!