效果预览
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/pe…