requestAnimationFrame

  • Window. RequestAnimationFrame with setTimeout () method is similar, are delay the execution of a function. The difference is that setTimeout must specify a delay;

  • Window. RequestAnimationFrame browser () is delayed until next heavy flow execution, the execution of the redrawn to the next. Re-paint is usually 16.7 ms (60 FPS/s) performs a, but the browser will automatically adjust the rate, such as web page Tab to switch to the background, the window. The requestAnimationFrame () will be suspended.

  • If a function to change the layout of the page, usually on the window. The requestAnimationFrame (), so I can save system resources, make the site more smooth. This is because slower devices will restream and redraw at a slower rate, while faster devices will have a faster rate.

  • This method takes a callback function as an argument.

    window.requestAnimationFrame(callback)
    Copy the code
  • Window. RequestAnimationFrame () of the return value is an integer, the integer can be passed

  • Window. CancelAnimationFrame (), which is used to cancel the execution of the callback function.

The setInterval timer implements canvas animation

Code implementation:

<canvas id="cas" width="600px" height="500px">Your browser does not support canvas, please upgrade your browser</canvas>
<button id="btn-dir-left">please</button>
<button id="btn-dir-right">-</button>
<button id="btn-dir-up">write</button>
<button id="btn-dir-down">left</button>
Copy the code
* {
    margin: 0;
    padding: 0;
}
canvas {
    border: 1px solid #ccc;
    margin: 20px;
}
button {
    width: 30px;
    height: 25px;
    margin: 5px;
}
Copy the code
let cas = document.querySelector("#cas")
let ctx = cas.getContext('2d')

// Control the cropping image's Y coordinates indirectly control the direction
let dirIndex = 0
let timer = null
let img = new Image()
img.src = "https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/1/16/16855fe9b908c9af~tplv-t2oaga2asx-image.image"<! -- setInterval --> img.onload =function() {
    // Use to control the X coordinate of the cropping image
    let xIndex = 0
    clearInterval(timer)
    timer = setInterval((a)= > {
        // Clear the previous canvas
        ctx.clearRect(0.0, ctx.canvas.width, ctx.canvas.height)
        ctx.drawImage(
            img, / / 160 * 260
            xIndex * 40.// Cut the x coordinate of the image
            dirIndex * 65.40.// Cut the width of the image
            65.240.// Display the x coordinate at the canvas position
            150.40.// The width of the image to use
            65 / / height
        )
        xIndex ++
        xIndex %= 4
    }, 200)}// Change the direction by the y coordinate of the image
/* ===== bind click events ======== */
document.querySelector("#btn-dir-left").onclick = function(){
    dirIndex = 1;
}
document.querySelector("#btn-dir-right").onclick = function(){
    dirIndex = 2;
}
document.querySelector("#btn-dir-up").onclick = function(){
    dirIndex = 3;
}
document.querySelector("#btn-dir-down").onclick = function(){
    dirIndex = 0;
}
Copy the code

RequestAnimationFrame implements canvas animation

Main JS improvements above:

 // Use to control the X coordinate of the cropping image
let xIndex = 0
step = (timestamp, elapsed) = > {
     // Clear the previous canvas
    ctx.clearRect(0.0, ctx.canvas.width, ctx.canvas.height)
        ctx.drawImage(
            img, / / 160 * 260
            xIndex * 40.// Cut the x coordinate of the image
            dirIndex * 65.40.// Cut the width of the image
            65.240.// Display the x coordinate at the canvas position
            150.40.// The width of the image to use
            65 / / height
        )
    xIndex ++
    xIndex %= 4

    requestAnimationFrame(step)
}

requestAnimationFrame(step)
Copy the code

As mentioned above, requestAnimationFrame is deferred until the next browser restream and then the next redraw. Redraw is usually 16.7ms (60fps/s), so how do we adjust the frame rate if we want to animate at 10 frames per second?

As mentioned above, requestAnimationFrame returns an integer; RequestAnimationFrame calls callback with a timestamp parameter, which can be used to determine the frame rate you need.

For example /10 frames per second, write:

let step = (timestamp, elapsed) = > {
    if (elapsed > 1000 / 7) {
        //TO DO SOMETHING
        elapsed = 0
    }
    
    requestAnimationFrame(
        _timestamp= > step(_timestamp, elapsed + _timestamp - timestamp)
    )
}
requestAnimationFrame(timestamp= > step(timestamp, 0))
Copy the code

The above code can be rewritten:

 // Use to control the X coordinate of the cropping image
let xIndex = 0
step = (timestamp, elapsed) = > {
    if (elapsed > 1000 / 10) {
            // Clear the previous canvas
        ctx.clearRect(0.0, ctx.canvas.width, ctx.canvas.height)
            ctx.drawImage(
                img, / / 160 * 260
                xIndex * 40.// Cut the x coordinate of the image
                dirIndex * 65.40.// Cut the width of the image
                65.240.// Display the x coordinate at the canvas position
                150.40.// The width of the image to use
                65 / / height
            )
        xIndex ++
        xIndex %= 4
        elapsed = 0
    }

    requestAnimationFrame(
        _timestamp= > step(_timestamp, elapsed + _timestamp - timestamp)
    )
}

requestAnimationFrame(timestamp= > step(timestamp, 0))
Copy the code