运行以下脚本后,仅显示一个圆圈。为什么?我该如何解决?

时间:2019-06-30 19:13:19

标签: javascript html canvas

我试图在画布上“拖”几个“泡泡”。我写了这个小脚本,但是运行它之后,只显示了一个圆圈。似乎它吸引了100次相同的“气泡”。为什么?

这是我的app.js:

var canvas = document.getElementById("cv");
let width = window.innerWidth * 0.98;
let height = window.innerHeight * 0.97;
canvas.width = width;
canvas.height = height;

var context = canvas.getContext("2d");

var boubles = [];

var createBouble = function() {
  this.x = width * Math.random();
  this.y = height * Math.random();
  this.color = getColor();
  this.radius = 30 + (Math.random() * 50);
//  console.log(this);
  return this;
}

var getColor = function() {
  return 'rgba(' + (Math.random() * 255) + ', ' + (Math.random() * 255) + ', ' + (Math.random() * 255) + ', ' + 0.3 + ')';
}

var generateBoubles = function(amount) {
  for (let i = 0; i < amount; i++) {
    boubles.push(createBouble());
  }
  drowBoules();
}

var drowBoules = function() {
  context.clearRect(0, 0, canvas.width, canvas.height);
  for (let i = 0; i < boubles.length; i++) {
    drowBouble(i);
  }
}

var drowBouble = function(index) {
  context.fillStyle = boubles[index].color;
  context.arc(boubles[index].x, boubles[index].y, boubles[index].radius, 0, 2 * Math.PI);
  context.fill();
}

generateBoubles(10);
<canvas id="cv"></canvas>

3 个答案:

答案 0 :(得分:2)

在功能中

var createBouble = function() {
  this.x = width * Math.random();
  this.y = height * Math.random();
  this.color = getColor();
  this.radius = 30 + (Math.random() * 50);
//  console.log(this);
  return this;
}

当您console.log this时,它总是变成window的对象。

那是因为它被视为正常功能。

创建新对象时,应使用new关键字。

即应该是

var generateBoubles = function(amount) {
  for (let i = 0; i < amount; i++) {
    boubles.push(new createBouble()); // use new here
  }
  drowBoules();
}

答案 1 :(得分:1)

您正在呼叫createBouble(),而没有绑定到this。 执行此操作时,this的值将默认为window对象,因此,每次调用createBouble()时,都将使用不同的值更新同一对象。

要解决此问题,您可以将this绑定到某个对象,如下所示:

createBouble.call({}); // Assignes an empty object to 'this'

或者,使用new关键字将新对象分配给this并返回它(这样就可以避免使用return this;):

const b = new createBouble();

但是,我认为一种更好的方法是避免使用this并返回一个新对象:

const createBouble = () => ({
  x: width * Math.random(),
  y: height * Math.random(),
  color: getColor(),
  radius: 30 + (Math.random() * 50),
});

答案 2 :(得分:1)

createBouble函数中,您必须返回值的对象,而在drowBouble函数中,您必须首先执行context.beginPath();

var canvas = document.getElementById("cv");
let width = window.innerWidth * 0.98;
let height = window.innerHeight * 0.97;
canvas.width = width;
canvas.height = height;

var context = canvas.getContext("2d");

var boubles = [];

var createBouble = function() {
  let x = Math.floor( width * Math.random());
  let y = Math.floor(height * Math.random());
  let color = getColor();
  let radius = 30 + Math.floor(Math.random() * 50);

  return {x,y,color,radius};
}

var getColor = function() {
  return 'rgba(' + Math.floor(Math.random() * 255) + ', ' + Math.floor(Math.random() * 255) + ', ' + Math.floor(Math.random() * 255) + ', ' + 0.3 + ')';
}

var generateBoubles = function(amount) {
  for (let i = 0; i < amount; i++) {
    boubles.push(createBouble());
  }
  drowBoules();
}

var drowBoules = function() {
  context.clearRect(0, 0, canvas.width, canvas.height);
  for (let i = 0; i < boubles.length; i++) {
    drowBouble(i);
  }
}

var drowBouble = function(index) {
  context.fillStyle = boubles[index].color;
  context.beginPath();
  context.arc(boubles[index].x, boubles[index].y, boubles[index].radius, 0, 2 * Math.PI);
  context.fill();
}

generateBoubles(10);
<canvas id="cv"></canvas>