canvas 绘制动态雷达图
最近收到一个需求,需要做一个预定的动态雷达图,于是绞尽脑汁,基于canvas 终于实现如图的效果:
图片效果:
我是基于vue 来实现的,现在让我们看看具体是如何实现的:
1.需要使用canvas 画出静止的样式
这里就需要用到canvas 的知识点,实现的代码如下:
this.time += 1
this.ctx.drawImage(this.canvasImgBg, -(this.ww / 2) - 15, -(this.wh / 2) - 20, this.ww + 10, this.wh + 27)
this.ctx.beginPath()
this.ctx.rect(-2000, -2000, 4000, 4000)
this.ctx.fill()
this.ctx.strokeStyle = 'rgba(255,255,255,0.1)'
this.ctx.strokeStyle = this.Color(1)
var r = this.ww / 2.29
var line_deg = (this.time / 2) % 360
var line_deg_len = 100
for (var i = 0; i < line_deg_len; i++) {
// var deg = (time-i);
var deg1 = line_deg - i - 1
var deg2 = line_deg - i
var point1 = this.Point(r, deg1)
var point2 = this.Point(r, deg2)
var opacity = 1 - i / line_deg_len - 0.3
if (i === 0) opacity = 1
this.ctx.beginPath()
this.ctx.fillStyle = 'white'
this.ctx.fillStyle = this.Color(opacity)
this.ctx.moveTo(0, 0)
this.ctx.lineTo(point1.x, point1.y)
this.ctx.lineTo(point2.x, point2.y)
// ctx.stroke();
this.ctx.fill()
}
2.画出随机位置的图标和名字
const radius = this.ww / 42
this.globalRadius = radius
this.originEnemiesList.map(obj => {
const avatar = new Image()
avatar.src = obj.userInfo.avatar
var obj_point = this.Point(obj.r, obj.deg)
this.ctx.save()
this.ctx.beginPath()
this.ctx.arc(obj_point.x, obj_point.y, radius, 0, 2 * Math.PI)
obj.point = obj_point
this.ctx.textAlign = 'center'
this.ctx.font = 'bold 12px PingFang SC'
this.ctx.fillStyle = this.Color1(obj.opacity)
this.ctx.fillText(obj.userInfo.fullName, obj_point.x, obj_point.y + radius + 20)
this.ctx.clip() // 裁剪上面的圆形
this.ctx.globalAlpha = obj.opacity
this.ctx.drawImage(avatar, obj_point.x - radius, obj_point.y - radius, 2 * radius, 2 * radius)
this.ctx.restore() // 还原状态
this.ctx.strokeStyle = this.Color1(obj.opacity)
this.ctx.stroke()
if (Math.abs(obj.deg - line_deg) <= 1) {
obj.opacity = 0.8
}
this.ctx.strokeStyle = this.Color1(obj.opacity)
this.ctx.lineWidth = 2
this.ctx.beginPath()
this.ctx.arc(obj_point.x, obj_point.y, (radius + 1) * (1 / (obj.opacity + 0.2)), 0, 2 * Math.PI)
this.ctx.stroke()
})
原理是:当扫描动起来,只有扫过以后,才能出现图标,所以默认一开始的图标都是隐藏的,即透明度为0,故下面的代码就是用来判断是否扫过
if (Math.abs(obj.deg - line_deg) <= 1) {
obj.opacity = 0.8
}
3.让整体动起来
3.联系我
如需完整项目代码,请备注联系我,邮箱1015095073@qq.com