Firebase Javascript + P5.js: an asynchronous function that prevents the canvas from being redrawn

I am trying to create an application in which circles will be drawn on canvas by reading information from the Firebase database, which stores the x and y coordinates of the circles. However, the execution of the code below simply does not give anything, without any signs of circles, because the drawCricles function is executed asynchronously, and thus the command background(40)clears everything before the circles can be drawn.

Here is my code:

function setup() {
    createCanvas(windowWidth, windowHeight); 
    background(40); 
    stroke(80); 
    smooth();
    frameRate(60);
}

function drawCircles() {
    firebase.database().ref("circles").once("value", function(snapshot) {
        var snapshotVal = snapshot.val();
        var circleCount = snapshotVal.numCircles;

        for (var j = 0; j < circleCount; j++) {
            firebase.database().ref("circles" + j).once("value", function(snapshot) {
                var snapshotValue = snapshot.val();
                fill(143, 2, 2);
                ellipse(snapshotValue.xPos, 50, 50);
            });
        }
    });
}

function draw() {
    stroke(80);
    background(40);

    stroke(0);
    drawCircles(); 
}
+6
source share
3 answers

, 60 , . Firebase .once async, , P5 , , .

, , , .

1 -

.

  • 1: , , , . , .on("value") .once("value"), firebase , , , 60 , . : . 1 .

  • 2: , , 60 . .once draw() . . 2 .

2 -

, . , , circleCount. , , , , , . ( )

, -, circles1 circles2 .. , .ref("circles" + j) . , : .ref("circles/" + j), , circle circles. , circles/circle1 circles/circle2 ..

, firebase, . Firebase , forEach .

3 - firebase

. , firebase 1/60 (16 miliseconds), . , . 30 , , firebase 30 .

1

(, , - , , xPos)

var latestCirclePositionsSnapshot;

function setup() {
  createCanvas(windowWidth, windowHeight); 
  background(40); 
  stroke(80); 
  smooth();
  frameRate(60);

  firebase.database().ref("circles").on("value", function(snapshot) {
    // got a new value from database, so let save this in a global variable. 
    latestCirclePositionsSnapshot = snapshot;
    // we will keep drawing this update until we get a new one from the database.
  });
}

function draw() {
  drawCircles(); 
}

function clearBackground () {
  stroke(80);
  background(40);
}

function drawCircles() {
  clearBackground();
  stroke(0);  
  latestCirclePositionsSnapshot.forEach(function(circleSnapshot) {  
    // circleData will be the actual contents of each circle
    var circleData = circleSnapshot.val();
    fill(143, 2, 2);
    ellipse(circleData.xPos, 50, 50);
  });
}

, firebase, . ( , P5 60 , firebase , firebase firebase ..)

2

, , , , firebase (, )

var circlePositions;
var gotPositions = false;

function setup() {
  createCanvas(windowWidth, windowHeight); 
  background(40); 
  stroke(80); 
  smooth();
  frameRate(60);

  firebase.database().ref("circles").once("value", function(snapshot) {
    // got the circle values from the database
    // let store them and we'll keep drawing them forever. 
    circlePositions = snapshot;
    gotPositions = true;
  });
}

function draw() {
  drawCircles(); 
}

function clearBackground () {
  stroke(80);
  background(40);
}

function drawCircles() {
  clearBackground();
  stroke(0); 

  if (gotPositions) {
    circlePositions.forEach(function(circleSnapshot) {  
      // circleData will be the actual contents of each circle
      var circleData = circleSnapshot.val();
      fill(143, 2, 2);
      ellipse(circleData.xPos, 50, 50);
    });
  } else {
    // Display some text here like "LOADING DATA FROM SERVERS..." 
  }
}

, :) Processing Firebase.

0

, . , :

var circles = [];

function fetchData() {
    firebase.database().ref("circles").once("value",
    function(snapshot) {
        var snapshotVal = snapshot.val();
        var circleCount = snapshotVal.numCircles;
        
        circles = [];

        for (var j = 0; j < circleCount; j++) {
            firebase.database().ref("circles" + j).once("value",                 function(snapshot) {
                circles.push(snapshot.val());
            });
        }
    });
}

function setup() {
    createCanvas(windowWidth, windowHeight); 
    background(40); 
    stroke(80); 
    smooth();
    frameRate(60);
    fetchData();
}

function drawCircles() {
    circles.forEach(function (snapshotValue) {
        var snapshotValue = snapshot.val();
        fill(143, 2, 2);
        ellipse(snapshotValue.xPos, 50, 50);
    });
}

function draw() {
    stroke(80);
    background(40);

    stroke(0);
    drawCircles(); 
}
Hide result

, fetchData, setInterval, :

function setup() {
      createCanvas(windowWidth, windowHeight); 
      background(40); 
      stroke(80); 
      smooth();
      frameRate(60);
      setInterval(fetchData, 5000); //will call fetchData every 5000 ms
  }
Hide result
0

, drawCircles() - , draw() frameRate(), background() : . background. background(40) draw(), , . , Firebase .

, : background() setup(), draw(), , , .

function setup() {
  createCanvas(400, 200);
  frameRate(5)
  background(40);
}
function drawCircles() {
  fill(143, 2, 2);
  ellipse(random(width), 50, 50);
}
function draw() {
  // background(40);
  drawCircles();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.16/p5.js"></script>
<html>
  <head>
  </head>
  <body>
  </body>
 </html>
Hide result

, , createGraphics. , (, ..).

Here is an example: each frame is cleared using background(), then the buffer is pgdrawn on the canvas, then the mouse is drawn in a white circle. Since the background clears the screen, the white circle leaves no traces from frame to frame, but the red circles are drawn on an uncleared graphic buffer, so they are saved.

var pg;
function setup() {
  createCanvas(400, 200);
  pg = createGraphics(400, 200);
  background(40);
}
function drawCircles() {
  pg.fill(143, 2, 2);
  pg.ellipse(random(pg.width), 50, 50);
}
function draw() {
  background(40);
  drawCircles();
  image(pg,0,0);
  fill(255);
  ellipse(mouseX,mouseY,50,50);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.16/p5.js"></script>
<html>
  <head>
  </head>
  <body>
  </body>
</html>
Run codeHide result
0
source

All Articles