使用canvas绘制圆弧动画
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/j_bleach/article/details/86365888
效果预览
canvas 绘制基本流程
初始画布
对于canvas的绘制,首先需要在html内指定一块画布,即<canvas></canvas>
, 可以看做是在PS中新建一个空白文档,之后所有的操作都将呈现在这个文档之上,与PS的区别是,canvas本身没有图层的特性,当需要展示不同维度的视图时,需要交由html的位置关系来解决。
canvas标签上,值得一提的就是width和height两个属性,这两个属性代表着画布的宽高,与canvas样式上的宽高有很大区别。在浏览器当中,看到的图形绘制大小,本身是由canvas.style.width/canvas.style.height决定的,他们决定了canvas这个dom元素的大小关系,而canvas.width和canvas.height决定的是canvas内部图形的大小关系。当这两个宽高比不同时,就会产生视觉上的形变。即,把canvas.style.height放大为2倍时,显示效果会被拉伸:
当不设置样式宽高时,浏览器中canvas大小由画布大小决定(在实际开发中,碰到一个例外,是在使用mapbox时,绘制map的标签如果只设置canvas画布大小时,在ios移动端的浏览器上显示异常,PC正常)。
获取上下文
所谓上下文,代表的就是一个环境,在这个环境当中你可以获取到相关的方法,变量。程序中有上下文,html的媒体中也有上下文,比如音频上下文(AudioContext),只有拿到了上下文,才能进行相关的方法操作,canvas也是如此,canvas上的方法都是借由canvas上下文得到。
<canvas id="leftCanvas"></canvas>
const canvasL = document.getElementById("leftCanvas");
const cxtL = canvasL.getContext("2d");
配置线条
本次圆弧动画需要用到的上下文属性有:
- lineCap 线段端点形状,本次设置为round
- lineWidth 线宽
- strokeStyle 线条填充颜色
- clearRect 清除画布里面的内容
- beginPath 在画布上开始一段新的路径
- arc 圆弧绘制参数配置
- stroke 绘制
角度计算
角度计算之前,先介绍一下绘制圆弧的基础api arc。
ctx.arc(x, y, radius, startAngle, endAngle [, anticlockwise]);
这个函数可以接收6个参数,前五个为必填,分别为圆心x坐标,圆心y坐标,半径,起始角度,结束角度,方向(默认为false,顺时针)。
回到圆弧动画,当前动画有两段,以顺时针方向这段为例。
- x, y:在canvas当中,坐标系默认以左上角为原点,如果想让圆弧动画以画布中心点旋转,可以将圆心点设置为画布中心点,即画布长宽的1/2,假设设置的画布长宽均为100,那么圆心点的坐标即为(50, 50),这个圆就绘制在了画布中间。
- radius:为了不与画布产生切角,半径设置比画布一般略小,。
- startAngle:起始角度为正北方向,而圆以x轴水平方向为0度,因此将起始点逆时针旋转90°,即:-1 / 2 * Math.PI。
- endAngle:因为圆弧长度为30°,终点角度在起始角度的基础上增加 1 / 6 * Math.PI。
顺时针方向圆弧初始配置为:
cxtL.arc(WidthL / 2, HeightL / 2, WidthL / 2 - 5, -1 / 2 * Math.PI, 1 / 6 * Math.PI, false);
开启动画
window.requestAnimationFrame()
借助requestAnimationFrame,来对canvas圆弧进行不断的重绘,每次重绘canvas之前清空画布,每轮动画方向角偏移2°,即2 / 180 * Math.PI,动画结束的标记为圆弧终点的角度,移动至3 / 2 * Math.PI,当满足条件时,调用window.cancelAnimationFrame(animationId)取消动画。
屏幕适配
通过进入html后,动态获取视口,来设置canvas宽高,比如希望画布大小为窗口的宽度的15%,可以通过
const clientWidth = document.documentElement.clientWidth;
const canvasWidth = Math.floor(clientWidth * 0.15);
const canvasL = document.getElementById("leftCanvas");
canvasL.setAttribute("width", canvasWidth + "px");
这样就可以使画布适应不同屏幕大小。
以下为未整理代码,较乱,仅供参考。
https://codepen.io/jbleach/pen/KbryLW
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3h0i9e4btmasg
- Java中使用Hibernate系列之加载并存储对象学习(第三节)
- Java中使用Hibernate系列之启动方法学习(第二节)
- Java中使用Hibernate系列之映射文件学习(第一节)
- Java中为图片添加水印效果的方法——实例代码
- Java中使用Hibernate系列之过滤器(filters)学习
- Node.js中的内存泄漏分析
- Java实现把整数转换为英语单词的方法,实用代码
- Chrome XSS审计之SVG标签绕过
- Java实现的一个简单计算器,有字符分析功能
- Java中实现判断括号是否有效的方法,实用代码
- Java中使用栈实现一个队列,实用代码
- NDK 的开发流程
- 蜜罐背后的影子系统探秘
- Oracle 免费的数据库--Database 快捷版 11g 安装使用与SOD框架对Oracle的CodeFirst支持
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 基于决策树的工业数据分类——数据智能
- Kestrel的ListenAnyIP和ListenLocalhost的区别
- 【为宏正名】什么?我忘了去上“数学必修课”!
- 第6章 Jenkins系统权限划分与授权管理
- Python爬虫新手教程: 知乎文章图片爬取器
- 《重构-代码整洁之道TypeScript版》第4天
- C++基础 杂记(一)
- 一种Cortex-M内核中的精确延时方法(ns级别)
- 算法集锦(17)|自然语言处理| 比特币市场情绪分析算法
- Linux匿名管道及实例
- 查找算法笔记(C++版)
- C++基础 指针使用注意
- FreeRTOS移植-基于STM32F407
- 感知机的股票预测算例及python代码实现 | 山人聊算法 | 5th
- C++基础 智能指针