HTML5 Canvas动画在底部稳定下来

时间:2016-11-08 14:13:18

标签: javascript jquery html css html5

我有点卡住了我的动画,我设置了true / false来解决页面底部的纸屑达到一定的高度......任何人都对如何做到这一点有任何想法...而不是新的到JS。

我想会使用

的某种条件
var confettiSettle = true;

...

if (confettiSettle == true){
    ...
}

(function() {
  var canvas;
  var ctx;
  var confettiHandler;
  //canvas dimensions
  var W;
  var H;
  var mp = 150; //max particles
  var particles = [];
  var angle = 0;
  var tiltAngle = 0;
  var confettiActive = true;
  var confettiSettle = true;
  var animationComplete = true;
  var deactivationTimerHandler;
  var reactivationTimerHandler;
  var animationHandler;
  var colorOptions = ["DodgerBlue", "OliveDrab", "Gold", "pink", "SlateBlue", "lightblue", "Violet", "PaleGreen", "SteelBlue", "SandyBrown", "Chocolate", "Crimson"];
  $(window).resize(function() {
    canvas = document.getElementById("canvas");
    W = window.innerWidth;
    H = window.innerHeight;
    canvas.width = W;
    canvas.height = H;
  });
  $(document).ready(function() {
    $('#stopButton').click(DeactivateConfetti);
    $('#startButton').click(RestartConfetti);
    $('#settleButton').click(SettleConfetti);
    canvas = document.getElementById("canvas");
    ctx = canvas.getContext("2d");
    W = window.innerWidth;
    H = window.innerHeight;
    canvas.width = W;
    canvas.height = H;
    InitializeConfetti();
  });

  function InitializeConfetti() {
    var currentColorIndex = 0;
    var colorCount = 0;
    particles = [];
    animationComplete = false;
    for (var i = 0; i < mp; i++) {
      if (colorCount >= 10) {
        colorCount = 0;
        currentColorIndex++;
        if (currentColorIndex >= colorOptions.length) {
          currentColorIndex = 0;
        }
      }
      colorCount++;
      var particleColor = colorOptions[currentColorIndex];
      particles.push({
        x: Math.random() * W, //x-coordinate
        y: (Math.random() * H) - H, //y-coordinate
        r: randomFromTo(10, 30), //radius
        d: (Math.random() * mp) + 10, //density
        color: particleColor,
        tilt: Math.floor(Math.random() * 10) - 10,
        tiltAngleIncremental: (Math.random() * 0.07) + .05,
        tiltAngle: 0
      });
    }
    StartConfetti();
  }

  function drawConfetti(particle) {
    ctx.beginPath();
    ctx.lineWidth = particle.r / 2;
    ctx.strokeStyle = particle.color;
    ctx.moveTo(particle.x + particle.tilt + (particle.r / 4), particle.y);
    ctx.lineTo(particle.x + particle.tilt, particle.y + particle.tilt + (particle.r / 4));
    return ctx.stroke();
  };

  function draw() {
    ctx.clearRect(0, 0, W, H);
    var results = [];
    for (var i = 0; i < mp; i++) {
      (function(j) {
        results.push(drawConfetti(particles[j]));
      })(i);
    }
    update();

    return results;
  }

  function randomFromTo(from, to) {
    return Math.floor(Math.random() * (to - from + 1) + from);
  }


  function update() {
    var remainingFlakes = 0;
    angle += 0.01;
    tiltAngle += 0.1;
    for (var i = 0; i < mp; i++) {
      if (animationComplete) return;
      var p = particles[i];
      p.tiltAngle += p.tiltAngleIncremental;
      if (!confettiActive && p.y < -15) {
        p.y = H + 100;
      } else {
        p.y += (Math.cos(angle + p.d) + 3 + p.r / 2) / 5;
      }

      p.x += Math.sin(angle);
      p.tilt = (Math.sin(p.tiltAngle - (i / 3))) * 15;
      if (p.y <= H) {
        remainingFlakes++;
      }
      if ((p.x > W + 20 || p.x < -20 || p.y > H) && confettiActive) {
        if (i % 5 > 0 || i % 2 == 0) //66.67% of the flakes
        {
          particles[i] = {
            x: Math.random() * W,
            y: -10,
            r: p.r,
            d: p.d,
            color: p.color,
            tilt: Math.floor(Math.random() * 10) - 10,
            tiltAngle: p.tiltAngle,
            tiltAngleIncremental: p.tiltAngleIncremental
          };
        } else {
          if (Math.sin(angle) > 0) {
            //Enter from the left
            particles[i] = {
              x: -5,
              y: Math.random() * H,
              r: p.r,
              d: p.d,
              color: p.color,
              tilt: Math.floor(Math.random() * 10) - 10,
              tiltAngleIncremental: p.tiltAngleIncremental
            };
          } else {
            //Enter from the right
            particles[i] = {
              x: W + 5,
              y: Math.random() * H,
              r: p.r,
              d: p.d,
              color: p.color,
              tilt: Math.floor(Math.random() * 10) - 10,
              tiltAngleIncremental: p.tiltAngleIncremental
            };
          }
        }
      }
    }
    if (remainingFlakes === 0) {
      StopConfetti();
    }
  }

  function StartConfetti() {
    W = window.innerWidth;
    H = window.innerHeight;
    canvas.width = W;
    canvas.height = H;
    (function animloop() {
      if (animationComplete) return null;
      animationHandler = requestAnimFrame(animloop);
      return draw();
    })();
  }

  function ClearTimers() {
    clearTimeout(reactivationTimerHandler);
    clearTimeout(animationHandler);
  }

  function DeactivateConfetti() {
    confettiActive = false;
    ClearTimers();
    console.log('deactivate');
  }

  function StopConfetti() {
    animationComplete = true;
    if (ctx == undefined) return;
    ctx.clearRect(0, 0, W, H);
  }

  function RestartConfetti() {
    ClearTimers();
    StopConfetti();
    reactivationTimerHandler = setTimeout(function() {
      confettiActive = true;
      animationComplete = false;
      InitializeConfetti();
    }, 100);
  }
  
  function SettleConfetti() {
		
  }

  window.requestAnimFrame = (function() {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
      return window.setTimeout(callback, 1000 / 60);
    };
  })();
})();
canvas {
  display: block;
  position: relative;
  z-index: 1;
  pointer-events: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<canvas id="canvas"></canvas>

1 个答案:

答案 0 :(得分:1)

所以我们需要做的是,当粒子落下时,我们添加一个解决条件,即如果sett flag设置为true。这种情况将属于update()方法,其中粒子尺寸和角度被重新调整以保持其下降。

在沉降条件下,我们检查粒子是否到达底部的特定区域,距离底部高度约为60像素。如果有,那么我们跳过它的调整以保持它在同一地点。

以下是示例:http://codepen.io/Nasir_T/pen/vyOvxL (检查与解决变量和代码中的方法相关的注释以便理解)

单击左上方的结算按钮,使五彩纸屑下降,然后单击开始按钮再次启动它。

希望这有帮助。