可视化系列讲解:canvas的动画实现

news2024/12/25 22:21:41

文章目录

  • 一、Canvas动画
      • 1.1 Canvas绘图都是通过JavaScript 去操控的,如要实现一些交互性动画是相当容易的。那Canvas是如何做一些基本动画的?
      • 1.2 Canvas 画出一帧动画的基本步骤(如要画出流畅动画,1s 需绘60帧):
  • 二、Canvas-绘制秒针-setInterval实现
      • 2.1 setTimout定时器的缺陷
  • 三、Canvas-绘制秒针--requestAnimationFrame实现
      • 3.1 requestAnimationFrame函数
  • 四、其他动画案例


一、Canvas动画

1.1 Canvas绘图都是通过JavaScript 去操控的,如要实现一些交互性动画是相当容易的。那Canvas是如何做一些基本动画的?

◼ canvas可能最大的限制就是图像一旦绘制出来,它就是一直保持那样了。
◼ 如需要执行动画,不得不对画布上所有图形进行一帧一帧的重绘(比如在1秒绘60帧就可绘出流畅的动画了)。
◼ 为了实现动画,我们需要一些可以定时执行重绘的方法。然而在Canvas中有三种方法可以实现:分别为 setInterval 、 setTimeout 和 requestAnimationFrame 三种方法来定期执行指定函数进行重绘。

1.2 Canvas 画出一帧动画的基本步骤(如要画出流畅动画,1s 需绘60帧):

◼ 第一步:用 clearRect 方法清空 canvas ,除非接下来要画的内容会完全充满 canvas(例如背景图),否则你需要清空所有。
◼ 第二步:保存 canvas 状态,如果加了 canvas 状态的设置(样式,变形之类的),又想在每画一帧之时都是原始状态的话,
你需要先保存一下。
◼ 第三步:绘制动画图形(animated shapes) ,即绘制动画中的一帧。
◼ 第四步:恢复 canvas 状态,如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧。

二、Canvas-绘制秒针-setInterval实现

2.1 setTimout定时器的缺陷

setTimeout定时器不是非常精准的,因为setTimeout的回调函数是放到了宏任务中等待执行。
◼ 如果微任务中一直有未处理完成的任务,那么setTimeout的回调函数就有可能不会在指定时间内触发回调
◼ 如果想要更加平稳和更加精准的定时执行某个任务的话,可以使用requestAnimationFrame函数。

在这里插入图片描述

<!DOCTYPE html>
<html lang="zh-CH">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    * {
      margin: 0;
      padding: 0;
    }
    body {
      padding: 100px;
      margin: auto;
      background-image: url(../images/grid.png);
    }
    canvas {
      background-color: rgba(255, 0, 0, 0.1);
    }
  </style>
</head>
<body>
  
  <!-- 如果不给宽高 默认宽300px 高150px -->
  <canvas id="box" width="300" height="300">
    您的浏览器不兼容Canvas,请升级浏览器
  </canvas>

  <script>
    // 这个函数就是动画的一帧
    function draw(ctx, count) {
      // 清空画布
      ctx.clearRect(0, 0, 300, 300)
      ctx.save()
      // 绘图
      ctx.translate(100, 100)
      // Math.PI * 2 圆
      // Math.PI * 2 / 60 把圆分为60份
      ctx.rotate(Math.PI * 2 / 60 * count)
      ctx.lineWidth = 6
      ctx.lineCap = 'round'
      ctx.strokeStyle = 'green'
      ctx.beginPath()
      ctx.moveTo(0, 0)
      ctx.lineTo(0, -80)
      ctx.stroke()
      ctx.restore()
    }
    window.onload = function() {
      const canvasEl = document.getElementById('box')
      if (!canvasEl.getContext) return
      let ctx = canvasEl.getContext('2d')
      let count = 0
      draw(ctx, count)

      setInterval(() => {
        count++
        if (count >= 60) {
          count = 0
        }
        draw(ctx, count)
      }, 1000);
    }
  </script>
</body>
</html>

三、Canvas-绘制秒针–requestAnimationFrame实现

3.1 requestAnimationFrame函数

告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用该函数的回调函数来更新动画。
◼ 该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
◼ 若想在浏览器下次重绘之前继续更新下一帧动画,那么在回调函数自身内必须再次调用 requestAnimationFrame()
◼ 通常每秒钟回调函数执行 60 次左右,也有可能会被降低。

<!DOCTYPE html>
<html lang="zh-CH">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    * {
      margin: 0;
      padding: 0;
    }
    body {
      padding: 100px;
      margin: auto;
      background-image: url(../images/grid.png);
    }
    canvas {
      background-color: rgba(255, 0, 0, 0.1);
    }
  </style>
