While Loop Not Working In Function For P5.js - javascript

I am experienced in python but completely new to java. I am using p5 and want to set up a simple function that, depending on what number the user inputs, it draws that many circles. I'm not sure why it is not working.
var numProton;
function setup() {
numProton = createInput();
numProton.changed(nucleus);
createCanvas(600, 500);
background(255);
}
function draw() {
noStroke()
textSize(15);
fill(0, 0, 0);
text('^ # of Protons', 25, 30);
text('^ # of Neutrons', 150, 30);
text('^ # of Electrons', 275, 30);
}
function nucleus() {
var i = 0;
while(i <= numProton.value) {
ellipse(300, 250, 10);
i++;
}
}
Probably a very simple error but I appreciate the help none the less.

Why don't you use a for loop, it has the same exact purpose:
for (var i = 0; i <= numProton.value; i++) {
ellipse(300, 250, 10);
}

Is it possible that numProton.value() is supposed to be a function call with ()?
See here p5.js/changed

Related

Execute function when the spacebar key is pressed

This is my code:
var drawGlob = function () {
function keyPressed() {
if (keyTyped === 32) {
var size = (random(100, 150));
fill(random(0, 255), 0, 0);
ellipse(mouseX, mouseY, size, size);
return false;
}
}
};
var draw = function () {
noStroke();
drawGlob();
};
After some testing, I discovered that the problem lies within:
var draw = function () {
noStroke();
drawGlob();
};
Not sure where and how you are using it, more information would be useful. Anyway, in drawGlob you are declaring a function in a function, and where is it taking the variable keyTyped since it is not passed as arguments?
Are you referring to keyTyped the function? maybe take a look to this example
Maybe you meant keyCode here another example
Edit: try this:
function keyPressed() {
if (keyCode === 32) {
var size = (random(100, 150));
fill(random(0, 255), 0, 0);
ellipse(mouseX, mouseY, size, size);
return false;
}
};
var draw = function() {
noStroke();
};
So, when you press a Spacebar(32) it will trigger a random circle where the mouse is pointed.

p5.js : Trouble with clicking buttons and objects

