Samy Samy - 7 months ago 30
Javascript Question

Canvas+Javascript water overlay

I'm trying to make water waves in Javascript on a canvas but there is something wrong.

My idea was making 3 waves with different colors but they overdraw each other.
I was not able figure out where the problem is.



<!DOCTYPE HTML>
<html>

<style>

<!-- 100% area -->
body, html {
height: 100%;
width: 100%;
}
</style>

<body>
<canvas id="myCanvas" ></canvas>

<script>
//get window size
var canvas = document.getElementById( "myCanvas" );
canvas.width = window.innerWidth; /// equal to window dimension
canvas.height = window.innerHeight;

// get the context
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext('2d');


// VARIABLES
var frameCount=0;
var N = 30;
var positionXTeiler= Math.floor(canvas.width/(N-N/2));
var size = 50;
var xOffset = 200;
var colors = [];
var amplitude = 200;
var wavesCount = 3;


var init = function()
{
colors.push("rgba(0,0,128,1)");
colors.push("rgba(0,0,255,1)");
colors.push("rgba(47,86,233,1)");
}

var draw = function() {

context.clearRect (0, 0, canvas.width, canvas.height);


for (i=0; i<N; i++) {

for (n=0; n<wavesCount; n++) {
var x = amplitude*Math.sin (frameCount*0.02+n*Math.PI/2);
context.save();
context.fillStyle = colors[n];
context.beginPath();
context.arc(positionXTeiler*i+x-xOffset,canvas.height-n*20,size,0,Math.PI*2,true);
context.closePath();
context.fill();

context.restore();
}
}
// count the frame and loop the animation
frameCount = frameCount+1;
requestAnimationFrame(draw);
};

// start the loop
init();
draw();


</script>

</body>

</html>





My result should look like that + with moving

enter image description here

Answer

Loop the waves, then, inside, loop the circles (i.e. inverts the 2 loops).

The goal is to create all circles of a wave before moving to the next. This way you make sure that the circles of a wave are drawn on top of the previous one.

Also, you may want to consider using a time-based increment instead of a frame count. Your frames are not guaranteed to be regular.

<!DOCTYPE HTML>
<html>

  <style>

    <!-- 100% area -->
    body, html {
      height: 100%;
      width: 100%;
    }
  </style>

  <body>
    <canvas id="myCanvas" ></canvas>

    <script>
      //get window size
      var canvas = document.getElementById( "myCanvas" );
      canvas.width = window.innerWidth;   /// equal to window dimension
      canvas.height = window.innerHeight;

      // get the context
      var canvas = document.getElementById("myCanvas");
      var context = canvas.getContext('2d');


      // VARIABLES
      var frameCount=0;
      var N = 30;
      var positionXTeiler= Math.floor(canvas.width/(N-N/2));
      var size = 50;
      var xOffset = 200;
      var colors = [];
      var amplitude = 200;
      var wavesCount = 3;


      var init = function()
      {
        colors.push("rgba(0,0,128,1)");
        colors.push("rgba(0,0,255,1)");
        colors.push("rgba(47,86,233,1)");
      }

      var draw = function() {

        context.clearRect (0, 0, canvas.width, canvas.height);	

        for (n=wavesCount-1; n>=0; n--) { 
          for (i=0; i<N; i++) { 
            var x = amplitude*Math.sin (frameCount*0.02+n*Math.PI/2);
            context.save();
            context.fillStyle = colors[n];
            context.beginPath();
            context.arc(positionXTeiler*i+x-xOffset,canvas.height-n*20,size,0,Math.PI*2,true);
            context.closePath();
            context.fill();

            context.restore();
          }
        }       
        // count the frame and loop the animation
        frameCount = frameCount+1;
        requestAnimationFrame(draw);
      };

      // start the loop
      init();
      draw();


    </script>

  </body>

</html>