波形图动画edit icon

创建者:
流光
Fork(复制)
下载
嵌入
BUG反馈
index.html
index.html
            
            <!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;
        drawInterval=10;
        rangeup = 20 //数值上范围
        rangedown = 180; //数值下范围
        animStep = 10; //每个线分10步
        /**
         * @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.preY == 0) {
                this.curY = (this.queue.shift() / (this.rangeup - this.rangedown) * this.h + this.h).toFixed(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);

            this.drawLine(this.preX, this.preY, this.nextX, this.nextY);

            if (this.nextX >= this.curX) {

                this.preX = this.curX;
                this.preY = this.curY;

                //重新获取y
                if (this.queue.length === 0) {
                    this.curY = this.h / 2;
                    this.ctx.globalCompositeOperation = 'xor';
                } else {
                    this.curY = (this.queue.shift() / (this.rangeup - this.rangedown) * this.h + this.h).toFixed(2);
                }
                //重新获取x
                this.curX += 16; //16是一个小网格的宽高
            }

            if (this.curX >= this.w) {
                this.curX = 0;
                this.nextX = -3;
                this.preX = -3;
            }


        }

        drawLine = (x1, y1, x2, y2) => {
            // console.log(x1, y1, x2, y2)
            this.ctx.beginPath(); //不写每次都会重绘上次的线
            this.ctx.strokeStyle = this.strokeStyle;


            this.ctx.moveTo(x1, y1);
            this.ctx.lineTo(x2, y2);
            this.ctx.stroke();
        }

        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();
</script>
        
编辑器加载中
预览
控制台