</head>
<body>
  
  <!-- 如果不给宽高 默认宽300px 高150px -->
  <canvas id="box" width="300" height="300">
    您的浏览器不兼容Canvas,请升级浏览器
  </canvas>

  <script>
    // 这个函数就是动画的一帧
    function draw(ctx) {
      let second = new Date().getSeconds()
      ctx.clearRect(0, 0, 300, 300)
      ctx.save()
      ctx.translate(100, 100)
      ctx.rotate(Math.PI * 2 / 60 * second)
      ctx.lineWidth = 6
      ctx.lineCap = 'round'
      ctx.strokeStyle = 'green'
      ctx.beginPath()
      ctx.moveTo(0, 0)
      ctx.lineTo(0, -80)
      ctx.stroke()
      ctx.restore()
    
      requestAnimationFrame(() => {
        draw(ctx)
      })
    }

    window.onload = function() {
      const canvasEl = document.getElementById('box')
      if (!canvasEl.getContext) return
      let ctx = canvasEl.getContext('2d')
      requestAnimationFrame(() => {
        draw(ctx)
      })
    }
  </script>
</body>
</html>

四、其他动画案例

案列地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/135192.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【回答问题】ChatGPT上线了!推荐30个以上比较好的自然语言处理模型

【回答问题】ChatGPT上线了&#xff01;推荐40个以上比较好的自然语言处理模型以及github源码&#xff1f; BERT (Bidirectional Encoder Representations from Transformers): https://github.com/google-research/bert GPT (Generative Pre-training Transformer): https:/…

Taro笔记

Taro官网:https://nervjs.github.io/taro-docs/docs/ Taro简介 可使用React、Vue等框架开发跨端开发框架,一套代码编译到多端,使用Taro,只书写一套代码,再通过Taro的编译工具,将源代码分别编译出可以在不同端(微信小程序、H5、RN等)运行的代码。Taro 核心转化图 Taro使…

数据链路层重点总结

文章目录前言一、MAC地址二、一跳一跳的网络传输三、以太网四、ARP协议4.1 ARP协议的作用4.2 ARP协议的工作流程五、MTU5.1 什么是MTU5.2 MTU对IP协议的影响5.3 MTU对UDP协议的影响5.4 MTU对于TCP协议的影响总结前言 又是新的一年&#xff0c;展望2023年&#xff0c;博主给大家…

可视化系列讲解:canvas的进阶使用(颜色和样式设置,绘制文本,绘制图片)

文章目录一、Canvas的颜色和样式设置1.1 颜色&#xff08;不设置默认黑色&#xff09;1.2 透明度 Transparent1.3 线型 Line styles二、Canvas绘制文本2.1 文本的样式&#xff08;需在绘制文本前调用&#xff09;2.2 fillText(text, x, y [, maxWidth])2.3 strokeText(text, x,…

回首2022,展望2023

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小黄&#xff0c;独角兽企业的Java开发工程师&#xff0c;CSDN博客专家&#xff0c;Java领域新星创作者&#x1f4d5;系列专栏&#xff1a;Java设计模式、数据结构和算法、Kafka从入门到成神、Kafka从成神到…

【自学Java】Java数据类型

Java数据类型 Java数据类型 数据类型在编程语言中占有重要的地位。Java 的数据类型分为基本数据类型和引用数据类型。 Java基本类型 Java 基本数据类型包括&#xff1a;boolean&#xff0c;byte&#xff0c;char&#xff0c;short&#xff0c;int&#xff0c;long&#xff…

node.js中fs\path\http模块的使用

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;Node.js的fs\path\http模块的使用&#xff0c;模块化开发概念 目录 一、node.js概念与作…

dubbo源码实践-serialize层的例子

目录 1 serialize层概述 2 序列化的简单例子 2.1 项目截图 2.2 三个类的源码 2.2.1 ABC是实体类 2.2.2 TestSeriarsWrite把ABC对象序列化到文件中 2.2.3 TestSeriarsRead从文件中读取ABC对象 2.2.4 运行结果 3 展示一个通过URL属性动态切换序列化实现类的例子 3.1 原理分…

为什么云并不总是足够的

虽然人们普遍认为云是未来&#xff0c;但云仍然有多种形式&#xff0c;理解每种形式的各自优点至少可以说是模糊的。 行业分析师有时会争论单租户与多租户部署的优缺点。虽然单租户部署在最近可能是某些组织的可行解决方案&#xff0c;但多租户部署为希望实现运营现代化的组织…

ansible(第一天)

