忠信 发表于 2024-5-11 00:23:01

Canvas案例-实现ECG心电图

描绘一个ECG心电图

上代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>canvas绘制心电图</title>
</head>
<body>
    <canvas id="ecg" width="751" height="201" ></canvas>
</body>
</html>
<script>
    var ecgDom = document.getElementById('ecg');
    var ecgDomWidth = ecgDom.width - 1,
      ecgDomHeight = ecgDom.height - 21;
    var addX = ecgDomWidth / 50, // 这个50是横坐标总的中格子数
      addY = ecgDomHeight / 12, // 这个12是纵坐标总的中格子数
      marginL = 0.5;
    /*
    1、context.strokeRect(x,y,width,height); strokeRect() 方法绘制矩形(不填色)。笔触的默认颜色是黑色。
   */
    // canvas 的左上角坐标为 (0,0)
    // 绘制表格的函数,此表格包含大中小三种格子,分别对应三种函数:
    function drawSmallGrid(c_canvas){ // 绘制小格子
      var context = c_canvas.getContext("2d");
      context.fillStyle = '#ff6b64';
      var dotMarginX = addX / 5,
            dotMarginY = addY / 5;
      var i = dotMarginX;
      // let num = 0;
      for (i; i < ecgDomWidth; i += dotMarginX) {
            // console.log(i);
            // if ((i % addX) === 0) { console.log(i); }
            if ((i % addX) !== 0) {    // 列分隔线处不打点
                for (var j = dotMarginY; j < ecgDomHeight; j += dotMarginY) {
                  if ((j % addY) !== 0) { // 行分割线处不打点
                        console.log('行分割线处不打点', j);
                        // num++;
                        // context.rect(x,y,width,height); 矩形左上角的 x 坐标, 矩形左上角的 y 坐标, 矩形的宽度,以像素计, 矩形的高度,以像素计
                        context.rect(i, j, 1, 0.5);
                  }
                }
            }
      }
      context.fill();
    }
    function drawMediumGrid(c_canvas){ // 绘制中格子
      var context = c_canvas.getContext("2d");
            context.strokeStyle = "#ff6b64";
            context.strokeWidth=1.5;
            context.setLineDash();
            context.beginPath();
      let num = 0;
      for (var x = marginL; x < ecgDomWidth; x += addX) {
            context.moveTo(x, 0); // moveTo(x,y) 定义线条开始坐标, Y轴的话从0开始描绘
            context.lineTo(x, ecgDomHeight); // lineTo(x,y) 定义线条结束坐标, X轴可以描绘到1000
            context.stroke();
            num++;
      };
      console.log('X轴网格数:', num);
      for (var y = marginL; y < ecgDomHeight; y += addY) {
            context.moveTo(0, y);
            context.lineTo(ecgDomWidth, y);
            context.stroke();
      };
      context.closePath();
      return;
    }

   function drawBigGrid(c_canvas){ // 绘制大格子
      var context = c_canvas.getContext("2d");
            context.strokeStyle = "#ff6b64"; // 设置或返回用于笔触的颜色、渐变或模式。
            context.strokeWidth=1.5;
            context.setLineDash(); // 设置线条虚线样式的间距和长度。: 虚线长度为0则绘制成实线
            context.beginPath();// 起始一条路径,或重置当前路径.
      var bigAddX = ecgDomWidth / 10, // 10表示10s
            bigAddY = ecgDomHeight / 2; // 2表示把Y轴分成2份,分别为正负
      for (var x = marginL; x < ecgDomWidth; x += bigAddX) {
            context.moveTo(x, 0); // moveTo(x,y) 定义线条开始坐标
            context.lineTo(x, ecgDomHeight); // lineTo(x,y) 定义线条结束坐标
            context.stroke(); // stroke() 方法来绘制线条
         };
      for (var y = marginL; y < ecgDomHeight; y += bigAddY) {
            context.moveTo(0, y); // moveTo(x,y) 定义线条开始坐标
            context.lineTo(ecgDomWidth, y); // lineTo(x,y) 定义线条结束坐标
            context.stroke(); // stroke() 方法来绘制线条
      };
      context.closePath(); // 关闭一条打开的子路径
      return;
   }
   function drawBigBorder(c_canvas){ // 绘制边框
      var context = c_canvas.getContext("2d");
            /* context.strokeStyle = "#ff6b64"; // 设置或返回用于笔触的颜色、渐变或模式。
            context.strokeWidth=1.5;
            context.setLineDash(); // 设置线条虚线样式的间距和长度。: 虚线长度为0则绘制成实线
            context.beginPath();// 起始一条路径,或重置当前路径.
            context.moveTo(ecgDomWidth,0);
            context.lineTo(ecgDomWidth,ecgDomHeight);
            context.moveTo(0,ecgDomHeight);
            context.lineTo(ecgDomWidth,ecgDomHeight);
            context.closePath(); // 关闭一条打开的子路径 */
            context.strokeStyle = "#ff6b64";
            context.strokeWidth=1.5;
            context.setLineDash();
            context.beginPath();
            context.moveTo(ecgDomWidth + marginL,0);
            context.lineTo(ecgDomWidth + marginL,ecgDomHeight + 1);
            context.moveTo(0,ecgDomHeight+marginL);
            context.lineTo(ecgDomWidth,ecgDomHeight+marginL);
            console.log('宽高:', ecgDomWidth, ecgDomHeight);
            context.stroke();
      return;
   }
   function drawBigBG(c_canvas){ // 绘制背景
      var context = c_canvas.getContext("2d");
            context.fillStyle = '#FFE9E9';
            context.fillRect(0, 0, ecgDomWidth + 21, ecgDomHeight + 21);
   }
   function drawLabelX(c_canvas){ // 绘制横坐标的label
    var secondLabel = ecgDomWidth / 10;
      var context = c_canvas.getContext("2d");
            context.strokeStyle = '#000';
            context.setLineDash(); // 设置线条虚线样式的间距和长度。: 虚线长度为0则绘制成实线
            context.beginPath();// 起始一条路径,或重置当前路径
            context.strokeWidth=1.5;
            for (var x = marginL; x <= ecgDomWidth + secondLabel; x += secondLabel) {
                context.moveTo(x, ecgDomHeight); // moveTo(x,y) 定义线条开始坐标
                context.lineTo(x, ecgDomHeight + secondLabel + 20); // lineTo(x,y) 定义线条结束坐标
                context.stroke(); // stroke() 方法来绘制线条
            };
            // 绘制底部长线
            context.moveTo(0, ecgDomHeight+marginL+20); // moveTo(x,y) 定义线条开始坐标
            context.lineTo(ecgDomWidth,ecgDomHeight+marginL+20); // lineTo(x,y) 定义线条结束坐标
            context.stroke(); // stroke() 方法来绘制线条
            var textNum = 0;
            for (var x = marginL; x <= ecgDomWidth + secondLabel; x += secondLabel) {
                context.font="12px Arial";
                context.fillStyle = "#000";
                context.fillText(textNum+"s",x+2, ecgDomHeight + 15);
                textNum++;
                console.log('textNum:', textNum);
            };
            context.closePath(); // 关闭一条打开的子路径
   }
   // 然后是绘制心电图的函数:
   function drawLine(c_canvas) {
      var ctx = c_canvas.getContext('2d');
            ctx.strokeStyle = "#000"; // 设置或返回用于笔触的颜色、渐变或模式。
            ctx.strokeWidth = 1;
            ctx.setLineDash(); // 设置线条虚线样式的间距和长度。: 虚线长度为0则绘制成实线
            ctx.beginPath(); // 起始一条路径,或重置当前路径。
            ctx.moveTo(0.5, 90); // moveTo(x,y) 定义线条开始坐标
            ctx.lineTo(10, 90); // lineTo(x,y) 定义线条结束坐标
      for(var x = 9; x < 90; x++) {
            ctx.lineTo(x * 6, (Math.random() * 10 -5) * 10 + 90)
      }
      ctx.lineTo(650, 90)
      ctx.lineTo(750, 90)
      ctx.stroke(); // stroke() 方法来绘制线条
      ctx.closePath(); // 关闭一条打开的子路径
   }
   // 最后一起调用这些函数:
(function draw(){
   var c_canvas = document.getElementById("ecg");
   var canvas = c_canvas.getContext("2d");
    //c_canvas.fillStyle = "#ffe9e9";
    //canvas.fillRect(0, 0, c_canvas.width, c_canvas.height)
   drawBigBG(c_canvas);
   drawSmallGrid(c_canvas);
   drawMediumGrid(c_canvas)
   drawBigGrid(c_canvas);
   drawLine(c_canvas);
   drawBigBorder(c_canvas);
   drawLabelX(c_canvas);
   return;
})();
</script>
效果图:
页: [1]
查看完整版本: Canvas案例-实现ECG心电图