涉及知识点有canvas在移动端的适配及清晰度调整,画还是非常简单的效果如图
大概的思路是:canvas的width及height使用rem作单位来实现适配,当然也可以通过屏幕计算比例来设置宽高
另外一个点是,上图是由两个圆堆叠而成的,中间的文字也是利用canvas画出来的
具体代码如下:
// 画环
drawMulCircle (canvas_id, proportion,total) {
var canvas = document.getElementById(canvas_id)
if (canvas.getContext) {
var ctx = canvas.getContext('2d')
// 处理手机端显示模糊问题
var devicePixelRatio = window.devicePixelRatio || 1
// 浏览器在渲染canvas之前存储画布信息的像素比
var backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1
// canvas的实际渲染倍率
var ratio = devicePixelRatio / backingStoreRatio
// 宽高可以传入
canvas.style.width = '2rem'
canvas.style.height = '2rem'
// 重新设置宽高解决模糊问题
canvas.width = canvas.width * ratio
canvas.height = canvas.height * ratio
// 获取宽高
var w = canvas.width
var h = canvas.height
// 弧度有关计算
var rad = Math.PI * 2 / 100
var start = 60 * Math.PI / 180
var init = Math.PI / 2
var sum = 0
// 此处多画一个的原因在于没有比例时的显示
this.generateProportion(ctx, w, 0, 2*Math.PI,'#eee')
// 绘制
for(let i = 0; i < proportion.length; i++) {
sum += proportion[i].num
var end = sum == 0 ? start : init + sum * rad
this.generateProportion(ctx, w, start, end, proportion[i].color)
start = end
}
this.generateInnerProportion(ctx,w,h,total)
}
},
generateProportion (ctx, w, start, end, color) {
ctx.save()
ctx.beginPath()
ctx.moveTo(w/2, w/2)
ctx.arc(w/2, w/2, w/2, start, end, false)
ctx.fillStyle = color
ctx.fill()
ctx.closePath()
ctx.restore()
},
generateInnerProportion (ctx, w, h, total) {
var font_size = 0
ctx.save()
ctx.beginPath()
ctx.arc(w/2, w/2, w/2 * 3 / 4, 0, Math.PI * 2, false)
ctx.fillStyle = 'white'
ctx.fill()
ctx.fillStyle = '#666'
if (this.tools.isMobile()) {
font_size = '2em'
} else {
font_size = '14px'
}
ctx.font = font_size + " PingFangSC-Regular Arial"
ctx.fillText(total + '次',(w - ctx.measureText(total + '次').width) / 2, h / 2 - (w/2) / 10)
ctx.fillText('沟通标记', (w - ctx.measureText('沟通标记').width) / 2, h / 2 + (w/2) / 10 + 10)
ctx.closePath()
ctx.restore()
},
pieChart (proportion, total) {
this.drawMulCircle('canvas', proportion, total)
},
样式跟布局就省了