
需求
- 背景是2层渐变叠加的效果
- 适配不同手机屏幕的宽度,高度是宽度的2/3
- 仪表盘不是半圆,左右多出2个刻度
- 动画效果,刻度变化,数字变化
拿到这个需求的时候,第一反应是第三方库,调研之后,echarts最接近的例子,需求还是比较自定义化,echarts不太满足,只能造(怕)轮(被)子(喷)了。
背景是2层渐变叠加的效果
canvas支持渐变,和css设置挺像
// 创建线性渐变
var grd = ctx.createLinearGradient(0, 0, 200, 0);
grd.addColorStop(0, "blue"); // 第二个参数支持rgba
grd.addColorStop(1, "red");
// 填充渐变
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 150, 80);
考虑到是2层渐变叠加,canvas内部是挤压的(防止图片模糊,canvas进行缩放绘制)
渐变都是放在style上面设置,会导致下载的图片没有渐变效果
<div class="gauge-wrap">
<canvas id="gauge" class="gauge" width="750" height="500"></canvas>
</div>
.gauge-wrap-high{
background: -webkit-linear-gradient(135deg, rgba(255,255,255,0.00) 0%, rgba(255,255,255,0.19) 26%, rgba(255,255,255,0.25) 28%, rgba(255,255,255,0.00) 100%);
}
.gauge-high{
background: -webkit-linear-gradient(90deg, #414141 3%, #030303 100%);
}
适配不同手机屏幕的宽度,高度是宽度的2 / 3 ≈ 0.66
canvas外面div的样式
.gauge-wrap{
height: 66vw;
}
canvas画布大小
const width = 750
const height = width * 2 / 3
仪表盘不是半圆,左右多出2个刻度
从视觉图中数刻度数量,如果正好排好一个圆总共80个刻度
每个刻度的弧度const deg = Math.PI / 40
ctx.rotate(deg)
deg是正数时旋转顺时针方向deg弧度,所以默认顺时针旋转38
个刻度的弧度
动画效果,刻度变化,数字变化
使用window.requestAnimationFrame
进行递归循环,刻度从初始位置按照固定速度递增,数字从0递增
每次重新绘制前需要清空画布ctx.clearRect(0, 0, width, height)
总结
canvas适合于2d的绘制,一旦涉及3d,需要webgl的canvas。