阅读视图

发现新文章,点击刷新页面。

水厂水泵工作流程图canvas动画

水厂水泵工作流程图.jpg展示地址 http://jstopo.top

let state = {
    qpaoTime: 0,
    waterLen: 0,
    countNum: 0,
    timeR: 0
  };
  const starCanvas = document.getElementById('myCanvas');
  const drawLineFunc = (ctx, objs)=>{//绘制线路
      objs.forEach(item=>{
          ctx.save();
          ctx.beginPath();
          ctx.strokeStyle = item.color;
          ctx.lineWidth = item.isDash ? 5:item.lineWidth;
          ctx.lineCap = item.lineCap;
          // item.isDash ? ctx.setLineDash(item.lineDash||[]):ctx.setLineDash([]);
          item.lines.forEach((line,indx)=>{
              if(!item.isDash){
                  if(line.isMoveTo) ctx.moveTo(line.x,line.y);
                  else ctx.lineTo(line.x,line.y);
              }else if(item.isDash && !line.isMoveTo){
                  if( line.y == item.lines[indx-1].y){//不能是第一个点
                      if(line.x > item.lines[indx-1].x){//管道x向右
                          let c = state.countNum, total_c = line.x - item.lines[indx-1].x;
                          while(c <= total_c-4){
                              let ax = item.lines[indx-1].x+c;
                              ctx.moveTo(ax,line.y);
                              let ax2 = item.lines[indx-1].x+c+8;
                              ctx.lineTo(ax2, line.y);
                              c += 12;
                          }
                      }else{//管道x向左
                          let c = state.countNum, total_c = item.lines[indx-1].x - line.x;
                          while(c <= total_c-6){
                              let ax = item.lines[indx-1].x-c;
                              ctx.moveTo(ax,line.y);
                              let ax2 = item.lines[indx-1].x-c-8;
                              ctx.lineTo(ax2, line.y);
                              c += 12;
                          }
                      }
                      
                  }else if(line.x == item.lines[indx-1].x){
                      if(line.y > item.lines[indx-1].y){//管道y向下
                          let c = state.countNum, total_c = line.y - item.lines[indx-1].y;
                          while(c <= total_c-6){
                              let ay = item.lines[indx-1].y+c;
                              ctx.moveTo(line.x, ay);
                              let ay2 = item.lines[indx-1].y+c+8;
                              ctx.lineTo(line.x, ay2);
                              c += 12;
                          }
                      }else{//管道y向上
                          let c = state.countNum, total_c = item.lines[indx-1].y - line.y;
                          while(c <= total_c-4){
                              let ay = item.lines[indx-1].y-c;
                              ctx.moveTo(line.x, ay);
                              let ay2 = item.lines[indx-1].y-c-8;
                              ctx.lineTo(line.x, ay2);
                              c += 12;
                          }
                      }
                      
                  }
              }
          })
          ctx.stroke();
          ctx.restore();
      })
  }
  const drawInitRect = (ctx)=>{//绘制文字矩形
      ctx.save();
      ctx.beginPath();ctx.font = "normal 14px 微软雅黑";
      ctx.lineWidth = 2;ctx.fillStyle = "#333";
      ctx.rect(160, 32, 100, 80);
      ctx.fillText("闸门", 196, 130);
      ctx.moveTo(370+12, 18);
      ctx.arc(370, 38, 18, 0, Math.PI*2);
      ctx.rect(330, 57, 80, 26);
      ctx.fillText("5.5 m³/H", 416, 33);
      ctx.fillText("瞬时流量", 416, 50);
      ctx.fillText("7.5 GJ", 416, 96);
      ctx.fillText("瞬时热量", 416, 111);
  
      ctx.fillText("9.3 m³/H", 216, 370);
      ctx.fillText("瞬时流量", 216, 390);
  
      ctx.fillText("6.8 GJ", 216, 510);
      ctx.fillText("瞬时热量", 216, 530);
  
      ctx.fillText("自流井", 326, 770);
      ctx.fillText("水箱", 908, 750);
      ctx.fillText("水量 73.9%", 788, 690);
      ctx.moveTo(466, 56);
      ctx.lineTo(466, 85);
      ctx.lineTo(490, 85);
      ctx.lineTo(490, 105);
      ctx.lineTo(510, 105);
      ctx.lineTo(510, 85);
      ctx.lineTo(538, 85);
      ctx.lineTo(538, 56);
      ctx.lineTo(468, 56);
      ctx.moveTo(420, 401);
      ctx.rect(300, 572, 100, 180);
      ctx.moveTo(930-52, 606);
      ctx.arc(930, 606, 52, Math.PI, Math.PI*2);
      ctx.lineTo(982, 706);ctx.lineTo(1003, 706);ctx.lineTo(1003, 730);
      ctx.lineTo(860, 730);ctx.lineTo(860, 706);ctx.lineTo(878, 706);ctx.lineTo(878, 606);
      ctx.fill();
      ctx.restore();
      Animation_of_water_flowing_up(ctx);
  }
  const Animation_of_water_flowing_up = (ctx)=>{//水向上流动动画
    const grd = ctx.createLinearGradient(300, 752, 300, 752-state.waterLen);
    ctx.save();
    ctx.beginPath();
    grd.addColorStop(0.3,"#832392");
    grd.addColorStop(1,"#c636de");
    ctx.fillStyle = grd;ctx.strokeStyle = grd;
    //瀑布流动
    ctx.moveTo(400, 647);
    ctx.quadraticCurveTo(352, 678, 352-state.countNum, 752);
    ctx.lineTo(362-state.countNum, 749);
    ctx.quadraticCurveTo(366, 678, 400, 653);
    //水储存在箱子里
    ctx.moveTo(300, 752);
    ctx.lineTo(400, 752);
    ctx.lineTo(400, 751-state.waterLen);
    ctx.lineTo(300, 751-state.waterLen);
    ctx.lineTo(300, 752);
    //水箱 水量
    ctx.moveTo(975, 706);
    ctx.lineTo(885, 706);
    ctx.lineTo(885, 706-state.waterLen);
    ctx.lineTo(975, 706-state.waterLen);
    ctx.moveTo(975, 706);
    ctx.stroke();
    ctx.fill();
    ctx.restore();
    if(state.waterLen > 30){
        randomBubble(ctx,400,752,300,752-state.waterLen);
        randomBubble(ctx,955,706,895,706-state.waterLen);
    }
  }
  const randomBubble = (ctx,sx,sy,ex,ey)=>{//水里随机的气泡动画
      const width = sx - ex, height = sy - ey-16;
      ctx.save();
      ctx.beginPath();ctx.strokeStyle = "rgba(255,255,255,0.4)";
      ctx.arc(sx-Math.random()*width,sy-8-Math.floor(Math.random()*height),Math.floor(Math.random() * 8) + 1,0,Math.PI*2);
      ctx.fillStyle = "rgba(255,255,255,0.4)";
      ctx.fill();ctx.stroke();
      ctx.restore();
  }
  const requestAmatinat = (ctx,width,height)=>{
      const dotMove = ()=>{
          ctx.clearRect(0,0,width,height);
          drawLineFunc(ctx,[
              {
                  isDash:false,
                  lines:[
                    {x:1180,y:682,isMoveTo:true},
                    {x:1180,y:546},{x:1420,y:546},
                    {x:1420,y:546},{x:1420,y:160}
                  ],
                  color:'#333',lineWidth:16,lineCap:'round'
              },
              {
                isDash:true,
                lines:[
                  {x:1180,y:682,isMoveTo:true},
                  {x:1180,y:546},{x:1420,y:546},
                  {x:1420,y:546},
                  {x:1420,y:160}
                ],
                color:'#c636de',
                lineWidth:5,
                lineCap:'butt',
                lineDash:[12, 3]
              },
              {isDash:false,lines:[
                {x:500,y: 70,isMoveTo:true},
                {x:500,y:310},
                {x:width - 160,y:310},
                {x:100,y:70,isMoveTo:true},
                {x:width - 160,y:70},
                {x:100,y:70,isMoveTo:true},
                {x:width - 160,y:70},
                {x:320,y:221,isMoveTo:true},
                {x:320, y: 470},
                {x:1180,y: 470},
                {x:1180,y: 410},
                {x:width - 160, y:410}
              ],color:'#333',lineWidth:16,lineCap:'round'},
              {
                  isDash:true,
                  lines:[
                    {x:500,y:70,isMoveTo:true},
                    {x:500,y:310},
                    {x:width - 160,y:310},
                    {x:100,y:70,isMoveTo:true},
                    {x:width - 160,y:70},
                  ],
                  color:'#ff9800',
                  lineWidth:5,
                  lineCap:'butt',
                  lineDash:[12, 3]
              },
              {
                isDash:false,
                lines:[
                {x:100,y:220,isMoveTo:true},
                {x:width - 600,y:220},
                {x:width - 600,y:160},
                {x:width - 160,y:160},
                {x:100,y:550,isMoveTo:true},
                {x:830, y:550},{x:830,y:650},{x:880,y:650},
                {x:980,y:682,isMoveTo:true},
                {x:1536, y:682},
                {x:1536, y:410},
                {x:500,y:550,isMoveTo:true},
                {x:500,y:650},{x:401,y:650},
                {x:401,y:680,isMoveTo:true},
                {x:610,y:680},{x:610,y:750},
                {x:710,y:750},{x:710,y:790},
                ],
                color:'#333',lineWidth:16,lineCap:'round'
              },
              {
                isDash:true,
                lines:[
                    {x:100,y:220,isMoveTo:true},
                    {x:width - 600, y:220},
                    {x:width - 600, y:160},
                    {x:width - 160, y:160},
                    {x:320,y:221,isMoveTo:true},
                    {x:320, y:470},
                    {x:1180, y:470},
                    {x:1180, y:410},
                    {x:width - 160, y:410},
                    {x:100,y:550,isMoveTo:true},
                    {x:830, y:550},{x:830,y:650},{x:880,y:650},
                    {x:980,y:682,isMoveTo:true},
                    {x:1536, y:682},{x:1536, y:410},
                    {x:500,y:550,isMoveTo:true},
                    {x:500,y:650},{x:401,y:650},
                    {x:401,y:680,isMoveTo:true},
                    {x:610,y:680},{x:610,y:750},
                    {x:710,y:750},{x:710,y:830},
                  ],
                  color:'#c636de',
                  lineWidth:5,
                  lineCap:'butt',
                  lineDash:[12, 3]
              },
          ]);
          drawInitRect(ctx);
          state.countNum+=0.6;
          state.waterLen+=0.2;
          state.qpaoTime+=1;
          if(state.qpaoTime >= 100){
              state.qpaoTime = 0;
          }
          if(state.waterLen >= 110){
              state.waterLen = 110;
              cancelAnimationFrame(state.timeR);
          }
          if(state.countNum >= 12){
              state.countNum = 0;
              cancelAnimationFrame(state.timeR);
          }
          state.timeR = requestAnimationFrame(dotMove);
      }
      dotMove();
  }
  const drawChart = ()=>{
      if(!starCanvas) return;
      starCanvas.width = starCanvas.clientWidth;
      starCanvas.height = starCanvas.clientHeight;
  
      const ctx = starCanvas.getContext('2d');
      requestAmatinat(ctx,starCanvas.width,starCanvas.height);
  }
  window.onload = ()=>{
    drawChart();
  }
❌