组态-管道流动效果初步实现

130 阅读1分钟

上一份工作,有见到组态,第一次认识组态。当时网上找了一些开源的或者做这个的线上的案例,还有公司花钱做出来thingjs的产品,对那个动画比较感兴趣。

当时也是花时间研究了下,目前只实现了笔直的管道流动效果。下面是思考过程草图:

lineMoveAnalysisProcess.png

这是实现效果的几个状态,权当动态看了:

image.png

主要技术就是绘制封闭曲线:

function drawOutLine(
  startX = 100,
  startY = 50,
  length = 200,
  width = 2,
  arc = 10
) {
  ctx.beginPath();
  ctx.lineWidth = width;
  ctx.strokeStyle = '#ff0000';
  ctx.moveTo(startX, startY);
  ctx.arc(startX + arc, startY, arc, Math.PI, 0, false);
  ctx.lineTo(startX + arc * 2, startY + length);
  ctx.arc(startX + arc, startY + length, arc, 0, Math.PI, false);
  ctx.lineTo(startX, startY);
  ctx.closePath();
  ctx.stroke();
}

其次是绘制矩形块:

function drawSmallRect(
  startX = 100,
  startY = 50,
  length = 20,
  width = 2,
  gap = 2
) {
  ctx.fillStyle = 'red';
  ctx.fillRect(startX, startY, width, length);
}

然后是通过管道长度和矩形块长度,决定总共能显示多少块矩形长度。

最后是循环绘制:

let moveInterval = setInterval(() => {
  ctx.clearRect(0, 0, 600, 500);
  drawOutLine(startX, startY, road, 2, 4);
  heightArray.forEach(item => {
    drawSmallRect(startX, item.start + moveY, item.height, 8);
  });
  moveY = moveY + step;

  let firstArrItem = heightArray[0]; // 引用类型
  let lastArrItem = heightArray[arrLen - 1]; // 引用类型

  if (
    moveY - startY >= sRectMargin &&
    moveY - startY < sRectMargin + sRectHeight
  ) {
    firstArrItem.start = startY - moveY;
    firstArrItem.height = moveY - startY - sRectMargin;
    lastArrItem.height = sRectHeight - (moveY - startY - sRectMargin);
  }

  if (moveY - startY > sRectMargin + sRectHeight) {
    isInitStart = true;
    firstArrItem.start = 0;
    firstArrItem.height = 0;
    lastArrItem.height = sRectHeight;
    moveY = moveY - sRectMargin - sRectHeight;
  }
}, speed);

这个是初步实现,运动方向也是固定的。