数组元素的依从性

时间:2018-08-11 15:41:47

标签: javascript arrays canvas

在画布上,我分配了一个具有坐标的星星数组:

x: randomInt(1, canvas.width - 1),
y: randomInt(0, canvas.height - 1),

每个星星的初始不透明度(op)值为1。在动画过程中,不透明度变为0(并且星星消失)。

应该是因为画布的顶部(y < 75)中的星星消失的速度与底部中的星星消失的速度不同,这是因为以下代码为每一帧设置了不透明度值:

 for (let i = 0; i < SF_COUNT; i++) {
     if (stars[i].y < 75) {stars[i].op -= 0.001;}    
     else {stars[i].op -= 0.01;}
 }

但是,实际上发生的是,星星以不同的速率动画,但是这种差异显示为随机(即不限于画布顶部的星星) 。为什么? http://jsfiddle.net/Nata_Hamster/6jdnq3ry/

2 个答案:

答案 0 :(得分:2)

错误:

现在,您的drawFrame代码在绘制星星之后设置 的不透明度,这意味着不透明度会影响 next 而不是当前的星星:

...
// draw all SF_COUNT stars
for (let i = 0; i < SF_COUNT; i++) {
    // this draws star i with the *current* context.strokeStyle
    snowflake(stars[i].x, stars[i].y);
    // this sets the context.strokeStyle for star i + 1
    context.strokeStyle = 'rgba(255,255,255,' + stars[i].op + ')';
}
...

修复:

交换两行,以便在绘制星形之前设置颜色:

...
// draw all SF_COUNT stars
for (let i = 0; i < SF_COUNT; i++) {   
    // this sets the context.strokeStyle, changing the opacity of star i
    context.strokeStyle = 'rgba(255,255,255,' + stars[i].op + ')';
    // this draws star i with the new context.strokeStyle
    snowflake(stars[i].x, stars[i].y);
}
...

Here's a fixed codepen.

答案 1 :(得分:2)

当应该将strokeStyle作为第一步时,将其作为最后一步。

这是我的更正后的代码:
还添加了其他一些小的改进,以使代码更具可读性

var canvas = document.getElementById("drawingCanvas");
var context = canvas.getContext("2d");
var stars = [];

const SF_COUNT = 500;
context.lineWidth = 1.1;

window.onload = function() {
  changeColor1();
  drawFrame();
}

for (let i = 0; i < SF_COUNT; i++) {
  stars.push({
    x: randomInt(1, canvas.width - 1),
    y: randomInt(0, canvas.height - 1),
    op: 1
  });
}

function randomInt(min, max) {
  return Math.floor(Math.random() * (max - min));
}

function snowflake(star) {
  context.strokeStyle = 'rgba(255,255,255,' + star.op + ')';
  context.beginPath();
  context.moveTo(star.x, star.y);
  context.lineTo(star.x + context.lineWidth, star.y + context.lineWidth);
  context.stroke();
}

function drawFrame() {
  context.clearRect(0, 0, canvas.width, canvas.height);
  for (let i = 0; i < SF_COUNT; i++)
    snowflake(stars[i]);
  setTimeout(drawFrame, 190);
}

function changeColor1() {
  for (let i = 0; i < SF_COUNT; i++)
    if (stars[i].op > 0)
      stars[i].op -= (stars[i].y < 75) ? 0.002 : 0.01;
  requestAnimationFrame(changeColor1);
}
#drawingCanvas {
  height: 170px;
  width: 400px;
  background-color: #000;
}
<canvas id="drawingCanvas"></canvas>