title: Integrate GSAP with canvas to make a curvy timeline
body: <p>I'm currently working on a canvas timeline-like animation.</p>
  
  <p>This is what I made so far...</p>
  
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>$(function() {
    'use strict';
  
    var canvas = document.querySelector('#canvas');
    var ctx = canvas.getContext('2d');
    var s = 20;
    var arr = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100];
    var colorP = ['#ff5454', '#ffa144', '#ffe256', '#aaff75', '#8cd8ff', '#b5b6ff', '#b882ff'];
    var dots = [];
    var rDots = [];
  
    function init() {
      var reverse = true;
      for (var i = 0; i &lt; 100; i++) {
        var dot = new Object();
        var height = null;
        if (arr.indexOf(i) != -1) {
          dot.x = s;
          dot.y = 50;
          dot.r = 3;
          dot.c = 'red';
          dot.f = 'rgba(0,0,0,0)';
          dot.t = '1';
          dot.s = 0;
  
          rDots.push(dot);
        } else {
          dot.x = s;
          dot.y = 50;
          dot.r = 1;
          dot.c = 'red';
          dot.f = '';
          dot.t = '';
          dot.s = 0;
        }
        s += 10;
        dots.push(dot);
      };
  
      function tween() {
        height = Math.floor(Math.random() * (75 - 25) + 25);
        TweenMax.staggerTo(dots, 5, {
          y: height,
          yoyo: true,
          repeat: 'repeat',
          repeatDelay: 1,
          ease: Sine.easeInOut
        }, 0.5);
      };
      tween();
      setInterval(function() {
        tween()
      }, 4800);
    }
    init();
  
    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
  
      for (var i = 0; i &lt; dots.length - 1; i++) {
        ctx.beginPath();
        ctx.moveTo(dots[i].x, dots[i].y);
        ctx.lineTo(dots[i + 1].x, dots[i + 1].y);
        ctx.lineWidth = 3;
        ctx.strokeStyle = 'red';
        ctx.stroke();
      };
  
      for (var i = 0; i &lt; dots.length; i++) {
        ctx.beginPath();
        ctx.arc(dots[i].x, dots[i].y, dots[i].r, 0, 2 * Math.PI);
        ctx.strokeStyle = dots[i].c;
        ctx.lineWidth = 1;
        ctx.fillStyle = dots[i].f;
        ctx.fill();
        ctx.stroke();
        ctx.font = dots[i].s + 'px Arial';
        ctx.textAlign = 'center';
        ctx.fillStyle = '#FFF';
        ctx.fillText(dots[i].t, dots[i].x, dots[i].y + 4);
      };
  
      setTimeout(function() {
        draw();
      }, 5);
    }
    draw();
  
    function hover(e, bool) {
      var dot = canvas.getBoundingClientRect();
      var x = e.clientX - dot.left;
      var y = e.clientY - dot.top;
  
      for (var i = 0; i &lt; rDots.length; i++) {
        if (x == rDots[i].x) {
          TweenMax.to(rDots[i], 0.1, {
            r: 10,
            f: 'red',
            s: 8
          });
          $('body').css('cursor', 'pointer');
        } else {
          TweenMax.to(rDots[i], 0.1, {
            r: 3,
            f: 'rgba(0,0,0,0)',
            s: 0
          });
        }
      };
    };
  
    $(canvas).on('mousemove', function(e) {
      hover(e, true);
    });
  
  });</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;
  &lt;canvas id="canvas" height="100" width="1050" style="background: #EEE"&gt;&lt;/canvas&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenMax.min.js"&gt;&lt;/script&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>The idea is,</p>
  
  <p>I want it to swing randomly (checked)</p>
  
  <p>and when the cursor close in the knot, it will enlarge and show the text in it...</p>
  
  <p>I tried to use x and y axis to do the trick,</p>
  
  <p>but it doesn't work well...</p>
  
  <p>Then I tried to make another function to draw a bigger circle to cover the original knot,</p>
  
  <p>but since my draw() keeping clear the canvas, so I failed again...</p>
  
  <p>Wondering is there any better ways to make it work?</p>
  
  <p>any suggestions or hints are welcome!</p>