canvas动画及案例

介绍

由于我们是用 JavaScript 去操控 对象,这样要实现一些交互动画也是相当容易的。
可能最大的限制就是图像一旦绘制出来,它就是一直保持那样了。如果需要移动它,我们不得不对所有东西(包括之前的)进行重绘。重绘是相当费时的,而且性能很依赖于电脑的速度。

动画基本步骤

  1. 清空 canvas 除非接下来要画的内容会完全充满 canvas(例如背景图),否则你需要清空所有。最简单的做法就是用 clearRect 方法。
  2. 保存 canvas 状态 如果你要改变一些会改变 canvas 状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,你需要先保存一下。
  3. 绘制动画图形(animated shapes) 这一步才是重绘动画帧。
  4. 恢复 canvas 状态 如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧

更新画布

  1. setInterval(function, delay)(不推荐,不准确,宏任务)
    当设定好间隔时间后,function 会定期执行。

  2. setTimeout(function, delay)(不推荐,不准确,宏任务)
    在设定好的时间之后执行函数

  3. requestAnimationFrame(callback)
    告诉浏览器你希望执行一个动画,并在重绘之前,请求浏览器执行一个特定的函数来更新动画。
    一般每秒钟回调函数执行 60 次

太阳系动画

<script>
        window.onload= function() {
            const canvasEl = document.getElementById('myCanvas')
            if (!canvasEl.getContext) {
                return
            }
            const ctx = canvasEl.getContext('2d')
            let sun = new Image()
            sun.src = '../images/canvas_sun.png'
            let earth = new Image()
            earth.src = '../images/canvas_earth.png'
            let moon = new Image()
            moon.src = '../images/canvas_moon.png'
            requestAnimationFrame(draw)
            // 一秒钟大概重绘60次
            function draw() {
                ctx.clearRect(0,0,300,300)
                ctx.save()
                // 绘制背景
                drawSun()
                // 绘制地球
                drawEarth()
                ctx.restore()
                requestAnimationFrame(draw)
            }
        
            function drawSun() {
                ctx.save()
                ctx.drawImage(sun,0,0)
                // 绘制轨道线
                ctx.translate(150,150)
                ctx.strokeStyle = 'rgba(255,255,255,0.3)'
                ctx.beginPath()
                ctx.arc(0,0,100,0,Math.PI * 2)
                ctx.stroke()
                ctx.restore()
            }
            function drawEarth() {
                ctx.save()
                ctx.translate(150,150)
                // 地球旋转(一分钟一周)
                // 获取当前时间miao 
                let Seconds = new Date().getSeconds()
                let milliseconds = new Date().getMilliseconds()
                // 一周Math.PI * 2
                // 180 Math.PI * 1
                // 一秒:Math.PI * 2 / 60
                // 一毫秒:Math.PI * 2 / 60 / 1000
                ctx.rotate(Math.PI * 2 / 60 * Seconds + Math.PI * 2 / 60 / 1000 * milliseconds)
                ctx.translate(100,0)
                ctx.drawImage(earth,-12,-12)
                
                // 绘制月球
                drawMoon(Seconds,milliseconds)
                // 绘制蒙版
                drawMengban()
                ctx.restore()
            }
            function drawMoon(Seconds,milliseconds) {
                ctx.save()
                // 月球旋转(10s一周)
                // 一秒: Math.PI * 2 / 10
                //一毫秒:Math.PI * 2 / 10 / 1000
                ctx.rotate(Math.PI * 2 / 10 * Seconds + Math.PI * 2 / 10 / 1000 * milliseconds)
                ctx.translate(30,0)
                ctx.drawImage(moon,-3.5,-3.5)
                ctx.restore()
            }
            function drawMengban() {
                ctx.save()
                ctx.fillStyle = 'rgba(0,0,0,0.3)'
                ctx.fillRect(0,-15,40,30)
                ctx.restore()
                
            }
        
        }

        
    </script>

在这里插入图片描述

时钟动画

