Reputation: 97
I've made a sine wave animation with javascript where the area below the sine wave is filled with a light blue color. But when I run the code my computer starts heating up and lags. This could also be beacause my computer is pretty worn out by now, but I really would like to know how to optimize this code or maybe recreate the effect with something else that isn't so performance intensive if possible.
The Sine wave animation: https://jsfiddle.net/x2audoqk/13/
The code:
const canvas = document.querySelector("canvas")
const c = canvas.getContext("2d")
canvas.width = innerWidth
canvas.height = innerHeight
window.addEventListener("resize", function () {
canvas.width = innerWidth
canvas.height = innerHeight
wave.y = canvas.height / 1.5
wave.length = -4.5 / canvas.width
amplitude = canvas.width / 35
})
const wave = {
y: canvas.height / 1.5,
length: -4.5 / canvas.width,
amplitude: canvas.width / 25,
frequency: 0.0045
}
let increment = wave.frequency
function animate() {
requestAnimationFrame(animate)
// Deletes previous waves
c.clearRect(0, 0, canvas.width, canvas.height)
c.beginPath()
// Get all the points on the line so you can modify it with Sin
for (let i = 0; i <= canvas.width; i++) {
c.moveTo(i, wave.y + Math.sin(i * wave.length + increment) * wave.amplitude * Math.sin(increment))
c.lineTo(i, canvas.height)
}
// Fill the path
c.strokeStyle = 'rgba(1, 88, 206, .25)'
c.stroke()
increment += wave.frequency
c.closePath()
}
animate()
Any suggestions are welcome.
Upvotes: 0
Views: 113
Reputation: 3804
The heavy load is due to requestAnimationFrame
which run over and over again. An approach is to limit the frame rate of the animation. Knowing that the human's eyes need at least 24 fps for a fluid image, you can pick a fps between 24-60 fps of your choice (limited by monitor refresh rate up to 60Hz depends on configuration but this is mostly the default).
Here is a guide how to control the fps
var fps = 30;
var now;
var then = Date.now();
var interval = 1000/fps;
var delta;
function animate() {
requestAnimationFrame(animate);
now = Date.now();
delta = now - then;
if (delta > interval) {
then = now - (delta % interval);
//your code drawing here
}
}
animate();
The the difference between 30 fps and 60 fps
Another technique to achieve the same effect with less workload is to use CSS animation (horizontal), with your background wave pre-draw as an image.
Upvotes: 2