How to keep smooth lines when drawing out animated bezier curves in html5 canvas

Grant

I finally found out how to animate drawing a bezier curve. I've seen other solutions that use quadratic curves to do it, but I needed 4 points for what I was doing, and b-spline was too difficult finding random plots, plus it's just how I want to do it; with Bezier Cuves.

My issue is I can't find a good, fast speed without seeing the dots or lines. I've gotta be missing something. Could someone point out my error or a more efficient way to get this going smoothly at any time/speed? I need it to be steady and go faster than the example below, but if I do anymore the gaps get larger and larger...

fiddle with code: https://jsfiddle.net/qzsy8aL7/

//B(t) = (1 - t)^3P0 + 3t(1 - t)^2 P1 + 3t^2(1 - t)P2 + t^3P3
function animatedBSpline(context, points, t) {
    // Draw curve segment
    context.beginPath();
    context.moveTo(
    Math.pow(1 - t, 3) * points[0].x +
    3 * t * Math.pow(1 - t, 2) * points[1].x +
    3 * Math.pow(t, 2) * (1 - t) * points[2].x +
    Math.pow(t, 3) * points[3].x,

    Math.pow(1 - t, 3) * points[0].y +
    3 * t * Math.pow(1 - t, 2) * points[1].y +
    3 * Math.pow(t, 2) * (1 - t) * points[2].y +
    Math.pow(t, 3) * points[3].y
  );

  // Draw spline segemnts
  context.lineTo(
    Math.pow((1 - t) + 0.001, 3) * points[0].x +
    3 * (t + 0.001) * Math.pow((1 - t) + 0.001, 2) * points[1].x +
    3 * Math.pow(t + 0.001, 2) * (1 - (t + 0.001)) * points[2].x +
    Math.pow(t + 0.001, 3) * points[3].x,

    Math.pow((1 - t) + 0.001, 3) * points[0].y +
    3 * (t + 0.001) * Math.pow((1 - t) + 0.001, 2) * points[1].y +
    3 * Math.pow(t + 0.001, 2) * (1 - (t + 0.001)) * points[2].y +
    Math.pow(t + 0.001, 3) * points[3].y
  );

  //33d4ff
  context.strokeStyle="#35bb23";
  context.lineJoin="round";
  context.lineWidth=2;
  context.fillStyle = "black";
  context.stroke();
  context.fill();

  // Keep going until t = 1
  if (t < 1) requestAnimationFrame(function() {
    animatedBSpline(context, points, t + 0.01);
  });
  else
    context.closePath();
}

If any more information is needed please let me know. I've been at this all day.

To add: If I just outright draw it with these plots, and not animate it being done, it looks fine, obviously, but just wanted to point that out. Its something with the way I'm animating it I just don't know.

Patrick Roberts

Here's the full updated code with animation of green bezier curve:

(function() {
  var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;

  $(function() {
    var canvas = $('#drawings')[0];
    var context = canvas.getContext('2d');
    var lineLength = 0;
    var lineLengthMax = 7;
    var timer;

    // Define points
    var points = [[{
      x: 600,
      y: 200
    }, {
      x: 550,
      y: 100
    }, {
      x: 350,
      y: 100
    }, {
      x: 300,
      y: 250
    }],
    [{
      x: 350,
      y: 250
    }, {
      x: 75,
      y: 225
    }, {
      x: 30,
      y: 400
    }, {
      x: 120,
      y: 450
    }],
    [{
      x: 200,
      y: 450
    }, {
      x: 5,
      y: 380
    }, {
      x: 25,
      y: 750
    }, {
      x: 175,
      y: 610
    }],
    [{
      x: 200,
      y: 520
    }, {
      x: 150,
      y: 560
    }, {
      x: 175,
      y: 750
    }, {
      x: 325,
      y: 605
    }],
    [{
      x: 400,
      y: 395
    }, {
      x: 275,
      y: 450
    }, {
      x: 250,
      y: 750
    }, {
      x: 565,
      y: 655
    }],
    [{
      x: 515,
      y: 540
    }, {
      x: 500,
      y: 695
    }, {
      x: 660,
      y: 675
    }, {
      x: 675,
      y: 560
    }],
    [{
      x: 600,
      y: 400
    }, {
      x: 790,
      y: 315
    }, {
      x: 1005,
      y: 500
    }, {
      x: 675,
      y: 585
    }],
    [{
      x: 500,
      y: 250
    }, {
      x: 700,
      y: 100
    }, {
      x: 775,
      y: 350
    }, {
      x: 700,
      y: 380
    }]];

    //33d4ff
    context.strokeStyle="#35bb23";
    context.lineJoin="round";
    context.lineWidth=2;

    doLineDraw();
    //animatedBSpline(context, points, 0);

    function doLineDraw() {
      if (lineLength <= lineLengthMax) {
        clearTimeout(timer);

        // Kick things off at t = 0
        context.beginPath();
        animatedBSpline(context, points[lineLength], 0);
        //animatedBSpline(context, eval('points'+(lineLength)), 0);

        lineLength++;
        if (lineLength <= lineLengthMax)
          timer = setTimeout(doLineDraw, 2000);
      }
    }

    //B(t) = (1 - t)^3P0 + 3t(1 - t)^2 P1 + 3t^2(1 - t)P2 + t^3P3
    function animatedBSpline(context, points, t) {
      // Draw curve segment
      if (t == 0)
        context.moveTo(
          Math.pow(1 - t, 3) * points[0].x +
          3 * t * Math.pow(1 - t, 2) * points[1].x +
          3 * Math.pow(t, 2) * (1 - t) * points[2].x +
          Math.pow(t, 3) * points[3].x,

          Math.pow(1 - t, 3) * points[0].y +
          3 * t * Math.pow(1 - t, 2) * points[1].y +
          3 * Math.pow(t, 2) * (1 - t) * points[2].y +
          Math.pow(t, 3) * points[3].y
        );
      
      // Draw spline segemnts
      context.lineTo(
        Math.pow((1 - t) + 0.001, 3) * points[0].x +
        3 * (t + 0.001) * Math.pow((1 - t) + 0.001, 2) * points[1].x +
        3 * Math.pow(t + 0.001, 2) * (1 - (t + 0.001)) * points[2].x +
        Math.pow(t + 0.001, 3) * points[3].x,

        Math.pow((1 - t) + 0.001, 3) * points[0].y +
        3 * (t + 0.001) * Math.pow((1 - t) + 0.001, 2) * points[1].y +
        3 * Math.pow(t + 0.001, 2) * (1 - (t + 0.001)) * points[2].y +
        Math.pow(t + 0.001, 3) * points[3].y
      );
			
      
      //context.fillStyle = "black";
      context.stroke();
      //context.fill();
			
      // Keep going until t = 1
      if (t < 1) requestAnimationFrame(function() {
        animatedBSpline(context, points, t + 0.01);
      });
    }
  });
}());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
  <article>
    <canvas id="drawings" width="1000" height="1000" />
  </article>
</section>

A couple key points, some of which were tangential to the question.

  • Avoid using eval for referencing variable names which have numbers post-fixed. Just use an array instead.
  • The reason you were drawing points instead of lines was because you called context.beginPath() and context.moveTo() before every new vertex, which causes context.stroke() and context.fill() to "forget" the previous instructions.

I moved the context.beginPath() outside of animatedBSpline() and specified context.moveTo() to run at t==0 within that function, that way there are no disjointed points. I hope that helps.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Drawing animated curves in canvas

HTML5 Canvas lines not drawing

Drawing Bezier curves in MonoGame (XNA) produces scratchy lines

How to keep drawing on canvas when scrolling?

How to smooth the joint of lines in bezier path?

Drawing crisp 1px lines on HTML5 canvas when using transformations

How to expand shape created from a lot of bezier curves (JavaScript and canvas)

HTML5 Canvas: Drawing lines along text baselines

How can I know when HTML5 Canvas finished drawing?

Drawing random paths with quadratic bezier curves

Drawing on a HTML5 Canvas: how to draw at tip of mouse cursor

How to make drawing draggable on canvas in HTML5

How to make my drawing move inside HTML5 canvas?

Html5 canvas not drawing

HTML5 Canvas: Not drawing

Ios drawing lines animated

How to connect multiple bezier curves?

HTML 5 Canvas drawing a straight smooth line example?

Antialiasing when drawing lines in Canvas in Firefox

HTML5 Canvas alpha transparency doesn't work in firefox for curves when window is big

How to draw a lowercase b with Quadratic Bezier Curve on HTML5 canvas

How to get bezier curve size in HTML5 canvas with cp2 point?

How to keep an object inside a html5 canvas?

How to create road lines using HTML5 canvas

How to draw sharp curves and angled lines on Canvas in Android

HTML5 Canvas diagonal lines get thicker or bolder after drawing another line somewhere else on the canvas (not on top)

HTML5 Canvas, How to show animated attacks between two points

Drawing a parallelogram HTML5 Canvas

Html5 canvas pattern drawing delay