<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<style>
.container-ecg {
position: relative;
}
.boack {
position: absolute;
top: 0;
left: 0;
}
</style>
<div class="container-ecg">
<div class="boack">
<canvas id="ecg-bg" width="993" height="600">
</div>
<div class="boack">
<canvas id="ecg" width="993" height="600">
</canvas>
</div>
</div>
</body>
</html>
<script>
var bg = document.getElementById("ecg-bg");
var ctx_bg = bg.getContext("2d");
var canvas = document.getElementById("ecg");
var width = canvas.width;
var height = canvas.height;
var ctx = canvas.getContext("2d");
var grid_width = 16; // 每一个小网格的宽高
var hLineNum = parseInt(height / grid_width); // 横线个数
var vLineNum = parseInt(width / grid_width) + 1; // 竖线个数
var x_start = -3;
</script>
<script>
class WaveView {
ctx = null;
curX = 16; //当前点x位置
curY = 0; //当前点y位置
preX = -3; //前一个点x位置
preY = 0; //前一个点y位置
nextX = -3;
nextY = 0;
speed = 10; // 每秒画几个点
clearWidth = 60; // 橡皮檫宽度
queue = []; // 数据队列
strokeStyle = "#36D2EB"; //线条颜色
w = 0;
h = 0;
rangeup = 0 //数值上范围
rangedown = 180; //数值下范围
animStep = 3; //每个线分10步
frist = true;
/**
* @param ctx canves上下文对象
* @param w 容器宽度
* @param h 容器高度
* @param speed 每秒画几个点
*/
constructor(ctx, w, h, speed = 1) {
this.ctx = ctx;
this.speed = speed;
this.w = w;
this.h = h;
this.clearWidth = 16 * 2;
this.drawInterval = Math.floor(1000 / this.speed / this.animStep); // 绘制时间间隔
console.log(this.drawInterval);
}
draw = () => {
if (this.frist) {
this.frist = false;
this.curY = this.h / 2;
this.preY = this.curY;
this.nextY = this.curY;
}
// 橡皮擦 清除
if (this.curX === 0) {
this.ctx.clearRect(-2, 0, this.clearWidth, 600);
} else {
this.ctx.clearRect(this.curX - 2, 0, this.clearWidth, 600);
}
let gapX = this.curX - this.preX;
let gapY = this.curY - this.preY;
let dx = gapX / this.animStep;
let dy = gapY / this.animStep;
this.nextX += dx;
this.nextX = Math.min(this.nextX, this.curX); //防止超出
//(x-x1)/(x2-x1)=(y-y1)/(y2-y1)
this.nextY =
((this.nextX - this.preX) * (this.curY - this.preY)) / (this.curX - this.preX) +
Number(this.preY);
// if (this.queue.length <= 0) return;
this.drawLine(this.preX, this.preY, this.nextX, this.nextY);
if (this.nextX >= this.curX) {
this.preX = this.curX;
this.preY = this.curY;
//没有数据就回归中轴
if (this.queue.length === 0) {
this.queue.push((this.rangedown + this.rangeup) / 2);
}
let val = this.queue.shift();
this.curY = Number(
(
((this.rangeup - val) / (this.rangeup - this.rangedown)) * -this.h +
this.h
).toFixed(2)
);
//重新获取x
this.curX += 16; //16是一个小网格的宽高
}
if (this.curX >= this.w) {
this.curX = 3;
this.nextX = -3;
this.preX = -3;
}
}
drawLine = (x1, y1, x2, y2) => {
// console.log(x1, y1, x2, y2)
this.ctx.strokeStyle = this.strokeStyle;
this.ctx.lineWidth = 3;
this.ctx.lineJoin = "round";
this.ctx.lineCap = "round";
this.ctx.beginPath(); //不写每次都会重绘上次的线
this.ctx.moveTo(x1, y1);
this.ctx.lineTo(x2, y2);
this.ctx.stroke();
this.ctx.closePath();
}
loop = () => {
this.draw();
setTimeout(this.loop, this.drawInterval);
}
//增加数据
addData = (arr) => {
var max = Math.max.apply(null, arr);
var min = Math.min.apply(null, arr);
this.queue.push(...arr);
}
//画网格线
drawGrid = () => {
//画横线
this.ctx.beginPath();
this.ctx.lineWidth = 1;
this.ctx.strokeStyle = "#E6E7E8";
for (let i = 0; i < hLineNum; i++) {
if (i == 0 || i % 5 != 0) {
this.ctx.moveTo(0, i * grid_width);
this.ctx.lineTo(width, i * grid_width);
this.ctx.stroke();
}
}
this.ctx.beginPath();
this.ctx.lineWidth = 1;
this.ctx.strokeStyle = "#E6E7E8";
for (let i = 5; i <= vLineNum; i += 5) {
this.ctx.moveTo(i * grid_width, 0);
this.ctx.lineTo(i * grid_width, height);
this.ctx.stroke();
}
//画竖线
this.ctx.beginPath();
this.ctx.lineWidth = 1;
this.ctx.strokeStyle = "#E6E7E8";
for (let i = 0; i < vLineNum; i++) {
if (i == 0 || i % 5 != 0) {
this.ctx.moveTo(i * grid_width, 0);
this.ctx.lineTo(i * grid_width, height);
this.ctx.stroke();
}
}
//5个一组
this.ctx.beginPath();
this.ctx.lineWidth = 1;
this.ctx.strokeStyle = "#E6E7E8";
for (let i = 5; i <= hLineNum; i += 5) {
this.ctx.moveTo(0, i * grid_width);
this.ctx.lineTo(width, i * grid_width);
this.ctx.stroke();
}
}
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
let ecgbg = new WaveView(ctx_bg, width, height);
ecgbg.drawGrid();
let ecgWave = new WaveView(ctx, width, height, 5);
let data = [];
for (let i = 0; i < 100; i++) {
data.push(getRandomInt(90, 110));
}
// ecgWave.addData(data)
ecgWave.loop();
setInterval(() => {
let point = getRandomInt(50, 130);
console.log(point);
ecgWave.addData([point])
}, 1000);
</script>
index.html
index.html