Анимированная кривая Безье на нескольких полотнах - PullRequest
1 голос
/ 07 мая 2019

У меня есть несколько кривых Безье, которые бегут сверху вниз и немного колеблются! Как видно из этого CodePen , кривые кажутся анимированными так, как они должны, но нарисованы не так, как я ожидал. Если я увеличу размер холста, который, кажется, растягивает Безье так, чтобы после определенной высоты он выглядел хорошо, но я не могу понять, что все кривые смяты на небольшой высоте холста, как в этом примере. ниже мой код:

function milestoneLines() {
  //get all canvases from the DOM
  const canvas = document.querySelectorAll('canvas');
  console.log(canvas);
  //loop through array of canvases
  canvas.forEach(makeCanvas);

  function makeCanvas(canvas, index) {
    // get canvas width/height
    canvas.width = $(".main").eq(index).width();
    canvas.height = $(".main").eq(index).height();

    //getting the height of all milestones
    let milestoneHeight = $(".main").eq(index)
      .find('.info_wrapper');
    let totalMilestoneHeight = 0;
    milestoneHeight.each(function() {
      totalMilestoneHeight += $(this).outerHeight();
    });

    const c = canvas.getContext('2d');

    let milestoneHalfHeight = totalMilestoneHeight / 2;
    let milestoneQuarterHeight = totalMilestoneHeight / 4;
    let milestoneHalfWidth = canvas.width / 2;
    let bezEndY = $('.main').eq(index).offset().top +
      $('.main').eq(index).outerHeight();


    let bezStartY = $('.main').eq(index)
      .find(".dot").eq(0).offset().top;

    // Bezier Curve points
    let bezStart = {
      x: milestoneHalfWidth,
      y: bezStartY
    };
    let bezCp1 = {
      x: milestoneHalfWidth - 35,
      y: milestoneHalfHeight
    };
    let bezCp2 = {
      x: milestoneHalfWidth,
      y: milestoneHalfHeight + milestoneQuarterHeight
    };
    let bezEnd = {
      x: milestoneHalfWidth,
      y: bezEndY
    };

    //Line 1
    //dx = xvelocity 
    let dx1Line1 = .6;
    let dx2Line1 = .6;
    let bezCp1Line1x = bezCp1.x;
    let bezCp2Line1x = bezCp2.x;

    //Line 2
    //dx = xvelocity
    let dx1Line2 = .8;
    let dx2Line2 = .8;
    let bezCp1Line2x = bezCp1.x;
    let bezCp2Line2x = bezCp2.x;

    //Line 3
    //dx = xvelocity
    let dx1Line3 = 1;
    let dx2Line3 = 1;
    let bezCp1Line3x = bezCp1.x;
    let bezCp2Line3x = bezCp2.x;

    //Line 4
    //dx = xvelocity
    let dx1Line4 = .9;
    let dx2Line4 = .9;
    let bezCp1Line4x = bezCp1.x;
    let bezCp2Line4x = bezCp2.x;

    function bezCurve() {
      c.clearRect(0, 0, canvas.width, canvas.height);
      //different start positions for the bezier curves
      let bufferX = 120;
      let bufferY = 120;
      let bufferStartY = 80;

      for (var i = 0; i < 4; i++) {
        c.beginPath();
        if (i == 0) {
          c.moveTo(bezStart.x, bezStart.y + bufferStartY);
          c.bezierCurveTo(bezCp1Line1x - bufferX, bezCp1.y - bufferY, bezCp2Line1x + bufferX, bezCp2.y - bufferY, bezEnd.x, bezEnd.y);

          if (bezCp1Line1x > (bezCp1.x + 280) || bezCp1Line1x < bezCp1.x) {
            dx1Line1 = -dx1Line1;

          }
          if (bezCp2Line1x < (bezCp2.x - 280) || bezCp2Line1x > bezCp2.x) {
            dx2Line1 = -dx2Line1;
          }
          bezCp1Line1x -= dx1Line1;
          bezCp2Line1x += dx2Line1;
          c.strokeStyle = "red";
        }
        if (i == 2) {
          c.moveTo(bezStart.x, bezStart.y + bufferStartY);
          c.bezierCurveTo(bezCp1Line3x + bufferX, bezCp1.y + bufferY, bezCp2Line3x - bufferX, bezCp2.y + bufferY, bezEnd.x, bezEnd.y);

          if (bezCp1Line3x < (bezCp1.x - 320) || bezCp1Line3x > bezCp1.x) {
            dx1Line3 = -dx1Line3;
          }

          if (bezCp2Line3x > (bezCp2.x + 320) || bezCp2Line3x < bezCp2.x) {
            dx2Line3 = -dx2Line3;
          }
          bezCp1Line3x -= dx1Line3;
          bezCp2Line3x += dx2Line3;
          c.strokeStyle = "green";

        }
        if (i == 1) {
          c.moveTo(bezStart.x, bezStart.y + bufferStartY);
          c.bezierCurveTo(bezCp1Line2x + bufferX, bezCp1.y + bufferY, bezCp2Line2x - bufferX, bezCp2.y + bufferY, bezEnd.x, bezEnd.y);

          if (bezCp1Line2x < (bezCp1.x - 350) || bezCp1Line2x > bezCp1.x) {
            dx1Line2 = -dx1Line2;
          }

          if (bezCp2Line2x > (bezCp2.x + 350) || bezCp2Line2x < bezCp2.x) {
            dx2Line2 = -dx2Line2;
          }
          bezCp1Line2x -= dx1Line2;
          bezCp2Line2x += dx2Line2;
          c.strokeStyle = "blue";

        }
        if (i == 3) {
          c.moveTo(bezStart.x, bezStart.y + bufferStartY);
          c.bezierCurveTo(bezCp1Line4x - bufferX, bezCp1.y - bufferY, bezCp2Line4x + bufferX, bezCp2.y - bufferY, bezEnd.x, bezEnd.y);

          if (bezCp1Line4x > (bezCp1.x + 320) || bezCp1Line4x < bezCp1.x) {
            dx1Line4 = -dx1Line4;
          }
          if (bezCp2Line4x < (bezCp2.x - 320) || bezCp2Line4x > bezCp2.x) {
            dx2Line4 = -dx2Line4;
          }
          bezCp1Line4x -= dx1Line4;
          bezCp2Line4x += dx2Line4;
          c.strokeStyle = "grey";

        }
        c.lineWidth = 6;
        //c.strokeStyle = "#FCE6DF";
        c.stroke();
        bufferX = bufferX - 30;
        bufferY = bufferY - 30;
        bufferStartY = bufferStartY - 20;
      }
      requestAnimationFrame(bezCurve);
    }
    bezCurve();
  }
}
$(document).ready(milestoneLines);
#milestone_canvas {
  position: absolute;
}

.main {
  background-color: wheat;
}

.info_wrapper {
  margin-top: 70px;
  margin-bottom: 50px;
  border: solid 2px;
}

.container {
  height: 50%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
}

.dot {
  width: 30px;
  height: 30px;
  border-radius: 20px;
  background-color: maroon;
  border: solid 4px green;
  z-index: 100;
}

.header {
  width: 100%;
  height: 50px;
  background-color: lightblue;
}

.text {
  float: left;
  position: absolute;
  max-width: 500px;
}
<div class="main">
  <canvas id="milestone_canvas"> </canvas>
  <div class="header"></div>
  <div class="container">
    <div class="info_wrapper">
      <div class="text">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      </div>
      <div class="dot "></div>
    </div>
    <div class="info_wrapper">
      <div class="text">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      </div>
      <div class="dot "></div>
    </div>
    <div class="info_wrapper">
      <div class="text">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      </div>
      <div class="dot "></div>
    </div>
    <div class="info_wrapper">
      <div class="text">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      </div>
      <div class="dot "></div>
    </div>
    <div class="info_wrapper">
      <div class="text">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
      </div>
      <div class="dot "></div>
    </div>
  </div>
</div>
...