博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
requestAnimationFrame实现canvas动画
阅读量:7087 次
发布时间:2019-06-28

本文共 3715 字,大约阅读时间需要 12 分钟。

requestAnimationFrame

  • window.requestAnimationFrame() 方法跟 setTimeout 类似,都是推迟某个函数的执行。不同之处在于,setTimeout 必须指定推迟的时间;

  • window.requestAnimationFrame() 则是推迟到浏览器下一次重流时执行,执行完才会进行下一次重绘。重绘通常是 16.7ms (60fps/s) 执行一次,不过浏览器会自动调节这个速率,比如网页切换到后台 Tab 页时,window.requestAnimationFrame() 会暂停执行。

  • 如果某个函数会改变网页的布局,一般就放在 window.requestAnimationFrame() 里面执行,这样可以节省系统资源,使得网页效果更加平滑。因为慢速设备会用较慢的速率重流和重绘,而速度更快的设备会有更快的速率。

  • 该方法接受一个回调函数作为参数。

    window.requestAnimationFrame(callback)复制代码
  • window.requestAnimationFrame() 的返回值是一个整数,这个整数可以传入

  • window.cancelAnimationFrame(),用来取消回调函数的执行。

定时器 setInterval 实现 canvas 动画

代码实现:

您的浏览器不支持canvas,请升级您的浏览器
复制代码
* {    margin: 0;    padding: 0;}canvas {    border: 1px solid #ccc;    margin: 20px;}button {    width: 30px;    height: 25px;    margin: 5px;}复制代码
let cas = document.querySelector("#cas")let ctx = cas.getContext('2d')// 控制裁剪图片的 Y 坐标间接控制方向let dirIndex = 0let timer = nulllet img = new Image()img.src = "https://user-gold-cdn.xitu.io/2019/1/16/16855fe9b908c9af?w=160&h=260&f=png&s=5138"
img.onload = function() { // 用来控制裁剪图片的 X 坐标 let xIndex = 0 clearInterval(timer) timer = setInterval(() => { // 清除之前的画布 ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height) ctx.drawImage( img, // 160 * 260 xIndex * 40, // 剪切图片的 x 坐标 dirIndex * 65, 40, // 剪切图像的宽度 65, 240, // 显示在画布位置的 x 坐标 150, 40, // 要使用的图像的宽度 65 // 高度 ) xIndex ++ xIndex %= 4 }, 200)}// 改变方向 通过图像的 y 坐标/* =====绑定点击事件======== */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;}复制代码

requestAnimationFrame 实现 canvas 动画

上面主要 js 改进:

// 用来控制裁剪图片的 X 坐标let xIndex = 0step = (timestamp, elapsed) => {     // 清除之前的画布    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)        ctx.drawImage(            img, // 160 * 260            xIndex * 40, // 剪切图片的 x 坐标            dirIndex * 65,            40, // 剪切图像的宽度            65,            240, // 显示在画布位置的 x 坐标            150,            40, // 要使用的图像的宽度            65 // 高度        )    xIndex ++    xIndex %= 4    requestAnimationFrame(step)}requestAnimationFrame(step)复制代码

上面说到,requestAnimationFrame 是推迟到浏览器下一次重流时执行,执行完才会进行下一次重绘。重绘通常是 16.7ms (60fps/s),那我们要是想让动画每秒 10 帧,该如何调节帧频呢?

上面也提到,requestAnimationFrame 返回值是一个整数;而 requestAnimationFrame 调用 callback 的时候会传入一个时间戳参数,可以根据这个参数来进行判断从而处理你实际需要的帧速;

比如要每秒/10 帧的话,可这样写:

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))复制代码

上面代码可改写:

// 用来控制裁剪图片的 X 坐标let xIndex = 0step = (timestamp, elapsed) => {    if (elapsed > 1000 / 10) {            // 清除之前的画布        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)            ctx.drawImage(                img, // 160 * 260                xIndex * 40, // 剪切图片的 x 坐标                dirIndex * 65,                40, // 剪切图像的宽度                65,                240, // 显示在画布位置的 x 坐标                150,                40, // 要使用的图像的宽度                65 // 高度            )        xIndex ++        xIndex %= 4        elapsed = 0    }    requestAnimationFrame(        _timestamp => step(_timestamp, elapsed + _timestamp - timestamp)    )}requestAnimationFrame(timestamp => step(timestamp, 0))复制代码

转载于:https://juejin.im/post/5c3ef5505188252552516304

你可能感兴趣的文章
memset struct含有string的崩溃
查看>>
时间范围比较
查看>>
给初学者的RxJava2.0教程(三)(转)
查看>>
探究ConcurrentHashMap中键值对在Segment[]的下标如何确定
查看>>
数据结构与框架-抽象类与接口
查看>>
Openstack Neutron 允许VM流量转发
查看>>
Windows 7/8/8.1 硬盘安装法实现 ubuntu 14.04 双系统
查看>>
nodejs单元测试
查看>>
Docker学习记录3: 搭建 Private Registry
查看>>
HDU Common Subsequence(最长公共子序列)
查看>>
第六十四课、c++中的异常处理(上)
查看>>
12/8团队会议7
查看>>
三分法
查看>>
ubuntun 18.04 安装和配置mysql数据库
查看>>
Javascript Design Patterns - Js Class
查看>>
计算机图形学 补 光线跟踪
查看>>
SDL1.3(C语言)程序移植LINUX。。。
查看>>
献给即将27岁的我
查看>>
spring整合logback配置文件
查看>>
iOS学习笔记31-多线程深入
查看>>