2

ステップ関数内にある「雪片」の不透明度の代わりにparticleDepthBlur()を使用しようとしていますが、望ましくないストロボ効果が発生します-なぜですか? 次のコードを検討してください。

明確にするために編集:

<canvas id="canvas"></canvas>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var num = 2000;

var canvas = document.getElementById("canvas");
var width = canvas.width = 960;
var height = canvas.height = 500;
var ctx = canvas.getContext("2d");

var particles = d3.range(num).map(function(i) {
  return [Math.round(width*Math.random()), Math.round(height*Math.random())];
});

function particlesDepthBlur(){ 
   return Math.random();
   console.log(Math.random());
}

function particlesDepthSize(){
   return Math.floor((Math.random()*4)+1);
}

d3.timer(step);

function step() {
  ctx.shadowBlur=0;
  ctx.shadowColor="";
  ctx.fillStyle = "rgba(0,0,0,"+particlesDepthBlur()+")";
  ctx.fillRect(0,0,width,height);
  ctx.shadowBlur=particlesDepthSize();
  ctx.shadowColor="white";
  ctx.fillStyle = "rgba(255,255,255,1)";
  particles.forEach(function(p) {
    p[0] += Math.round(2*Math.random()-1);
    p[1] += Math.round(2*Math.random()-1) + 2;
    if (p[0] < 0) p[0] = width;
    if (p[0] > width) p[0] = 0;
    if (p[1] < 0) p[1] = height;
    if (p[1] > height) p[1] = 0;
    drawPoint(p);
  });
};

function drawPoint(p) {
  ctx.fillRect(p[0],p[1],1,1);
};
</script>
<style>
html, body { margin: 0; padding: 0; }
</style>
4

2 に答える 2

2

は、前のキャンバスのctx.fillStyle = "rgba(0,0,0,"+particlesDepthBlur()+")";表示範囲をランダムに変更します。キャンバス全体で均一に行われます。過去のビューを一掃する黒で画面を完全に埋める場合もあれば、最後の画面が部分的に表示される場合もあります。前のビューを表示すると、キャンバス上の白の量が 2 倍になり、不透明度が低くなると、白の量が突然減少します。

function particlesDepthBlur(){ 
   return Math.random(0.5)+.5;
}

これを滑らかにします

于 2013-10-09T23:53:25.610 に答える
2

いくつかのこと:まず、キャンバスの背景を塗りつぶす直前に
呼び出しています。 次に、パーティクルごとではなく、フレームごとに 1 回だけぼかしと不透明度を計算します。 第 3 に、パーティクルごとに計算すると (そして を使用し続けると)、1 秒あたり数千回の操作でマシンが停止します。ctx.fillStyle = "rgba(0,0,0,"+particlesDepthBlur()+")";

Math.random()

これが私の

フィドル!

~フレームごとに 10 個の不透明度と 10 個のサイズを計算し、パーティクルごとにそれらを設定して、パーティクル全体で反復します。~ << これは 古いバージョンでした。が呼び出される前に不透明度がすべて設定されstep()、サイズは不透明度に比例します。

編集:ランダムな落下モーションで良い仕事です!
edit2: パーティクルごとに一定の不透明度とサイズを設定するための微調整。おそらく、フレームごとに Math.random() を 4000 回実行しているためです。フレームごとに 1 回、数十個の位置ベクトルを計算し、すべてのパーティクルを反復処理することを検討してください。この方法では、n 個の雪片がすべて同じパターンで降ることになり、必要な計算量が大幅に減るという利点があります。

最後に、「近く」の雪片 (大きくて明るい) を「遠く」の雪片よりも速く降らせることを検討してください。

<snip>
// Set up an opacity value for each particle, this will later be indexed with j
var particleOpacities = [];
particles.forEach(function(p){
  particleOpacities.push(particlesDepthBlur());
});

d3.timer(step);
var j = 0;
// since j is used by both step and drawPoint, it has to be outside both functions
function step() {
  ctx.shadowBlur=0;
  ctx.shadowColor="";
  ctx.fillStyle = "rgba(0,0,0,1)";
  ctx.fillRect(0,0,width,height);
  j = 0;
  particles.forEach(function(p) {
    p[0] += Math.round(2*Math.random()-1);
    p[1] += Math.round(2*Math.random()-1) + 2;
    if (p[0] < 0) p[0] = width;
    if (p[0] > width) p[0] = 0;
    if (p[1] < 0) p[1] = height;
    if (p[1] > height) p[1] = 0;
    drawPoint(p);
  });
};

function drawPoint(p) {
  j++; // iterate over points
  var particleSize = particleOpacities[j] * 4;
  ctx.shadowBlur=particleSize;
  ctx.shadowColor="white";
  ctx.fillStyle = "rgba(255,255,255," + particleOpacities[j] + ")";
  ctx.fillRect(p[0],p[1],particleSize,particleSize);
};
于 2013-10-09T23:57:14.113 に答える