簡體   English   中英

HTML5畫布落紙屑/下雪多個對象

[英]HTML5 Canvas Falling Confetti / Snow Multiple Objects

我從以下示例開始: http : //thecodeplayer.com/walkthrough/html5-canvas-snow-effect

我正在嘗試添加下落物體的多種形狀。 但是,只有我撥打的最后一個似乎有效。 它會覆蓋屏幕上的其他內容。

我想做的另一件事是從數組中隨機化顏色,但是當我添加隨機函數時,我會得到瘋狂的變色效果。 我不完全了解發生了什么,這是我第一次涉獵畫布。 似乎每個幀都在重畫對象。 由於全都是白色圓圈,因此適用於雪地。

知道如何進行這些更改嗎? 這是我的代碼(SEIZURE WARNING!): http : //codepen.io/paper_matthew/pen/vGpyeq

HTML

<canvas id="confetti"></canvas>

<div id="party-info">

  <h2>PARTY!!</h2>
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deserunt impedit animi enim iste repellat aliquam laborum consequuntur asperiores neque eos praesentium quis, consectetur cupiditate suscipit cum inventore excepturi? Vel, laudantium.</p>
</div>

CSS

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  background-color: #fff;
  overflow: hidden;
}

#confetti {
  position: relative;
  top:0;
  left: 0;
  z-index: 1;
}

#party-info {
  position: absolute;
  background: #fff;
  padding: 20px;
  margin: 0 auto;
  height: 200px;
  top: 0;
  left: 0;
  right: 0;
  bottom:0;
  text-align: center;
  width: 400px;
  z-index: 22;
  color: gray;
}

使用Javascript

window.onload = function() {
  //canvas init
  var canvas = document.getElementById("confetti");
  var ctx = canvas.getContext("2d");

  COLORS = [
    [238, 96, 169],
    [68, 213, 217],
    [245, 187, 152],
    [144, 148, 188],
    [235, 234, 77]
  ];

  //canvas dimensions
  var W = window.innerWidth;
  var H = window.innerHeight;
  canvas.width = W;
  canvas.height = H;

  //particles
  var mp = 100; //max particles
  var particles = [];
  for (var i = 0; i < mp; i++) {
    particles.push({
      x: Math.random() * W, //x-coordinate
      y: Math.random() * H, //y-coordinate
      r: Math.random() * 4 + 1, //radius
      d: Math.random() * mp //density
    })
  }

  // Draw the shapes
  function drawCircle() {

    ctx.clearRect(0, 0, W, H);
    ctx.fillStyle = "rgba(" + COLORS[Math.floor(Math.random()*5+0)] + ", 0.8)";
    ctx.beginPath();
    for (var i = 0; i < mp; i++) {
      var p = particles[i];

      ctx.moveTo(p.x, p.y);
      ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2, true);

    }
    ctx.fill();
    update();

  }

  function drawTriangle() {

    ctx.clearRect(0, 0, W, H);
    ctx.fillStyle = "rgba(" + COLORS[2] + ", 0.8)";
    ctx.beginPath();
    for (var i = 0; i < mp; i++) {
      var p = particles[i];

      ctx.moveTo(p.x, p.y);
      ctx.lineTo(p.x + 15, p.y);
      ctx.lineTo(p.x + 15, p.y + 15);
      ctx.closePath();

    }
    ctx.fill();
    update();

  }

  function drawLine() {
    ctx.clearRect(0, 0, W, H);
    ctx.strokeStyle = "rgba(" + COLORS[3] + ", 0.8)";
    ctx.beginPath();
    for (var i = 0; i < mp; i++) {
      var p = particles[i];

      ctx.moveTo(p.x, p.y);
      ctx.lineTo(p.x, p.y + 20);
      ctx.lineWidth = 2;

    }
    ctx.stroke();
    update();
  }

  function update() {

    for (var i = 0; i < mp; i++) {
      var p = particles[i];
      p.y += Math.cos(p.d) + 1 + p.r / 2;
      p.x += Math.sin(0) * 2;

      if (p.x > W + 5 || p.x < -5 || p.y > H) {
        particles[i] = {
          x: Math.random() * W,
          y: -10,
          r: p.r,
          d: p.d
        };
      }
    }
  }

  function drawShapes() {
    drawTriangle();
    drawLine();
    drawCircle();
  }

  //animation loop
  setInterval(drawShapes, 33);

}

您正在調用drawShapes(),它緊接着彼此繪制三個形狀。 Var ctx是全局的,因此每個繪圖都會立即覆蓋前一個繪圖。

畫布上的任何動畫循環都需要重復調​​用update()和draw()。 您應該更新模型,然后繪制到畫布上。 沖洗並重復。

我創建了一個新的Javascript文件來與您的HTML / CSS一起使用。 它允許創建粒子對象,它可以是3種類型之一:

  1. 三角形

然后,我創建這些對象類型的數組。 每種類型的三分之一將填充到數組中。 然后,我簡單地循環訪問這些對象,並分別在我的動畫和更新函數中的動畫循環中調用每個對象的update和draw方法。

這是將粒子數減少到40以提高平滑動畫速度的代碼:

function Particle(ctx, width, height, maxParticles, particleType) {
    COLORS = [
        [238, 96, 169],
        [68, 213, 217],
        [245, 187, 152],
        [144, 148, 188],
        [235, 234, 77]
    ];
    var ctx = ctx;
    var width = width;
    var height = height;
    var maxParticles = maxParticles;
    var particleType = particleType;
    var color = COLORS[Math.floor(Math.random() * 5)];

    var x = Math.random() * width;
    var y = Math.random() * height;
    var r = Math.random() * 4 + 1;
    var d = Math.random() * maxParticles;

    this.update = function() {
        y += Math.cos(d) + 1 + (r / 2);
        x += Math.sin(0) * 2;
        if (x > width + 5 || x < -5 || y > height) {
            x = Math.random() * width;
            y = -10;
        }
    };

    this.draw = function() {
        ctx.save();
        ctx.strokeStyle = "rgba(" + color + ", 0.8)";
        ctx.fillStyle = ctx.strokeStyle;
        ctx.beginPath();
        for (var i = 0; i < maxParticles; i++) {
            ctx.moveTo(x, y);
            switch (particleType) {
            case 1:
                ctx.arc(x, y, r, 0, Math.PI * 2, false);
                ctx.fill();
                break;
            case 2:
                ctx.lineTo(x + 15, y);
                ctx.lineTo(x + 15, y + 15);
                ctx.fill();
                break;
            case 3:
                ctx.lineWidth = 2;
                ctx.lineTo(x, y + 20);
                ctx.stroke();
                break;
            default:
                console.log('Unable to draw: undefined particle type [' + particleType + ']');
                break;
            }
        }

        ctx.restore();
    };
}

window.onload = function() {
    //canvas init
    var canvas = document.getElementById("confetti");
    var ctx = canvas.getContext("2d");

    //canvas dimensions
    var W = window.innerWidth;
    var H = window.innerHeight;
    canvas.width = W;
    canvas.height = H;

    //particles
    var mp = 40;
    var particles = [];
    for (var i = 0; i < mp; i++) {
        var type = Math.floor(i * 3 / mp) + 1;
        particles.push(new Particle(ctx, W, H, particles.length, type));
    }

    function drawShapes() {
        update();
        draw();
        setTimeout(drawShapes, 20);
    }

    function update() {
        for (var key in particles) {
            particles[key].update();
        }
    }

    function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        for (var key in particles) {
            particles[key].draw();
        }
    }

    //animation loop
    drawShapes();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM