We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I have 3 programs that I wanted to layout in a 800x800 square. I don't know CSS or JS really I'm just a beginner so I thought I'd bring all the functions into this one single file. This posed some challenges for me. I thought the easiest thing to do was create many canvases so I used the following in the setup()
:
createCanvas(800, 800);
pg = createGraphics(500, 500);
ab = createGraphics(800, 300);
So the second and third canvases overlay the main one as it spans accross the whole composite, like so(the main effect - a particle system - is drawn to the main canvas on the top right, even though the canvas is the full 800x800, and this allows for its particles to trickle down to ab, which I happen to like):
| pg | C |
| 500 | | h:500
|-------------------|
| ab | h:300
800
Then I realized I needed ab to be drawn at one frame per 5 sec. so I tried ab.frameRate(1/5);
but didn't seem to work. So I settled for this in in the function which draws to ab:
if (frameCount % 150 == 0) {
ab.background(0);
ab.text(phrase, width/2, 25, 700, 400);
}
...
image(ab, 0, 500, width, height);
Is that proper and could have I used frameRate? What's the best practice?
About layout, I found this simple CSS block I added to a file to center the canvas on the html and have a black background:
canvas {
padding-left: 0;
padding-right: 0;
margin-left: auto;
margin-right: auto;
display: block;
width: 1000px;
}
body { background-color: black; }
So I'm trying to learn something from this. Maybe using many canvases wasn't such a good idea here, using one for all the functions is better; but here I had a function which required a different framerate so I don't see how I could have done both. I'm looking for some advice on what to do next time I want to do such a layout? Which of html, JS, CSS was the solution to layout those individual programs instead of merging them in the first place?
I'll add the whole script because ascii drawing on the forum works not so good to illustrate layout:
// //////////////////////////////////////////////////////////////////////////////// //
// "Montage pour..." - Un programme combinant 3 programmes en p5.js (p5js.org) //
// //////////////////////////////////////////////////////////////////////////////// //
// 1- le motif bleu //
// une "port" vers p5.js du sketch Processing "yabe1324065"; attribution: //
// "yabe1324065" by Tetsuro Yabe, licensed under Creative Commons //
// Attribution-Share Alike 3.0 and GNU GPL license. //
// Work: http://openprocessing.org/visuals/?visualID= 166810 //
// License: //
// http://creativecommons.org/licenses/by-sa/3.0/ //
// http://creativecommons.org/licenses/GPL/2.0/ //
//////////////////////////////////////////////////////////////////////////////////////
// 2- le système de particules triangulaires sur la photo //
// "Particle System" dans The Nature of Code, de Daniel Shiffman, //
// adapté en p5.js ici: http://p5js.org/learn/examples/Simulate_Particle_System.php //
// //////////////////////////////////////////////////////////////////////////////// //
// 3- le texte aléatoire construit à partir de listes de mots: //
// "Cadavre exquis" de PaHern_pAni( - 2014 //
// License: CC-by-SA/GNU GPLv2 //
// ///////////////////////////////////////////////////////////////////////////////////
var eColor = [];
// Matrice pour les "déplacements" dans le motif bleu
var speed = [
[2.0, 1.8, 1.6, 1.4, 1.2, 1.0],
[2.2, 2.0, 1.8, 1.6, 1.4, 1.2],
[2.4, 2.2, 2.0, 1.8, 1.6, 1.4]
];
var system;
var img;
// ///////////////////////////////////////////////////////////////////////////////////////////////////////
// 3 canvas; 1-motif bleu, 2- pg; fontaine sur image, 3- ab; texte
function setup() {
createCanvas(800, 800);
pg = createGraphics(500, 500);
ab = createGraphics(800, 300);
background(0, 50);
img = loadImage("photo.jpg");
system = new ParticleSystem(createVector(620, height/4));
pg.smooth();
pg.noStroke();
pg.fill(0);
for(var y = 0;y < 3; y++){
eColor[y] = [];
for(var x = 0;x < 6; x++){
eColor[y][x] = 0;
}
}
}
// ///////////////////////////////////////////////////////////////////////////////////////////////////////
function draw() {
cadavre();
triangles();
image(img, 500, 0, 300, 500);
system.addParticle();
system.run();
}
// ///////////////////////////////////////////////////////////////////////////////////////////////////////
// Le motif de triangles bleus
function triangles() {
pg.background(255);
for(var y = 0;y < 3; y++){
for(var x = 0;x < 6; x++){
eColor[y][x] += speed[y][x];
if (eColor[y][x] > 255 || eColor[y][x] < 0) {
speed[y][x] = -speed[y][x];
}
pg.fill(0, eColor[y][x], 255, 175);
pg.triangle(0+100*x, 84+168*y, 50+100*x, 0+168*y, -50+100*x, 0+168*y);
pg.fill(0, eColor[y][x], 255, 200);
pg.triangle(50+100*x, 168+168*y, 100+100*x, 84+168*y, 0+100*x, 84+168*y);
pg.fill(0, eColor[y][x], 255, 225);
pg.triangle(50+100*x, 0+168*y, 100+100*x, 84+168*y, 0+100*x, 84+168*y);
pg.fill(0, eColor[y][x], 255, 250);
pg.triangle(0+100*x, 84+168*y, 50+100*x, 168+168*y, -50+100*x, 168+168*y);
image(pg, 0, 0);
}
}
}
// ///////////////////////////////////////////////////////////////////////////////////////////////////////
// Le cadavre exquis - une liste pour sujet/complément, une pour verbe, etc. accent aigu= \xE9, grave \xE8
function cadavre() {
var sujcompl = [
"le loup-garou",
"le cri du chauve... souris",
"le cadavre",
"le festin",
"le cerf-volant",
"l'orange",
"la fleur",
"la tombe",
"la maison hant\xE9e",
"le sushi",
"la f\xE9e",
"le vent",
"le zombie",
"la souffleuse",
"le vampire",
"le tire-bouchon",
"le sorcier",
"le capitaine",
"l'\xE9toile de ninja"
];
var verbe = [
"mange",
"mord",
"lance",
"ouvre",
"ferme",
"aime",
"explose",
"d\xE9coupe",
"embrasse",
"vole",
"lib\xE8re",
"op\xE8re",
"dig\xE8re",
"dessine",
"attaque",
"d\xE9fend",
"effraie"
];
var adverbe = [
"all\xE8grement",
"terriblement",
"vertigineusement",
"mollement",
"courageusement",
"indubitablement",
"\xE9pouvantablement",
"verbalement",
"affectueusement",
"d\xE9licieusement"
];
var adjectif = [
"invert\xE9br\xE9(e)",
"\xE9gar\xE9(e)",
"triste",
"bleu(e)",
"scintillant",
"vibrant(e)",
"dangereu(se)",
"congel\xE9(e)",
"multicolore",
"d\xE9goulinant(e)",
"sucr\xE9(e)",
"glac\xE9(e)"
];
// on utilise le nombre d'éléments dans une liste, on tire au hasard, on ramène à un nbre entier, on assigne
var a = floor(random(sujcompl.length));
var b = floor(random(adjectif.length));
var c = floor(random(verbe.length));
var d = floor(random(adverbe.length));
var e = floor(random(sujcompl.length));
// Comme on utilise la même liste pour sujet et complément, on veut pas que ce soit le même mot.
if (a == e) {
e = floor(random(sujcompl.length));
} else {
}
// On construit la phrase avec les éléments bout à bout sélectionnés au hasard
var phrase = sujcompl[a]+" "+adjectif[b]+" "+verbe[c]+" "+adverbe[d]+" "+sujcompl[e]+"...";
// Paramètres du texte, taille etc.
ab.stroke(0, 102, 153, 51);
ab.strokeWeight(3);
ab.textLeading(30);
ab.textSize(30);
ab.textAlign(CENTER);
// Texte affiche seulement si compte des images total est un multiple de 150; 30fps par defaut donc aux 5 secs.
if (frameCount % 150 == 0) {
ab.background(0);
ab.text(phrase, width/2, 25, 700, 400);
} else {
}
image(ab, 0, 500, width, height);
}
// ///////////////////////////////////////////////////////////////////////////////////////////////////////
// Particle System Components
//
// A simple Particle class (sous forme de triangles multicolores ici)
var Particle = function(position) {
this.acceleration = createVector(0, -0.02);
this.velocity = createVector(random(-0.5, 0.5), random(4));
this.position = position.get();
this.lifespan = 255;
};
Particle.prototype.run = function() {
this.update();
this.display();
};
// Method to update position
Particle.prototype.update = function(){
this.velocity.add(this.acceleration);
this.position.add(this.velocity);
this.lifespan -= 1;
};
// Method to display
Particle.prototype.display = function() {
stroke(random(255), random(255), random(255), this.lifespan);
strokeWeight(2);
fill(random(255), random(255), random(255), this.lifespan);
if (this.velocity.y > 0) {
triangle(this.position.x, this.position.y, 6+this.position.x, this.position.y, 3+this.position.x, 6+this.position.y);
} else {
triangle(3+this.position.x, this.position.y, this.position.x, 6+this.position.y, 6+this.position.x, 6+this.position.y);
}
};
// Is the particle still useful?
Particle.prototype.isDead = function(){
if (this.lifespan < 0) {
return true;
} else {
return false;
}
};
var ParticleSystem = function(position) {
this.origin = position.get();
this.particles = [];
};
ParticleSystem.prototype.addParticle = function() {
this.particles.push(new Particle(this.origin));
};
ParticleSystem.prototype.run = function() {
for (var i = this.particles.length-1; i >= 0; i--) {
var p = this.particles[i];
p.run();
if (p.isDead()) {
this.particles.splice(i, 1);
}
}
};
Answers
Still noob about p5js. Nonetheless, how about this example? ~O)
Thank you! I'm analyzing what you wrote. I notice sometimes the change occurs after 6 or 9 seconds instead of 3... was it intended on your part that I witness that? Also, I have to look up; I don't know the syntax of
if (test) updatePG(pg);
what does the part on the same line after the test do again? As you can see there are different levels of noobs lol.You're right on that! Just found out a bug in p5.js! :@)
Variable frameCount is supposed to represent how many times draw() was called back by p5.js's framework:
http://p5js.org/reference/#/p5/frameCount
But it's clearly skipping the counting at random times! And that makes
frameCount%INTERVAL == 0
fail! :(It means if test is
true
, execute that statement. The statement can be in the same line as well! =:)Opened bug issue here: https://github.com/lmccart/p5.js/issues/406
Thank you! I gather using modulo was a good idea to do this despite the issue. Thanks for the cue on
if
, I struggle with syntax variations... :)Still looking for further info on making a more intelligent layout out of "my"(I did write one of the 3 programs loll) script...
Since frameCount is buggy in p5.js right now, what about a millis() version. Which btW is much more precise:
So this works and I'll be able to use that!! I'll mark your answer and will make another post focused on layout. Thanks again for your insight!