<body>
  <div class="clock">
    <canvas id="tutorial" width="300" height="300px">
      你的浏览器不兼容Canvas,请升级您的浏览器!
    </canvas>
  </div>
  <script>
    window.onload = function() {
      let canvasEl = document.getElementById('tutorial')
      if(!canvasEl.getContext){
        return
      }
      let ctx = canvasEl.getContext('2d') // 2d | webgl
      requestAnimationFrame(draw)

      /**
       1秒钟会回调 61次
      */
      function draw() {
        ctx.clearRect(0, 0, 300, 300)
        ctx.save()
        let time = new Date()
        let hours = time.getHours()
        let minute = time.getMinutes()
        let second = time.getSeconds()

        // 1.绘制背景(白色圆)
        drawBg()
        // 2.绘制的数字
        drawNumbers()
        // 3.绘制时针
        drawHours(hours, minute, second)
        // 3.绘制分针
        drawMinute(minute, second)
        // 4.绘制秒针
        drawSecond(second)
        // 5.绘制圆心
        drawCircle()
        // 6.画圆上的时针的刻度
        drawHoursTick()
        // 7.画圆上的分针的刻度
        drawMinuteTick()
        ctx.restore()
        requestAnimationFrame(draw)
      }

      function drawBg(){
        ctx.save()
        ctx.translate(150, 150)
        ctx.fillStyle ='white'
        ctx.beginPath()
        ctx.arc(0,0, 130, 0, Math.PI * 2)
        ctx.fill()
        ctx.restore()
      }

      function drawNumbers(){
        ctx.save()
        ctx.translate(150, 150)

        // 开始画 3 数字
        ctx.font = "30px fangsong"
        ctx.textBaseline = 'middle'
        ctx.textAlign = 'center'

        let numbers = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2]
        for(let i =0; i<numbers.length; i++){
          // i = 3 , 0 
          // i = 4 , 占 1份, Math.PI * 2 / 12 * i  
          let x = Math.cos(Math.PI * 2 / 12 * i) * 100
          let y = Math.sin(Math.PI * 2 / 12 * i) * 100
          ctx.fillText(numbers[i], x, y)
        }
        ctx.restore()
      }
      function drawHours(hours, minute, second) {
        ctx.save()
        ctx.translate(150, 150) // 坐标轴原点在园的中心

        // Math.PI * 2 一整个圆
        // Math.PI * 2 / 12  1h
        // Math.PI * 2 / 12 / 60  1min
        // Math.PI * 2 / 12 / 60 / 60  1secon

        // 1h + 1min + 1 second = 弧度?
        ctx.rotate(
          Math.PI * 2 / 12 * hours +
          Math.PI * 2 / 12 / 60 * minute +
          Math.PI * 2 / 12 / 60 / 60 * second 
        )
        ctx.lineWidth = 5
        ctx.lineCap = 'round'
        ctx.beginPath()
        ctx.moveTo(0,0)
        ctx.lineTo(0, -50)
        ctx.stroke()
        ctx.restore()
      }

      function drawMinute(minute, second) {
        ctx.save()
        ctx.translate(150, 150) // 坐标轴原点在园的中心

        // Math.PI * 2 一整个圆
        // Math.PI * 2 / 60  1min
        // Math.PI * 2 / 60 / 60  1sec

        // 59min + 59 second = 弧度?
        ctx.rotate(
          Math.PI * 2 / 60 * minute +
          Math.PI * 2 / 60 / 60 * second 
        )
        ctx.lineWidth = 3
        ctx.lineCap = 'round'
        ctx.beginPath()
        ctx.moveTo(0,0)
        ctx.lineTo(0, -70)
        ctx.stroke()
        ctx.restore()
      }

      function drawSecond(second) {
        ctx.save()
        ctx.translate(150, 150) // 坐标轴原点在园的中心

        // Math.PI * 2 一整个圆
        // Math.PI * 2 / 60   1sec

        // 1 second = 弧度?
        ctx.rotate(
          Math.PI * 2 / 60 * second 
        )
        ctx.strokeStyle = 'red'
        ctx.lineWidth = 2
        ctx.lineCap = 'round'
        ctx.beginPath()
        ctx.moveTo(0,0)
        ctx.lineTo(0, -80)
        ctx.stroke()
        ctx.restore()
      }

      function drawCircle() {
        ctx.save()
        ctx.translate(150, 150)

        ctx.beginPath()
        ctx.arc(0, 0, 8, 0, Math.PI*2)
        ctx.fill()

        ctx.fillStyle = 'gray'
        ctx.beginPath()
        ctx.arc(0, 0, 5, 0, Math.PI*2)
        ctx.fill()

        ctx.restore()
      }

      function drawHoursTick() {
        ctx.save()
        ctx.translate(150, 150)

        for(let j = 0; j< 12 ; j ++){
          ctx.rotate(Math.PI * 2 / 12 )
          ctx.lineWidth = 3
          ctx.beginPath()
          ctx.moveTo(0, -130)
          ctx.lineTo(0, -122)
          ctx.stroke()
        }

        ctx.restore()
      }

      function drawMinuteTick() {
        ctx.save()
        ctx.translate(150, 150)
        for(let j = 0; j< 60 ; j ++){
          ctx.rotate(Math.PI * 2 / 60 )
          ctx.lineWidth = 1
          ctx.beginPath()
          ctx.moveTo(0, -130)
          ctx.lineTo(0, -125)
          ctx.stroke()
        }
        ctx.restore()
      }
    }
  </script>
</body>

在这里插入图片描述

参考

链接: mdn

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: HTML5 Canvas 是一种用于在网页上绘制图形的技术。它允许开发者通过 JavaScript 脚本来创建二维和三维图形,实现交互式图表、游戏和动画等功能。HTML5 Canvas 支持多种绘制方法和功能,如绘制路径、填充颜色、渐变效果、变换、裁剪等,能够满足开发者对图形绘制的各种需求。 开发者可以使用 HTML5 Canvas 来绘制各种图形,如线条、矩形、圆形、文本、图片等。此外,HTML5 Canvas 还支持鼠标和触摸事件的监听,使得开发者可以实现与用户的交互。通过监听事件,开发者可以实现鼠标点击、拖动、缩放等交互行为,为用户提供良好的用户体验。 HTML5 Canvas 的开发详解 PDF 提供了对 HTML5 Canvas 进行全面学习和实践的指导。这本书详细介绍了 HTML5 Canvas 的各种特性和用法,并通过实例讲解了如何使用 HTML5 Canvas 来创建各种图形和动画效果。书中还介绍了一些常见的图形绘制和动画技巧,如绘制路径、使用图案填充、利用渐变效果来实现特殊的图形效果等。 此外,这本书还介绍了如何使用 HTML5 Canvas 结合其他 Web 技术来完成一些实际的开发项目。比如,如何利用 HTML5 CanvasJavaScript 来创建一个简单的游戏,如何使用 CSS3 和 HTML5 Canvas 来实现一个纯 CSS 动画等。这些实例给开发者提供了实践的机会,帮助他们更好地理解和掌握 HTML5 Canvas。 总之,HTML5 Canvas 是一种非常有用和强大的图形绘制技术,而这本开发详解 PDF 则为想要学习和深入了解 HTML5 Canvas 的开发者提供了宝贵的资料和指导。 ### 回答2: HTML5 Canvas开发详解PDF是一本讲解HTML5 Canvas技术的开发手册,该书内容丰富,涵盖了HTML5 Canvas的方方面面。 首先,该书会介绍HTML5 Canvas的基本概念和原理。HTML5 Canvas是一个用于绘制图形的HTML元素,它可以通过JavaScript绘制、填充和操纵图形。本书将详细解释Canvas的API和基本用法,使读者能够理解如何使用Canvas来创建各种图形,包括线条、矩形、圆形等。 其次,该书将深入讲解Canvas的复杂图形绘制和动画效果。它覆盖了各种高级技术,如路径绘制、渐变效果、阴影效果等。读者将学会如何使用这些技术来创建更加复杂和绚丽的图形效果,并且能够运用Canvas动画功能来实现各种生动的动画效果。 此外,该书还将介绍如何在Canvas中处理用户交互。读者将学会如何添加事件监听器来捕捉用户的点击、拖拽等操作,并通过JavaScript代码对其作出反应。这将使开发者能够为Canvas图形添加交互性,使用户能够与图形进行互动。 最后,该书还包含一些实际项目案例和实践指导。通过这些案例,读者可以了解如何将HTML5 Canvas应用于实际开发中,并且通过实践指导能够掌握一些开发技巧和最佳实践。 总之,HTML5 Canvas开发详解PDF是一本全面介绍HTML5 Canvas技术的教程,无论是初学者还是有一定经验的开发者,都能从中获得宝贵的知识和技巧。该书对于想要深入学习和应用HTML5 Canvas的人来说是一本非常有价值的工具书。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值