简体   繁体   中英

Improve performance of js animation

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM