2016-04-07 18 views
1

私はこの例から始まっは:http://thecodeplayer.com/walkthrough/html5-canvas-snow-effectHTML5キャンバス落ちる紙吹雪/雪複数のオブジェクト

私は落下物の複数の図形を追加しようとしています。しかし、私が最後に呼んだのはうまくいくようです。それは画面上の他のものを上書きします。

私がやろうとしているもう一つのことは、配列から色をランダム化することですが、ランダム関数を追加すると、狂った色の変化する効果が得られます。私は何が起こっているか完全に理解していない、これはキャンバスへの私の最初のダイビングです。オブジェクトが各フレームで再描画されているようです。それはすべての白い円なので、雪のために働く。

どうすればこれらの変更を行うことができますか?ここに私のコード(発作WARNING!)です:3つの図形を描く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); 

} 
+0

私は私のポストにcodepen例を持っている、あなたのために動作しないということでしたか? –

+0

いいえ、私は盲目です。 – QBM5

答えて

1

キャンバスへのアニメーションループには、update()およびdraw()を繰り返し呼び出す必要があります。モデルを更新してキャンバスに描画する必要があります。すすぎ、繰り返します。

あなたのHTML/CSSに対応する新しいJavascriptファイルを作成しました。私は、これらのオブジェクト型の配列を作成

ライン

  1. サークル
  2. トライアングル
  3. :それは、3種類のいずれかとすることができる、パーティクルオブジェクトを作成できます。各タイプの3分の1がアレイに充填されます。私はそれらのオブジェクトをループし、アニメーションループ内の各オブジェクトの更新と描画のメソッドを呼び出すだけで、私の更新と描画のそれぞれの関数で呼び出すことができます。ここで

    は、スムーズなアニメーションの速度を向上させるために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(); 
    } 
    
+0

それはお互いの上に表示するすべての3つの図形を取得しますが、一度に1つずつ行うこと。落下する各オブジェクトは、3つの図形のうちの1つです。 –

+0

次に、overdrawingの問題を避けたい場合は、clearRectを選択的に使用する必要があります。以前の描画操作のすべてを失うだけで、各図形の後にキャンバス全体をクリアすることはできません。 – ManoDestra

+0

または、各パーティクルが3つのうちの1つだけである場合、各パーティクルオブジェクトにプロパティを格納して、どの種類のものであるかを知る必要があります。次に、その種類のパーティクルに対して適切な描画関数を呼び出します。あるいは、もっと良い方法として、各パーティクルタイプに独自の更新と描画メソッドを持たせることができます。次に、それぞれを作成するときに、それらを配列に追加し、各パーティクルに対してupdateとdrawを呼び出すことができます。つまり、if-else構造を実装するのではなく、自身を描画する方法を処理します。そのインスタンスで行う必要があるのは、コンテキストへの参照を渡すことだけです。 – ManoDestra

1

あなたは(drawShapesを呼んでいます)お互いの直後。 Var ctxはグローバルなので、各描画は直前のものを直ちに上書きします。

+0

シェイプタイプごとに新しいコンテキスト変数を作成する必要がありますか? –

+0

私はキャンバスの経験もないので知らない。これは私の最初の観察だった。修正のために他の人と一緒に行く;) – yezzz

+0

@yezzzはあなたの重要な問題を正しく認識していたので、そのことを賞賛する。キャンバスには単一のコンテキスト変数しか必要ないので、それを使ってください。操作の順序と機能の呼び出しを実装する方法についての私の答えを参照してください:) – ManoDestra

関連する問題