首页 > 专栏 > 前端 > 文章详情
可视化系列:Canvas 如何实现动画 发布于:2023-03-04 10:36:37   来源:你的微笑、暖暖的   查看:61  讨论:0
一、Canvas动画Rwm易塔云建站-模板下载,web开发资源,技术博客
Rwm易塔云建站-模板下载,web开发资源,技术博客
1.1 Canvas绘图都是通过JavaScript 去操控的,如要实现一些交互性动画是相当容易的。那Canvas是如何做一些基本动画的?Rwm易塔云建站-模板下载,web开发资源,技术博客
◼ canvas可能最大的限制就是图像一旦绘制出来,它就是一直保持那样了。Rwm易塔云建站-模板下载,web开发资源,技术博客
◼ 如需要执行动画,不得不对画布上所有图形进行一帧一帧的重绘(比如在1秒绘60帧就可绘出流畅的动画了)。Rwm易塔云建站-模板下载,web开发资源,技术博客
◼ 为了实现动画,我们需要一些可以定时执行重绘的方法。然而在Canvas中有三种方法可以实现:分别为 setInterval 、 setTimeout 和 requestAnimationFrame 三种方法来定期执行指定函数进行重绘。Rwm易塔云建站-模板下载,web开发资源,技术博客
Rwm易塔云建站-模板下载,web开发资源,技术博客
1.2 Canvas 画出一帧动画的基本步骤(如要画出流畅动画,1s 需绘60帧):Rwm易塔云建站-模板下载,web开发资源,技术博客
◼ 第一步:用 clearRect 方法清空 canvas ,除非接下来要画的内容会完全充满 canvas(例如背景图),否则你需要清空所有。Rwm易塔云建站-模板下载,web开发资源,技术博客
◼ 第二步:保存 canvas 状态,如果加了 canvas 状态的设置(样式,变形之类的),又想在每画一帧之时都是原始状态的话,Rwm易塔云建站-模板下载,web开发资源,技术博客
你需要先保存一下。Rwm易塔云建站-模板下载,web开发资源,技术博客
◼ 第三步:绘制动画图形(animated shapes) ,即绘制动画中的一帧。Rwm易塔云建站-模板下载,web开发资源,技术博客
◼ 第四步:恢复 canvas 状态,如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧。
Rwm易塔云建站-模板下载,web开发资源,技术博客
Rwm易塔云建站-模板下载,web开发资源,技术博客
二、Canvas-绘制秒针-setInterval实现Rwm易塔云建站-模板下载,web开发资源,技术博客
Rwm易塔云建站-模板下载,web开发资源,技术博客
2.1 setTimout定时器的缺陷Rwm易塔云建站-模板下载,web开发资源,技术博客
◼ setTimeout定时器不是非常精准的,因为setTimeout的回调函数是放到了宏任务中等待执行。Rwm易塔云建站-模板下载,web开发资源,技术博客
◼ 如果微任务中一直有未处理完成的任务,那么setTimeout的回调函数就有可能不会在指定时间内触发回调。Rwm易塔云建站-模板下载,web开发资源,技术博客
◼ 如果想要更加平稳和更加精准的定时执行某个任务的话,可以使用requestAnimationFrame函数。
Rwm易塔云建站-模板下载,web开发资源,技术博客
Rwm易塔云建站-模板下载,web开发资源,技术博客
 
Rwm易塔云建站-模板下载,web开发资源,技术博客
           
