-1

This is the effect that I am trying to achieve: link

I have gotten the four waves and they are indeed animated, but I have gotten stuck on giving each of them a slightly different animation. At the current point, all curves move at the same speed, in the same direction and switch at the same place too. they should vary slightly in all these aspects. The end result I am looking for is very much like the link i posted, with difference that each wave can only have a maximum of one cycle, that is going up once and coming down once. Thank you for your input.

Below is my code:

function start() {  
  var canvas = $("canvas");
  console.log(canvas);
  canvas.each(function(index, canvas) {
      var context = canvas.getContext("2d"); 
      canvas.width = $(".box").eq(index).width();
      canvas.height = $(".box").eq(index).height();
      context.clearRect(0, 0, canvas.width, canvas.height);
      drawCurves(context, step);
      step += 1;
  });
  requestAnimationFrame(start);
}
var step = -1;
function drawCurves(ctx, step) {
    var width = ctx.canvas.width;
    var height = ctx.canvas.height;
    ctx.lineWidth = 2;
    
  for (i = 0; i < 4 ; i++) {    
    var x = 0;
    var y = 0;
    ctx.beginPath();
    if (i === 0 ) {
      ctx.strokeStyle = "red";
      var amplitude = 20;
     var frequency = height / (2 * Math.PI) ; 
      console.log(i, frequency);
     }  if ( i === 1) {
         ctx.strokeStyle = "blue";
       var amplitude = 30;
      var frequency = (height / (2 * Math.PI));
      console.log(i, frequency);
     }  if ( i === 2) {
          ctx.strokeStyle = "green";
       var amplitude = 40;
       var frequency = height / (2 * Math.PI) ;
      console.log(i, frequency);     
     }  if (i === 3) {
       ctx.strokeStyle = "yellow";
       var amplitude = 50;
      var frequency = height / (2 * Math.PI) ;
      console.log(i, frequency);
     }
  ctx.save();
  ctx.translate(-amplitude * Math.sin(step / frequency), 0);
  while (y < height) {
    x = (width / 2) + (amplitude * Math.sin((y + step) / frequency)) ;
    ctx.lineTo(x, y);
    y++;
  }
  ctx.closePath();
  ctx.stroke();
  ctx.restore();
}
  }


$(document).ready(function() {
  start();
})
<!DOCTYPE html>
<html>

<head>
</head>

<body>
   
  <div class="box">
       <canvas id="canvas"></canvas>
    </div>
  <div class="box">
       <canvas id="canvas"></canvas>
    </div>
  
</body>

</html>

And here a Code Pen

felixo
  • 1,453
  • 6
  • 33
  • 60
  • 1
    For the small canvas try: `drawWave(context, 10,2,"sin"); drawWave(context, 10,2,"cos"); drawWave(context, 20,2,"sin");` The main idea is to have a `sin` and a `cos` with the same amplitude and another `sin` or `cos` with a different amplitude – enxaneta May 14 '19 at 16:57

2 Answers2

0

Your code draw only one sinus wave. I'll advice you those points:

_If you want different(simultaneaous) wave you've to use differents x/y values at the draw point.

_You use $(document).ready(function() as animation loop, that's not the better way do do it. For animation you should set a setInterval or way better use the requestAnimationFrame who is meant to create animation. In each animation loop draw the 4 sinus lines, i'll forget about step for using objects instead that i think is better but that's not important point. I've no time to try your code but what is it doing when using requestAnimationFrame(start()) instead of the $document.ready ? Obviously in each animatve to clear the drawing place using clearRect(width,height); for example.

_The 4 steps add +1 to +4 to y in the same cartesian equation. In a sinus curve that will not really be seeing by human eyes because it's a really slight variation. You can use differents equations using differents sinusoïd equations for each step/object, i.e. Math.sin(y)+10 or Math.sin(y)*10 etc...or even different incremantation value for each differents objects. _i'll avoid translate and use a for loop to increment the x value and get the y value using sin(x) and whatever equation you need , that's personal choice but will avoid to write the .translate() line and will use normal coordinates instead of moved coordinates so you'll easily see in console.log real coordinates in canvas area.

_As for previous you can throw away the checking IFs at beginning of program if you use objets in a array (and loop it) and set a styleColor and weight of each of 4 objets.

Hope it's help, no time to write a clean code.

jean3xw
  • 121
  • 7
0

@enxaneta thank you for your input! Got it the way I wanted to, below is my solution:

var step = 0;
  
function start(timestamp) {
     var canvas = $("canvas");
     canvas.each(function(index, canvas) {
         var context = canvas.getContext("2d"); 
           canvas.width = $(".box").eq(index).width();
           canvas.height = $(".box").eq(index).height();
           context.clearRect(0, 0, canvas.width, canvas.height);
           if (canvas.height > 1000 ) {
            drawWave(context, 20,"sin");
            drawWave(context, 60,"cos");
            drawWave(context, 40,"sin");
            drawWave(context, 80,"cos"); 
           }

           if (canvas.height < 1000 ) {
            drawWave(context, 10,"sin");
            drawWave(context, 30,"cos");
            drawWave(context, 20,"sin");
            drawWave(context, 40,"cos"); 
           }
         
         step = timestamp / 7;
     });
        window.requestAnimationFrame(start);
  }

  function drawWave(ctx,amplitude,trig){
     var width = ctx.canvas.width;
     var height = ctx.canvas.height;
     ctx.beginPath();
     ctx.lineWidth = 2;
     ctx.strokeStyle = "blue";

     var x = 0;
     var y = 0;
     var frequency = height / (2 * Math.PI);
     ctx.save();
     ctx.translate(-amplitude * Math[trig](step / frequency), 0);
     while (y < height) {
        x = width / 2 + amplitude * Math[trig]((y + step) / frequency);
       ctx.lineTo(x, y);
        y++;
     }
     // ctx.closePath();
     ctx.stroke();
     ctx.restore();
  }
$(document).ready(function() {
  start();
});
canvas {
  background-color: wheat;
  position: absolute;
}
.box {
width: 500px;
 height: 2000px;
  border: solid;
}

.box.t {
width: 500px;
 height: 200px;
  border: solid;
}
<!DOCTYPE html>
<html>

<head>
</head>

<body>
     <div class="box t">
       <canvas id="canvas"></canvas>
    </div>
  
  <div class="box">
       <canvas id="canvas"></canvas>
    </div>

</body>

</html>
felixo
  • 1,453
  • 6
  • 33
  • 60