第一章&#xff1a;认识ansible 一、ansible的安装与介绍 1.Ansible软件及公司 ansible是个什么东西呢&#xff1f;官方的title是“Ansible is Simple IT Automation”——简单的自动化IT工具。 这个工具的目标有这么几项&#xff1a;让我们自动化部署APP&#xff1b;自动化…

Maven总结 - 一、初探-项目构建

maven不仅仅是一款管理jar包的工具&#xff0c;更重要的是一款项目构建的工具 maven下载网站&#xff1a;https://maven.apache.org/ maven搜索网站&#xff1a;http://mvn.coderead.cn/ 一、项目构建 给你一套源代码&#xff0c;你怎么能跑起来&#xff1f; 不能把&#xff0…

日期的格式化与解析

格式化&#xff1a;日期 —> 字符串 解析&#xff1a; 字符串 —> 日期 这里指的是日期的显式格式化和解析 DATE_FORMAT(date,fmt) 按照字符串fmt格式化日期date值 TIME_FORMAT(time,fmt) 按照字符串fmt格式化时间time值 GET_FORMAT(date_type,format_type) 返回…

1、影像组学基础知识

一、What is Radiomics? 提出影像组学论文&#xff1a; **主要目的&#xff1a;**说明肿瘤在时间和空间上的异质性&#xff0c;可以用影像组学说明 时间上的异质性&#xff1a;同一个人同一个肿瘤在不同时间段的表现 空间上的异质性&#xff1a;同一肿瘤在不同个体上的表…

适合编程初学者的开源项目:小游戏2048(Vue版)

目标 为编程初学者打造入门学习项目&#xff0c;使用各种主流编程语言来实现。 2048游戏规则 一共16个单元格&#xff0c;初始时由2或者4构成。 1、手指向一个方向滑动&#xff0c;所有格子会向那个方向运动。 2、相同数字的两个格子&#xff0c;相遇时数字会相加。 3、每次…

分布式存储系统 Ceph 实战操作

文章目录一、概述二、cephadm 工具的使用1&#xff09;cephadm 工具的介绍2&#xff09;cephadm 安装3&#xff09;cephadm 常用命令使用4&#xff09;启用 ceph shell三、ceph 命令使用1&#xff09;添加新节点2&#xff09;使用 ceph 安装软件3&#xff09;主机操作1、列出主…

Python绘制表白代码,又是一个表白神器(赠源码,文章内有效果展示)

前言 嗨呀&#xff0c;又是我&#xff0c;又给你们带来了表白的代码 之前发了那些 照片里面加文字的…还有烟花…还有跳动爱心…emm你们也可以去看看哦 今天带来的这个&#xff0c;也是很不错哦 只不过它出来的有些慢&#xff0c;我这里先给你们看看这个效果图吧 效果展示…

蓝桥集训(附加面试题)第九天

本文来源于算法面试题特训专栏&#xff0c;这里有大量专业性的算法题比如&#xff08;动态规划21天&#xff0c;大厂特训28天等等&#xff09; 欢迎大家一起学习。 链接&#xff1a;传送门 目录标题导读Java蓝桥集训面试题点击直接资料领取导读 在刚刚结束的 每日算法&面…

【大数据】CentOS7 安装 Hive(附有Hive基本使用-练习)

文章目录1.安装并配置Hive处理hive中文乱码2.Hive基本操作3.将本地文件导入Hive练习1练习21.安装并配置Hive 下载 利用Xshell中的xftp&#xff0c;将apache-hive导入到CentOS7的/opt/source文件夹下 解压 解压命令&#xff1a;tar -zxvf apache-hive-1.2.1-bin.tar.gz 重命名…

【人工智能】基于五笔字型规范和人工神经网络的简中汉字识别【一】

导语:看到一则旧闻,读了一篇论文,产生一些思考,完成一个模型 前言及项目简介 一、旧闻二、论文三、思考四、模型一、旧闻 大概去年十一月初吧,博主还在进行紧张的研考冲刺阶段。学校下达毕设选题任务,仓促间就要决定毕设内容,并无思路,不免有些迷茫:既担心选题过于简…

Unc0ver 8.0.0 更新:支持 iOS 14.6-14.8、A12-A13 iPhone 越狱

今日&#xff0c;越狱工具 unc0ver 发布了全新的 8.0.0 版本。现在支持 iOS 14.6-14.8 版本越狱&#xff0c;需要搭载 A12-A13 芯片的 iPhone 手机。 本次越狱支持的系统版本&#xff1a;iOS 14.6、iOS 14.7、iOS 14.7.1、iOS 14.8这4种版本&#xff0c;iOS 15.0以上系统请等待…