这两天闲着没事,就看了一下canvas,以前组里有过类似的需求,自己是菜鸡,没能做,这两天正好做了一下,感觉挺简单的!没想的那么复杂,里面代码有些地方挺啰嗦,等以后再继续改进吧!
先看一下实现的效果图:
这个图分两步来完成:
1 绘制六边形
2 绘制数据填充区
首先看一下六边形的坐标分析:下面这篇文章也对战力图进行了描述,而且挺详细的【刚发现....】
https://www.jianshu.com/p/43a39365b6f2
我的实现代码跟他的不太一样,但是大致思想都是相同的,下面直接上代码:
<html>
<head>
<title>Canvas tutorial</title>
<style type="text/css">
</style>
</head>
<body style="width:100%;height:300%;position: relative;margin: 0;padding: 0;">
<!-- <input id="save" type="submit" value="保存">
<input id="restore" type="reset" value="恢复"> -->
<canvas id="canvasLinear" width="800" height="800"></canvas>
</body>
<script type="text/javascript">
var canvas = document.querySelector('canvas');
var context = canvas.getContext('2d');
//绘制六边形
var pointArr = [];
for (let i=0;i<6;i++){
pointArr[i]={};
pointArr[i].x = 250 + 100 * Math.round(Math.sin(Math.PI * 60 * i / 180) * 1000000) / 1000000;//这里这样写,是因为浮点数计算误差问题
pointArr[i].y = 250 + 100 * Math.round(Math.cos(Math.PI * 60 * i / 180) * 1000000) / 1000000;
pointArr[i].text = 'text' + i;
if (i == 0) {
context.beginPath();
context.moveTo(pointArr[i].x, pointArr[i].y);
}
if (i < 6 && i != 0) {
context.lineTo(pointArr[i].x, pointArr[i].y);
continue;
}
}
context.closePath();
context.stroke();
//绘制文本
context.font = '14px arial';
for (let j=0; j<6; j++) {
if (j == 0) {
// context.textAlign;
context.fillText(pointArr[j].text,pointArr[j].x - 13, pointArr[j].y + 15);
}else if (j == 4 || j == 5) {
context.fillText(pointArr[j].text,pointArr[j].x - 35, pointArr[j].y + 6);
}else if (j == 3){
context.fillText(pointArr[j].text, pointArr[j].x - 13, pointArr[j].y - 6);
}else {
context.fillText(pointArr[j].text, pointArr[j].x + 3, pointArr[j].y - 3);
}
}
//绘制对角线
context.beginPath();
for (let k=0; k<3; k++) {
context.moveTo(pointArr[k].x, pointArr[k].y);
context.lineTo(pointArr[k+3].x, pointArr[k+3].y);
}
context.stroke();
//封装外部接口,输入为
function drawMap(array) {
var pointInnerMap = [];
for(let i=0; i<6; i++) {
pointInnerMap[i]={};
pointInnerMap[i].x = 250 + array[i] * Math.round(Math.sin(Math.PI * 60 * i / 180) * 1000000) / 1000000;
pointInnerMap[i].y = 250 + array[i] * Math.round(Math.cos(Math.PI * 60 * i / 180) * 1000000) / 1000000;
pointInnerMap[i].text = 'text' + i;
//这里直接画圆为什么不行????????????????
// context.fillStyle = 'red';
// context.beginPath();
// context.arc(pointInnerMap[i].x, pointInnerMap[i].y, 3, 0, Math.PI * 2);
// context.fill();
// context.closePath();
// context.stroke();
if (i == 0) {
context.beginPath();
context.moveTo(pointInnerMap[i].x, pointInnerMap[i].y);
}
if (i < 6 && i != 0) {
context.lineTo(pointInnerMap[i].x, pointInnerMap[i].y);
continue;
}
}
context.globalAlpha = 0.5;
context.fillStyle = 'red';
context.lineWidth = 3;
context.strokeStyle = 'red';
context.fill();
context.closePath();
context.stroke();
}
function drawMapCir(array) {
var pointInnerMap = [];
for(let i=0; i<6; i++) {
pointInnerMap[i]={};
pointInnerMap[i].x = 250 + array[i] * Math.round(Math.sin(Math.PI * 60 * i / 180) * 1000000) / 1000000;
pointInnerMap[i].y = 250 + array[i] * Math.round(Math.cos(Math.PI * 60 * i / 180) * 1000000) / 1000000;
context.fillStyle = 'red';
context.globalAlpha = 1;
context.beginPath();
context.arc(pointInnerMap[i].x, pointInnerMap[i].y, 3, 0, Math.PI * 2);
context.fill();
context.closePath();
context.stroke();
}
}
var array = [60,50,40,20,60,60];
// 画战力值区域图
drawMap(array);
// 画红心圆圈;
drawMapCir(array);
</script>
</html>