将GSAP与画布集成以制作曲线时间轴

时间:2017-02-17 04:22:46

标签: javascript html5 animation canvas html5-canvas

我目前正在制作类似画布时间轴的动画。

这是我到目前为止所做的......



$(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 < 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 < 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 < 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 < 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);
  });

});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" height="100" width="1050" style="background: #EEE"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenMax.min.js"></script>
&#13;
&#13;
&#13;

这个想法是,

我希望它随机摆动(检查)

当光标在结中关闭时,它会放大并显示其中的文字......

我尝试使用x和y轴来完成这个技巧,

但它不能很好地运作......

然后我尝试制作另一个函数来绘制一个更大的圆圈来覆盖原始的结,

但是因为我的画布()保持画布清晰,所以我又失败了......

想知道有没有更好的方法让它发挥作用?

欢迎任何建议或提示!

2 个答案:

答案 0 :(得分:0)

您可能会发现jCanvas有帮助。

它是一个包裹HTML5画布API的JavaScript库,允许您使用jQuery样式语法添加某些类似对象的功能。您可以稍微重构一下代码并使用mouseOver效果而不是将mousemove事件绑定到画布上,这样可以创建一个更加动画的动画。

此外,如果你增加触发动画的rDots.x的区域并将你的Tween时间间隔设置为略长于0.1的值,这会使动画稍微不那么生涩。

不确定这是否解决了您的问题,但我希望它有所帮助!

答案 1 :(得分:0)

好的,我已经出去了。

$(function() {
  'use strict';

  var dots = [],
    eDots = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100],
    rDots = [],
    stagger = 0;

  var canvas = document.querySelector('#canvas'),
    ctx = canvas.getContext('2d');

  //initialize all the dots obj
  function init() {
    for (var i = 0; i < 100; i++) {
      if (eDots.indexOf(i) != -1) {
        var dot = {
          xAxis: stagger,
          yAxis: 50,
          radius: 3,
          color: 'rgba(0,0,0,0)',
          num: 1,
        };
        rDots.push(dot);
      } else {
        var dot = {
          xAxis: stagger,
          yAxis: 50,
          radius: .5,
          color: 'rgba(0,0,0,0)',
          num: ''
        };
      }
      dots.push(dot);
      stagger += 10;
    }
  };
  init();

  //Save position property for click event
  function getSize() {
    for (var i = 0; i < rDots.length; i++) {
      rDots[i].top = rDots[i].yAxis - rDots[i].radius;
      rDots[i].right = rDots[i].xAxis + rDots[i].radius;
      rDots[i].bottom = rDots[i].yAxis + rDots[i].radius;
      rDots[i].left = rDots[i].xAxis - rDots[i].radius;
    }
  }
  getSize();

  //Hover event dots to change style
  function hover() {
    $(canvas).bind('mousemove', function(e) {
      var dot = canvas.getBoundingClientRect(),
        x = e.clientX - dot.left,
        y = e.clientY - dot.top;

      for (var i = 0; i < rDots.length; i++) {
        ctx.beginPath();
        ctx.arc(rDots[i].xAxis, rDots[i].yAxis, rDots[i].radius, 0, 2 * Math.PI);
        //rDots[i].radius = ctx.isPointInPath(x, y) ? 10 : 3;
        //rDots[i].color = ctx.isPointInPath(x, y) ? 'red' : 'rgba(0, 0, 0, 0)';
        if (ctx.isPointInPath(x, y)) {
          TweenMax.to(rDots[i], 0.1, {
            radius: 10,
            color: 'red',
          });
          $(canvas).css({
            cursor: 'pointer'
          });
          return;
        } else {
          TweenMax.to(rDots[i], 0.1, {
            radius: 3,
            color: 'rgba(0,0,0,0)'
          });
        }
        ctx.stroke();
        ctx.fill();
        $(canvas).css({
          cursor: 'default'
        });
      }
    });
  };
  hover();

  //Setup click event for functioning purpose
  function click(e) {
    var dot = canvas.getBoundingClientRect(),
      x = e.clientX - dot.left,
      y = e.clientY - dot.top;

    for (var i = 0; i < rDots.length; i++) {
      if (x < rDots[i].right && x > rDots[i].left && y > rDots[i].top && y < rDots[i].bottom) {
        console.log('This is dot ' + i);
      }
    }
  };
  $(canvas).on('click', function(e) {
    click(e);
  })

  //Let the line start to twist
  function tween() {
    var height = Math.floor(Math.random() * (75 - 25) + 25);
    TweenMax.staggerTo(dots, 4, {
      yAxis: height,
      yoyo: true,
      repeat: 'repeat',
      repeatDelay: 1,
      ease: Sine.easeInOut
    }, 0.5);

    setTimeout(function() {
      tween();
    }, 3800);
  }
  tween();

  //Let's get some paint
  function draw() {
    //clear canvas for animate
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    //draw the lines
    for (var i = 0; i < dots.length - 1; i++) {
      ctx.moveTo(dots[i].xAxis, dots[i].yAxis);
      ctx.lineTo(dots[i + 1].xAxis, dots[i + 1].yAxis);
      ctx.lineWidth = 3;
      ctx.stroke();
    }

    //draw the dots
    for (var i = 0; i < dots.length; i++) {
      ctx.beginPath();
      ctx.arc(dots[i].xAxis, dots[i].yAxis, dots[i].radius, 0, 2 * Math.PI);
      ctx.strokeStyle = 'red';
      ctx.strokeWidth = '1px';
      ctx.fillStyle = dots[i].color;
      ctx.stroke();
      ctx.fill()
    };

    setTimeout(function() {
      draw();
    }, 10);
  }
  draw();

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenMax.min.js"></script>
<canvas id="canvas" height="100" width="1000" style="background:#EEE"></canvas>

我需要做的只是使用isPointOnPath来获取路径的轴,

然后使用if语句操纵某个点的属性,在我的例子中是它的半径和颜色。

够简单......

无法相信我无法理解。

我想我现在需要睡一觉XD