I am really new to p5.js, and I'm trying to find a solution to this for a few days with no luck.
I have a button and an ellipse. When the button is clicked a rectangle appears on the canvas and when the ellipse is clicked its color changes.The problem is that I can't have both at the same time and the reason is this part of the code:
stroke(rgb);
strokeWeight(2);
If I have it on my code, when I click the button the rectangle appears, but when I click the ellipse nothing happens. If I leave it out of my code, I can change the ellipse's color, but when I click the button nothing happens.
I have no idea why these two lines of code make it impossible to interact with both the button and the shape, and I'd really like to find out. Am I missing something important?
My code is the following:
function setup(){
createCanvas(800, 600);
bubble = new new_ellipse(500,300);
}
function draw() {
background(51);
button = createButton("clickme");
button.position(100, 65);
button.mousePressed(show_rect);
bubble.display();
stroke(rgb);
strokeWeight(2);
}
function mousePressed(){
bubble.clicked();
}
function new_ellipse(x,y){
this.x = x;
this.y = y;
this.col = color(255,100);
this.display = function(){
stroke(255);
fill(this.col);
ellipse(this.x, this.y, 100, 100);
}
this.clicked = function(){
var d = dist(mouseX, mouseY, this.x, this.y);
if(d < 50){
this.col = color(233,11,75);
}
}
}
function show_rect(){
fill(255,24,23);
rect(200,200,100,100);
}
Two related issues:
Don't call createButton inside draw. draw is called about 60 times a second, so this spams buttons. draw is your animation loop. Use setup to set things up.
Given that draw() runs 60 times a second, any calls to show_rect triggered by a button press will be almost instantly wiped clean by background(51) a split second later.
One option is to introduce a boolean to keep track of whether the button has been pressed yet, then re-draw it every frame if it's supposed to be visible.
Another approach is to drop the draw() function and re-paint only when state changes. This prevents background(51) from blasting everything and is efficient, but also isn't suitable if you have animations or a good deal of dynamism in your app.
Here's a sample of the first approach, using a boolean:
var bubble, button;
var shouldShowRect = false;
function setup() {
createCanvas(800, 600);
bubble = new Ellipse(500, 300);
button = createButton("clickme");
button.mousePressed(function () {
// or set to true if you don't want to toggle
shouldShowRect = !shouldShowRect;
});
button.position(100, 65);
}
function draw() {
background(51);
bubble.display();
if (shouldShowRect) {
showRect();
}
strokeWeight(2);
}
function mousePressed() {
bubble.clicked();
}
function Ellipse(x, y) {
this.x = x;
this.y = y;
this.col = color(255, 100);
this.display = function() {
stroke(255);
fill(this.col);
ellipse(this.x, this.y, 100, 100);
}
this.clicked = function() {
var d = dist(mouseX, mouseY, this.x, this.y);
if (d < 50) {
this.col = color(233, 11, 75);
}
}
}
function showRect() {
fill(255, 24, 23);
rect(200, 200, 100, 100);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>

p5.js: Why is my ellipse flashing?

I have an ellipse that scales through draw(), but for some reason, it flashes uncontrollably. I can't seem to figure out why. I suspect it has to do with setTimeout. I need it because I need to wait 10 seconds before drawing the ellipse Here's the code:
//diameter of ellipse that increments
var dia1 = 0;
var dia2 = 0;
function setup() {
createCanvas(400,400);
stroke(255);
noFill();
frameRate(40);
}
//draw and increment ellipse
function circle1() {
ellipse(width/2,height/2, dia1,dia1);
dia1 = dia1+1;
if (dia1 >= width) {
dia1 = 0;
}
}
function circle2() {
ellipse(width/2,height/2, dia2,dia2);
dia2 = dia2+1;
if (dia2 >= width) {
dia2 = 0;
}
}
function draw() {
background(40,40,40);
//wait 10 seconds before drawing ellipse
setTimeout(function() { circle1(); }, 10000);
circle2();
console.log(dia1);
}
You should not use setTimeout() to call drawing functions.
If you want to do timing, use the millis() function. More info is available in the reference, but a basic program would look like this:
function draw(){
background(0);
if(millis() > 10000){
ellipse(width/2, height/2, 25, 25);
}
}

Create JS function add to stage

In createjs I'm trying to add elements to the stage but only when called by a function.
If I add this code into my onload init() function the code works:
function init()
{
background = new createjs.Shape();
background.graphics.beginLinearGradientFill(["blue", "darkgreen"], [0, 1], 0, 0, 100, 100).drawRect(0, 0, 70, 70);
background.x = 0;
background.y = 0;
stage.addChild(background);
}
However if I add it like
function init()
{
loadScreen();
}
function loadScreen()
{
background = new createjs.Shape();
background.graphics.beginLinearGradientFill(["blue", "darkgreen"], [0, 1], 0, 0, 100, 100).drawRect(0, 0, 70, 70);
background.x = 0;
background.y = 0;
stage.addChild(background);
}
I'm probably just doing something silly, any tips appreciated.
Thanks,
Remove the semicolon(;) after loadScreen() function defenition
function init()
{
loadScreen();
}
function loadScreen()
{
background = new createjs.Shape();
background.graphics.beginLinearGradientFill(["blue", "darkgreen"], [0, 1], 0, 0, 100, 100).drawRect(0, 0, 70, 70);
background.x = 0;
background.y = 0;
stage.addChild(background);
}
Make sure that your variables are declared.
E.g.
var stage; var background;
And make sure that they are global.
window.onload = function(){
var stage;
var background;
function init(){
// create reference to stage and add 'tick' listener.
}
function loadScreen(){
// draw something onto the stage.
}
};
Check out this website for an example: http://createjs.com/docs/easeljs/modules/EaselJS.html.
I can see that you removed this line ->
myGraphics.beginLinearGradientFill(["#000","#FFF"], [0, 1], 0, 20, 0, 120).drawRect(20, 20, 120, 120);
Have you tried instantiating background inside init() and then passing the object to the load function?

Javascript setInterval() function not working in drawing to canvas

I am trying to draw a line in a canvas. I am trying to make the line moving with time. I am using the following code to do so
var ctx = mycanvas.getContext('2d');
ctx.beginPath();
for (var x = 0; x < 200; x++) {
setInterval(draw(x, 0, ctx), 3000);
x = x++;
}
And here is the draw function
function draw(x, y, ctx) {
ctx.moveTo(10 + x, 400);
ctx.lineTo(11 + x, 400);
ctx.lineWidth = 10;
ctx.strokeStyle = "#ff0000";
ctx.stroke();
}
But the setInterval() function is not working and the line is being drawn instantly. Its not waiting for 3s to proceed to next pixel.
Am I making a mistake?
setInterval needs a function as the first parameter. Right now you are just calling draw(x,0,ctx) and it returns undefined. So your code is equivalent to setTimeout(undefined, 3000).
Instead you need to provide a callable function and invoke draw from it. Try this:
setInterval(function() {
draw(x, 0, ctx);
}, 3000);
Another problem is due to typical closure in loop behavior. You will need to create separate scope to be able to work with individual values of x:
for (var x = 0; x < 200; x++) {
(function(x) {
setInterval(function() {
draw(x, 0, ctx);
}, 3000 * x);
})(x);
x = x++;
}
Also check this question for more examples how to fix situations like this.

Categories

Resources