The animations on this page are generated using the program below. We start with a 20x20 grid and for each point we calculate the height of the wave using the sine and cosine functions of the point coordinates.
| <html> |
| <body> |
| <canvas id="myCanvas" width="600" height="800"></canvas> |
| <script> |
| function animate() { |
| context.clearRect(0, 0, canvas.width, canvas.height); |
| for (let x = 0; x < size; x++) { |
| for (let y = 0; y < size; y++) { |
| dots[x][y] = (y + 5 * Math.sin(counter / 50) * Math.sin((x + y) / (Math.PI * 2))) * scale; |
| if (x > 0 && y > 0) { |
| context.fillStyle = `hsl(${x * y + counter % 360},100%,50%)`; |
| context.beginPath(); |
| context.moveTo(x * scale, +(dots[x][y])); |
| context.lineTo((x - 1) * scale, (dots[x - 1][y])); |
| context.lineTo((x - 1) * scale, (dots[x - 1][y - 1])); |
| context.lineTo(x * scale, (dots[x][y - 1])); |
| context.lineTo(x * scale, (dots[x][y])); |
| context.fill(); |
| context.stroke(); |
| } |
| } |
| } |
| counter++; |
| window.requestAnimationFrame(animate); |
| } |
| let canvas = document.getElementById('myCanvas'); |
| let context = canvas.getContext('2d'); |
| let counter = 0; |
| const size = 20; |
| const scale = 30; |
| const dots = new Array(size); |
| for (let x = 0; x < size; x++) { |
| dots[x] = new Array(size); |
| } |
| animate(); |
| </script> |
| </body> |
| </html> |
Detailed code walkthrough
Lines [5-25]: the main 'animate' function, where all the magic happens.
[6] clear the previous animation frame
[7-8] loop through every dot in the grid
[9] the math formula that converts the x and y grid coordinates into the wave height at that point
[10-19] set the color based on the grid coordinates and the counter and draw a filled quadrilateral from the neighboring grid points to the current
[23] increase the frame counter - this makes the colors cycle in line 11
[24] wait for the next animation frame
[27-35] set up the canvas and declare the variables
[36] kick off the animation!
You can experiment with different formulas in line 9. Here are some examples:
dots[x][y] = (y + 5 * Math.sin(counter / 50) * Math.cos((x * x * y) / Math.PI / 50)) * scale;
dots[x][y] = scale*(y + Math.sin((x*5*y+counter)/Math.PI/10));
Try also:
dots[x][y] = scale * (y + Math.sin((25 * x * x * y + counter) / Math.PI / 10));
dots[x][y] = scale * (y + Math.sin((x * y + counter) / Math.PI / 10));
dots[x][y] = scale * (y + Math.sin(x) * Math.cos(y + counter / Math.PI / 4));