Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/432.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 创建一个不重复的动画';不要中断先前的通话_Javascript_Html_Animation_Canvas - Fatal编程技术网

Javascript 创建一个不重复的动画';不要中断先前的通话

Javascript 创建一个不重复的动画';不要中断先前的通话,javascript,html,animation,canvas,Javascript,Html,Animation,Canvas,我正在尝试创建一个循环的垂直圆行动画。每行从浏览器的底部开始,到顶部,以0到2秒之间的随机间隔出现。问题是,当动画在时间上靠得太近时,新的动画会中断上一个动画,因此有时圆行不会一直延伸到浏览器的顶部。我怎样才能防止这种情况,而不是一次设置多行动画 这是我的建议 像这样怎么样。我只重新使用了newLine1()函数。在线条绘制结束时(当posY

我正在尝试创建一个循环的垂直圆行动画。每行从浏览器的底部开始,到顶部,以0到2秒之间的随机间隔出现。问题是,当动画在时间上靠得太近时,新的动画会中断上一个动画,因此有时圆行不会一直延伸到浏览器的顶部。我怎样才能防止这种情况,而不是一次设置多行动画

这是我的建议


像这样怎么样。我只重新使用了
newLine1()
函数。在线条绘制结束时(当posY<0时),触发超时以开始另一行

var newLine1 = function(){
  var posX = Math.random() * canvas.width;
  posY = canvas.height;
  timer = setInterval(function() {
    posY -= 20;

    ... drawing code ...

    if(posY < 0) {
      clearInterval(timer);
      setTimeout(newLine1, Math.random() * 2000);
    }
  }, 30);
};
newLine1();

这看起来确实有点不同于我认为你想要的,但我有点喜欢它的效果。不过,我会仔细看看下面@MarkE的答案。我认为他的方法要好得多。没有超时或间隔,它使用的是
requestAnimationFrame
方法,看起来更干净。

这里有一种方法,使用垂直淡入圆圈的上升图像和首选动画循环(requestAnimationFrame)

注释代码和演示:

//画布相关变量
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
var cw=画布宽度;
var ch=画布高度;
//缓存PI*2,因为它经常被使用
var PI2=数学PI*2;
//与圆流相关的变量
var半径=10;
varα=1.00;
var alphaFade=0.05;
//创建内存画布,其中包含
//一连串垂直的圆圈
//顶部alpha=1.00,底部alpha=0.00
//此画布在屏幕画布上绘制图像
//模拟动画圆的步骤
变量streamHeight=(1/alphaFade)*半径*2;
var columnCanvas=document.createElement('canvas');
var columnCtx=columnCanvas.getContext('2d');
columnCanvas.宽度=半径*2;
columnCanvas.height=streamHeight;

对于(var y=radius;yAn我最喜欢的方法就是有一个适当范围的变量名为
working
animating
或其他任何东西。这是初始化为false,但一旦“job”开始,就将其设置为true,然后在完成后将其设置回false。然后在实际运行“wor”之前只需检查var是否为falseker的函数。简单易读。谢谢,这确实解决了问题。但是如果我想在旧的几行圆圈完全退出之前让新的几行圆圈进入屏幕呢?我想让几行不同的圆圈在随机时间进入并相互重叠。你可以在一个循环中执行
timer=setInterval…
记下不同的计时器。今晚晚些时候我会写点东西。谢谢你。
var newLine1 = function(){
  var posX = Math.random() * canvas.width;
  posY = canvas.height;
  timer = setInterval(function() {
    posY -= 20;

    ... drawing code ...

    if(posY < 0) {
      clearInterval(timer);
      setTimeout(newLine1, Math.random() * 2000);
    }
  }, 30);
};
newLine1();
window.onload = function() {

  function LineAnimator(canvas, startX, startY) {
    this.canvas = canvas;
    this.ctx = canvas.getContext('2d');
    this.startX = startX;
    this.startY = startY;
    this.interval = null;
    this.reset();
  }

  LineAnimator.prototype.reset = function() {
    this.posX = 0 + this.startX;
    this.posY = 0 + this.startY;
  }

  /** return false when there's no more to draw */
  LineAnimator.prototype.render = function() {
    this.posY -= 20;
    this.ctx.fillStyle = 'rgba(23,23,23,0.1)';
    this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
    this.ctx.fillStyle = 'white';
    this.ctx.beginPath();
    this.ctx.arc(this.posX, this.posY, 10, 0, twoPi, false);
    this.ctx.fill();
    if (this.posY < 0) {
      return false; /* done rendering */
    }
    else {
      return true;
    }
  };


  var canvas = document.getElementById("paper"),
  c = canvas.getContext("2d"),
  twoPi = Math.PI * 2;

  canvas.width  = 500;
  canvas.height = 700;

  c.fillStyle = "#232323";
  c.fillRect(0, 0, canvas.width, canvas.height);
  c.save();

  var renderLine = function() {
    console.log('render line');
    var posX = Math.random() * canvas.width;
    posY = canvas.height;
    var animator = new LineAnimator(canvas, posX, posY);
    var timer = setInterval(function() {
      if(!animator.render()) {
        console.log('done rendering');        
        clearInterval(timer);
        setTimeout(renderLine, Math.random() * 2000)
      }
    }, 30);
  };
  var ii = 0, 
      nConcurrentLines = 8;
  for (; ii < nConcurrentLines; ++ii ) {
    renderLine();
  }
};