// const image = new Image();Rwm易塔云建站-模板下载,web开发资源,技术博客
// image.src = "./bg.png";Rwm易塔云建站-模板下载,web开发资源,技术博客
function draw(context, count){Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.clearRect(0, 0, 320, 320);Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.save();Rwm易塔云建站-模板下载,web开发资源,技术博客
    // 与restore 必须成对出现Rwm易塔云建站-模板下载,web开发资源,技术博客
    // 画秒针Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.translate(160, 160);Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.rotate(Math.PI * 2 / 60 * count);Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.beginPath();Rwm易塔云建站-模板下载,web开发资源,技术博客
    // 如果使用clearRect(),后面新绘制的路径,必须加 beginPathRwm易塔云建站-模板下载,web开发资源,技术博客
    context.moveTo(-15, 0);Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.lineTo(105, 0);Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.lineWidth = 6;Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.lineCap = "round";Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.strokeStyle = "red";Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.stroke();Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.restore();Rwm易塔云建站-模板下载,web开发资源,技术博客
    // 与save必须成对出现Rwm易塔云建站-模板下载,web开发资源,技术博客
}Rwm易塔云建站-模板下载,web开发资源,技术博客
window.onload = function () {Rwm易塔云建站-模板下载,web开发资源,技术博客
    const canvas = document.getElementById("canvas");Rwm易塔云建站-模板下载,web开发资源,技术博客
    const context = canvas.getContext("2d");Rwm易塔云建站-模板下载,web开发资源,技术博客
    let count = 0;Rwm易塔云建站-模板下载,web开发资源,技术博客
    // context.drawImage(image, 0, 0);Rwm易塔云建站-模板下载,web开发资源,技术博客
    draw(context, count);Rwm易塔云建站-模板下载,web开发资源,技术博客
    setInterval(() => {Rwm易塔云建站-模板下载,web开发资源,技术博客
        if (count > 60) {Rwm易塔云建站-模板下载,web开发资源,技术博客
            count = 0;Rwm易塔云建站-模板下载,web开发资源,技术博客
        }Rwm易塔云建站-模板下载,web开发资源,技术博客
        count++;Rwm易塔云建站-模板下载,web开发资源,技术博客
        draw(context, count);Rwm易塔云建站-模板下载,web开发资源,技术博客
    }, 1000)Rwm易塔云建站-模板下载,web开发资源,技术博客
}
三、Canvas-绘制秒针-requestAnimationFrame实现
function draw(context, count){Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.clearRect(0, 0, 320, 320);Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.save();     // 与restore 必须成对出现Rwm易塔云建站-模板下载,web开发资源,技术博客
    // 画秒针Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.translate(160, 160);Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.rotate(Math.PI * 2 / 60 * count);Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.beginPath();    // 如果使用clearRect(),后面新绘制的路径,必须加 beginPathRwm易塔云建站-模板下载,web开发资源,技术博客
    context.moveTo(-15, 0);Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.lineTo(105, 0);Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.lineWidth = 6;Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.lineCap = "round";Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.strokeStyle = "red";Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.stroke();Rwm易塔云建站-模板下载,web开发资源,技术博客
    context.restore();  // 与save必须成对出现Rwm易塔云建站-模板下载,web开发资源,技术博客
}Rwm易塔云建站-模板下载,web开发资源,技术博客
window.onload = function () {Rwm易塔云建站-模板下载,web开发资源,技术博客
    const canvas = document.getElementById("canvas");Rwm易塔云建站-模板下载,web开发资源,技术博客
    const context = canvas.getContext("2d");Rwm易塔云建站-模板下载,web开发资源,技术博客
    let count = 0;Rwm易塔云建站-模板下载,web开发资源,技术博客
    draw(context, count);Rwm易塔云建站-模板下载,web开发资源,技术博客
    function anim(){Rwm易塔云建站-模板下载,web开发资源,技术博客
        const count = new Date().getSeconds();Rwm易塔云建站-模板下载,web开发资源,技术博客
        // 此时浏览器根据刷新频率,每秒60次刷新Rwm易塔云建站-模板下载,web开发资源,技术博客
        // 这60次刷新都是一个count值,获取的是当下的北京时间,是准确的Rwm易塔云建站-模板下载,web开发资源,技术博客
        console.log("count is", count)Rwm易塔云建站-模板下载,web开发资源,技术博客
        draw(context, count);Rwm易塔云建站-模板下载,web开发资源,技术博客
        window.requestAnimationFrame(anim)Rwm易塔云建站-模板下载,web开发资源,技术博客
    }Rwm易塔云建站-模板下载,web开发资源,技术博客
    window.requestAnimationFrame(anim)Rwm易塔云建站-模板下载,web开发资源,技术博客
}

评论

  • 匿名