HTML画布通过滑块改变changig值后的不稳定运动

时间:2018-02-15 16:09:33

标签: javascript html canvas html5-canvas

我在尝试调整canvas元素的移动速度时遇到问题 - 通过控制台更新值没有问题,但是当我使用网站上的滑块执行相同的操作时,元素会开始闪烁。

这是相关的JS:

function Particle() {
  this.x = Math.round(Math.random() * 800);
  this.y = y;
  this.vx = vx;
  this.vy = vy;
  //...

Particle.prototype.draw = function() {
  this.x += this.vx;
  if(this.y == ground[this.x]) {
    this.vy = 0;
    ground[this.x] = this.y - 1;
  } else { this.y += this.vy; }
  //...

var gravityControl = document.getElementById("gravity-control");
gravityControl.oninput = function() {
  vy = this.value;
  for(var i in particles) {
    if(particles[i].vy > 0) {
      particles[i].vy = this.value;
    }
  }
}

Here's a JSFiddle.尝试调整“重力”滑块,看看我的意思。

为什么会这样?

1 个答案:

答案 0 :(得分:0)

您没有将滑块值转换为Number,而是在将新vy添加到this.y时,它使用字符串连接。改变这个:

gravityControl.oninput = function() {
  vy = this.value;
  for(var i in particles) {
    if(particles[i].vy > 0) {
      particles[i].vy = this.value;
    }
  }
}

到此:

gravityControl.oninput = function() {
  vy = +this.value; // coerce to number
  for(var i in particles) {
    if(particles[i].vy > 0) {
      particles[i].vy = vy; // use vy instead of this.value
    }
  }
}

演示:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

var gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
gradient.addColorStop(0, "#323991");
gradient.addColorStop(1, "#000");

var flakes = 5;

var x = Math.random() * 800;
var y = 0;

var vx = 0;
var vy = 1;

var ground = [];

for(var i = 0; i < 800; i++) {
  ground.push(599);
}

var flakesControl = document.getElementById("flakes-control");
flakesControl.oninput = function() {
  flakes = this.value;
}

var gravityControl = document.getElementById("gravity-control");
gravityControl.oninput = function() {
  vy = +this.value;
  for(var i in particles) {
    if(particles[i].vy > 0) {
      particles[i].vy = vy;
    }
  }
}

var particles = {},
  particleIndex = 0,
  settings = {
    size: 1,
    density: 100
  }

function Particle() {
  this.x = Math.round(Math.random() * 800);
  this.y = y;
  this.vx = vx;
  this.vy = vy;
  particleIndex++;
  particles[particleIndex] = this;
  this.id = particleIndex;
}

Particle.prototype.draw = function() {
  this.x += this.vx;
  if(this.y == ground[this.x]) {
    this.vy = 0;
    ground[this.x] = this.y - 1;
  } else { this.y += this.vy; }
  ctx.clearRect(settings.leftWall, settings.groundLevel, canvas.width, canvas.height);
  ctx.fillStyle = "#fff";
  ctx.fillRect(this.x,this.y,1,1);
}

setInterval(function() {
  ctx.fillStyle = gradient;
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  for(var i = 0; i < settings.density; i++) {
    if(Math.random() > (1 - (flakes / 1000))) {
      new Particle();
    }
  }

  for(var i in particles) {
    particles[i].draw();
  }
}, 10);
<canvas id="canvas" width="800" height="600"></canvas>
<div id="controls">
  <div>
    <label for="flakes-control">Snowflakes: </label>
    <input type="range" min="1" max="10" value="5" id="flakes-control" class="slider">
  </div>
  <div>
    <label for="gravity-control">Gravity: </label>
    <input type="range" min="1" max="10" value="1" id="gravity-control" class="slider">
  </div>
</div>