<!DOCTYPE html>
<html style="background:#171B22;width:100%;height:100%;">
<head style="background:#171B22;width:100%;height:100%;">
<meta charset="UTF-8">
<style type="text/css">
#parentt .title:after{
content:"";
height: 9px;
width: 100%;
display: block;
background: -webkit-radial-gradient(#32E6F3 5%, #182B48 20%, #171B22 60%); /* Safari 5.1 - 6.0 /
background: -o-radial-gradient(#32E6F3 5%, #182B48 20%, #171B22 60%); / Opera 11.6 - 12.0 /
background: -moz-radial-gradient(#32E6F3 5%, #182B48 20%, #171B22 60%); / Firefox 3.6 - 15 /
background: radial-gradient(#32E6F3 5%, #182B48 20%, #171B22 60%); / 标准的语法(必须放在最后) */
}
</style>
<link rel="stylesheet" type="text/css" href="font_1283486_eotsckmipv/iconfont.css">
</head>
<body style="background:#171B22;width:100%;height:100%;">
<div style="width:100px;height:100px;" ></div>
<div id="parent" style="position: relative;width: 675px; height: 434px; transform- origin: 0px 0px; transform: scale(0.568889, 0.645161);">
<canvas style="width:100%;height:100%;box-shadow:0 0 2px rgba(255,255,255,0.5);" id="canvas"></canvas>
</div>
</body>
<script>
window.onload=function(){
var arr = [//四个图标得位置 和unicode //第一步
{x:10,y:330,icon:""},
{x:180,y:230,icon:""},
{x:350,y:330,icon:""},
{x:520,y:230,icon:""}
]
function angle(x1, y1, x2, y2) {
const x = x2 - x1;
const y = y2 - y1;
// 返回弧度 不是角度
return (360 * Math.atan(y / x)) / (2 * Math.PI);
}
var number = -1;
function render() {
const parent = document.getElementById("parent"); // 父容器
const canvas = document.getElementById("canvas"); // 子容器
canvas.width = parent.clientWidth
canvas.height = parent.clientHeight
timer();
}
function drawLine(h,canvas, x, y,z, tox, toy, toz,distance, lineWidth,vars, lineStyle) {
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.lineWidth = lineWidth;
// ctx.setLineDash([5, 15]);
if (lineStyle) {
ctx.setLineDash(lineStyle.dash);
ctx.lineDashOffset = lineStyle.offset;
ctx.strokeStyle = "rgba(235, 206, 53,1)";
} else {
ctx.strokeStyle = "rgba(39, 229, 239,1)";
}
if (vars) {
const lines = Math.sqrt(
Math.pow(toy + toz - y, 2) + Math.pow(tox - x, 2)
);
const qw =
((tox - x) /
Math.sqrt(Math.pow(tox - x, 2) + Math.pow(toy - y + z, 2))) *
distance;
const qh =
((toy + toz - y - h/2) /
Math.sqrt(Math.pow(tox - x, 2) + Math.pow(toy + toz - y, 2))) *
distance;
ctx.moveTo(
tox - ((tox - x) / lines) * distance + qw,
toy - ((toy - y) / lines) * distance - toz - Math.abs(qh) - h/2
);
ctx.lineTo(
tox - ((tox - x) / lines) * distance,
toy - ((toy - y) / lines) * distance - toz - h/2
);
ctx.lineTo(
tox - ((tox - x) / lines) * distance,
toy - ((toy - y) / lines) * distance
);
ctx.lineTo(x, y-z);
} else {
ctx.moveTo(x, y-z);
const lines = Math.sqrt(
Math.pow(toy + toz - y, 2) + Math.pow(tox - x, 2)
);
ctx.lineTo(
tox - ((tox - x) / lines) * distance,
toy - ((toy - y) / lines) * distance
);
ctx.lineTo(
tox - ((tox - x) / lines) * distance,
toy - ((toy - y) / lines) * distance - toz - h/2
);
const qw =
((tox - x) /
Math.sqrt(Math.pow(tox - x, 2) + Math.pow(toy - y + z, 2))) *
distance;
const qh =
((toy + toz - y - h/2) /
Math.sqrt(Math.pow(tox - x, 2) + Math.pow(toy + toz - y, 2))) *
distance;
ctx.lineTo(
tox - ((tox - x) / lines) * distance + qw,
toy - ((toy - y) / lines) * distance - toz - Math.abs(qh) - h/2
);
}
// ctx.strokeStyle = "rgba(255, 255, 255,1)";
// ctx.fillStyle = "rgba(255, 255, 255,1)";
ctx.stroke();
ctx.setLineDash([0, 0]);
ctx.lineDashOffset = 0;
}
function boox(
canvas,
x,
y,
z,
width,
height,
text,
font,
label,
lablefont,
valuecolor
) {
const angle = dataset.angle;
const ctx = canvas.getContext("2d");
y = y - z;
ctx.moveTo(x, y);
const line = width / 2 / Math.cos((Math.PI / 180) * angle);
ctx.moveTo(x - width / 2, y - height / 2);
// 背景
ctx.beginPath();
ctx.moveTo(x - width / 2, y + height / 2);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line,
y + height / 2 + Math.sin((Math.PI / 180) * angle) * line
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line * 2,
y + height / 2
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line * 2,
y + height / 2 - height * 1
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line,
y + height / 2 - Math.sin((Math.PI / 180) * angle) * line - height * 1
);
ctx.lineTo(x - width / 2, y + height / 2 - height * 1);
ctx.strokeStyle = "rgba(36, 177, 191,1)";
ctx.fillStyle = "rgba(36, 177, 191,0.5)";
ctx.stroke();
ctx.fill();
// 底层板
ctx.beginPath();
ctx.moveTo(x - width / 2, y + height / 2);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line,
y + height / 2 + Math.sin((Math.PI / 180) * angle) * line
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line * 2,
y + height / 2
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line,
y + height / 2 - Math.sin((Math.PI / 180) * angle) * line
);
ctx.lineTo(x - width / 2, y + height / 2);
ctx.strokeStyle = "rgba(36, 177, 191,1)";
ctx.fillStyle = "rgba(36, 177, 191,0.5)";
ctx.stroke();
ctx.fill();
// 中层板
ctx.beginPath();
ctx.moveTo(x - width / 2, y + height / 2 - height * 0.4);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line,
y + height / 2 + Math.sin((Math.PI / 180) * angle) * line - height * 0.4
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line * 2,
y + height / 2 - height * 0.4
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line * 2,
y + height / 2 - height * 0.6
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line,
y + height / 2 + Math.sin((Math.PI / 180) * angle) * line - height * 0.6
);
ctx.lineTo(x - width / 2, y + height / 2 - height * 0.6);
ctx.lineTo(x - width / 2, y + height / 2 - height * 0.4);
ctx.strokeStyle = "rgba(210, 201, 69,1)";
ctx.fillStyle = "rgba(210, 201, 69,1)";
ctx.stroke();
ctx.fill();
// 中层板
ctx.beginPath();
ctx.moveTo(x - width / 2, y + height / 2 - height * 0.6);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line,
y + height / 2 + Math.sin((Math.PI / 180) * angle) * line - height * 0.6
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line * 2,
y + height / 2 - height * 0.6
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line,
y + height / 2 - Math.sin((Math.PI / 180) * angle) * line - height * 0.6
);
ctx.lineTo(x - width / 2, y + height / 2 - height * 0.6);
ctx.strokeStyle = "rgba(40, 230, 239,1)";
ctx.fillStyle = "rgba(40, 230, 239,0.5)";
ctx.stroke();
ctx.fill();
// 顶层板
ctx.beginPath();
ctx.moveTo(x - width / 2, y + height / 2 - height * 1);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line,
y + height / 2 + Math.sin((Math.PI / 180) * angle) * line - height * 1
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line * 2,
y + height / 2 - height * 1
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line,
y + height / 2 - Math.sin((Math.PI / 180) * angle) * line - height * 1
);
ctx.lineTo(x - width / 2, y + height / 2 - height * 1);
ctx.strokeStyle = "rgba(37, 192, 205,1)";
ctx.fillStyle = "rgba(37, 192, 205,0.5)";
ctx.stroke();
ctx.fill();
// 呼吸灯
ctx.beginPath();
ctx.moveTo(x - width / 2, y + height / 2 - height * 1);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line,
y + height / 2 + Math.sin((Math.PI / 180) * angle) * line - height * 1
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line * 2,
y + height / 2 - height * 1
);
ctx.lineTo(
x - width / 2 + Math.cos((Math.PI / 180) * angle) * line * 2.2,
y - height * 2
);
ctx.lineTo(
x - width / 2 - Math.cos((Math.PI / 180) * angle) * line * 0.2,
y - height * 2
);
ctx.lineTo(x - width / 2, y + height / 2 - height * 1);
ctx.strokeStyle = "rgba(37, 192, 205,1)";
ctx.fillStyle = "rgba(37, 192, 205,0.5)";
const lingrad = ctx.createLinearGradient(
x,
y - height * 2,
x,
y + height / 2 + Math.sin((Math.PI / 180) * angle) * line - height * 1
);
lingrad.addColorStop(0, "rgba(37, 192, 205,0)");
let appha = 0;
if (parseInt(offset / 100) % 2 === 0) {
appha = (offset % 100) / 100;
} else {
appha = (100 - parseInt(offset % 100)) / 100;
}
// function iconFont(id) {
// return document.getElementById(id).textContent;
// }
for(var p=0;p<arr.length;p++){//第二步 循环arr数组绘制图标
ctx.font='60px IconFont';//图标大小
let lingrad1 = ctx.createLinearGradient(arr[p].x,arr[p].y, arr[p].x, arr[p].y-30);//渐变色位置
lingrad1.addColorStop(1, 'rgb(28, 254, 255)');//渐变色颜色
lingrad1.addColorStop(0, 'rgb(15, 96, 255)');//渐变色颜色
ctx.fillStyle = lingrad1;//填充渐变色
//ctx.strokeStyle = lingrad1; //样式3
ctx.fillText(eval(('("'+arr[p].icon).replace('&#x','\\u').replace(';','')+'")'), arr[p].x, arr[p].y);
}
lingrad.addColorStop(1, "rgba(37, 192, 205," + appha + ")");
ctx.fillStyle = lingrad;
ctx.fill();
ctx.fillStyle = valuecolor;
// 数字叠加
ctx.font = font + "px bold";
let w = ctx.measureText(text);
// ctx.fillText(text, x - w.width / 2, y - height / 2);
// 标签文字
ctx.fillStyle = "rgba(255, 255, 255,1)";
ctx.font = lablefont + "px bold";
w = ctx.measureText(label);
// ctx.fillText(label, x - w.width / 2, y + height * 2);
}
function timer() {
const angle = dataset.angle;
const canvas = document.getElementById("canvas"); // 子容器
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
const data = dataset.data;
for (let i = 0; i < data.length; i++) {
boox(
canvas,
data[i].x,
data[i].y,
data[i].z,
data[i].w,
data[i].h,
data[i].text,
data[i].font,
data[i].label,
data[i].lablefont,
data[i].valuecolor
);
const x = data[i].x;
const y = data[i].y;
if (i !== data.length - 1) {
if (data[i].y > data[i + 1].y) {
const z = data[i + 1].z;
const tox = data[i + 1].x;
const toy = data[i + 1].y;
const toz = data[i + 1].z;
const width = data[i + 1].w;
const line = width / 2 / Math.cos((Math.PI / 180) * angle);
const qw =
((tox - x) /
Math.sqrt(Math.pow(tox - x, 2) + Math.pow(toy + z - y, 2))) *
((line + dataset.distance * 2) / 2);
const qh =
((toy + z - y) /
Math.sqrt(Math.pow(tox - x, 2) + Math.pow(toy + z - y, 2))) *
((line + dataset.distance * 2) / 2);
drawLine(
data[i].h,
canvas,
x + width / 4,
y - (Math.sin((Math.PI / 180) * angle) * line) / 2,
z,
tox - qw,
toy + Math.abs(qh),
toz,
dataset.distance,
3,
false
);
offset++;
drawLine(
data[i].h,
canvas,
x + width / 4 - 3,
y - (Math.sin((Math.PI / 180) * angle) * line) / 2 - 3,
z,
tox - qw - 3,
toy + Math.abs(qh) - 3,
toz,
dataset.distance,
1,
false,
{ dash: [4, 4], offset: parseInt(offset / 10) }
);
drawLine(
data[i].h,
canvas,
x + width / 4 + 3,
y - (Math.sin((Math.PI / 180) * angle) * line) / 2 + 3,
z,
tox - qw + 3,
toy + Math.abs(qh) + 3,
toz,
dataset.distance,
1,
false,
{ dash: [4, 4], offset: parseInt(offset / 10) }
);
} else {
const toz = data[i].z;
const tox = data[i].x;
const toy = data[i].y;
const width = data[i].w;
const x = data[i + 1].x;
const y = data[i + 1].y;
const z = data[i + 1].z;
const line = width / 2 / Math.cos((Math.PI / 180) * angle);
const qw =
((tox - x) /
Math.sqrt(Math.pow(tox - x, 2) + Math.pow(toy + z - y, 2))) *
((line + dataset.distance * 2) / 2);
const qh =
((toy + z - y) /
Math.sqrt(Math.pow(tox - x, 2) + Math.pow(toy + z - y, 2))) *
((line + dataset.distance * 2) / 2);
drawLine(
data[i].h,
canvas,
x - width / 4,
y - (Math.sin((Math.PI / 180) * angle) * line) / 2,
z,
tox - qw,
toy + Math.abs(qh),
toz,
dataset.distance,
3,
true
);
offset++;
drawLine(
data[i].h,
canvas,
x - width / 4 + 3,
y - (Math.sin((Math.PI / 180) * angle) * line) / 2 - 3,
z,
tox - qw + 3,
toy + Math.abs(qh) - 3,
toz,
dataset.distance,
1,
true,
{ dash: [4, 4], offset: parseInt(offset / 10) }
);
drawLine(
data[i].h,
canvas,
x - width / 4 - 3,
y - (Math.sin((Math.PI / 180) * angle) * line) / 2 + 3,
z,
tox - qw - 3,
toy + Math.abs(qh) + 3,
toz,
dataset.distance,
1,
true,
{ dash: [4, 4], offset: parseInt(offset / 10) }
);
}
}
}
if (timerccc) {
clearTimeout(timerccc);
}
timerccc = setTimeout(() => {
timer();
}, 16);
}
var timerccc = null;
var offset = 0;
var dataset = {"distance":17.578125,"angle":30,"valueFontSize":20,"data":[
{"x":42.1875,"y":344.125,"z":0,"w":100,"h":31,"text":24,"font":40,"valuecolor":"rgba(6 5, 239, 65,1)","label":"触发","lablefont":20},
{"x":210.9375,"y":244.125,"z":0,"w":100,"h":31,"text":23,"font":40,"valuecolor":"rgba(239, 196, 65,1)","label":"跟踪","lablefont":20},
{"x":379.6875,"y":344.125,"z":0,"w":100,"h":31,"text":26,"font":40,"valuecolor":"rgba(239, 65, 233,1)","label":"维修","lablefont":20},
{"x":548.4375,"y":244.125,"z":0,"w":100,"h":31,"text":23,"font":40,"valuecolor":"rgba(241, 23, 12,1)","label":"解决","lablefont":20}]}
render();
}
</script>
</html>
核心代码
var arr = [//四个图标得位置 和unicode //第一步
{x:10,y:330,icon:""},
{x:180,y:230,icon:""},
{x:350,y:330,icon:""},
{x:520,y:230,icon:""}
];
for(var p=0;p<arr.length;p++){//第二步 循环arr数组绘制图标
ctx.font='60px IconFont';//图标大小
let lingrad1 = ctx.createLinearGradient(arr[p].x,arr[p].y, arr[p].x, arr[p].y-30);//渐变色位置
lingrad1.addColorStop(1, 'rgb(28, 254, 255)');//渐变色颜色
lingrad1.addColorStop(0, 'rgb(15, 96, 255)');//渐变色颜色
ctx.fillStyle = lingrad1;//填充渐变色
//ctx.strokeStyle = lingrad1; //样式3
ctx.fillText(eval(('("'+arr[p].icon).replace('&#x','\\u').replace(';','')+'")'), arr[p].x, arr[p].y);
}
网友评论