将div排列成圆形并向外设置动画半径

时间:2016-03-12 21:59:43

标签: javascript

问题:我想在圆圈中排列div并为半径设置动画。不幸的是,我似乎对我的变量有某种约束性问题。试着从3天开始搞清楚这一点。我能做些什么来摆脱这种困境?我是说如何以“优雅的方式”解决这个问题?

我尝试了什么:我做了一些控制台日志,一切都暗示javascript在解释我对“this”的意思时遇到了问题。

我还发现我需要在requestAnimationFrame中绑定参数,但是我无法想象绑定每个变量和函数名称所以我必须在这里做错了。

这是JSFiddle:https://jsfiddle.net/Lh23pzvb/4/

代码:

function explodeRocket(obj) {
  this.elem = document.getElementsByTagName('div');
  this.particle = [];
  this.radius = obj.radius;
  this.color = ['red', 'yellow', 'cyan', 'orchid']
    this.interval = 2 * Math.PI / obj.particles;

  this.init = function() {
    this.create();
    this.blast();
  }

  this.init();

  this.create = function() {
    for(var i = 0;  i < obj.particles; i++) {
      document.body.appendChild(document.createElement('div'));
      this.elem[i].style.background = this.color[obj.colorIndex];
      this.particle.push(new this.Properties(0, obj.x, obj.y));
      this.updatePosition(i);
    } 
  }

  this.Properties = function(angle, x, y) {
    this.angle = angle;
    this.x = x;
    this.y = y;
  }

    this.updatePosition = function(index) {
    this.elem[index].style.left = this.particle[index].x + 'px';
    this.elem[index].style.top = this.particle[index].y + 'px';
  }

  this.blast = function() {
    for(var i = 0;  i < 10 - 1; i++) {
      if(this.radius < obj.radiusMax) {
        this.radius += 0.2;
      }
      this.particle[i].x = Math.round(window.innerWidth) / 2 + obj.radius * Math.cos(this.particle[i].angle) ;
      this.particle[i].y = Math.round(window.innerHeight) / 2 + obj.radius * Math.sin(this.particle[i].angle);
      this.updatePosition(i);
      this.particle[i].angle += this.interval;
    }
    requestAnimationFrame(this.blast);
  }
}


new explodeRocket({ 
    particles: 4, colorIndex: 0, radius: 0, radiusMax: 200, x: 0, y: 0 
})

2 个答案:

答案 0 :(得分:2)

错误1:

init()函数初始化之前调用create(),因此您无法调用它。您可以将init()放在explodeRocket函数的末尾来修复它,以便在调用init()时存在所有函数。

错误2:

.blast()运行循环次数太多。您只有4个粒子,但循环运行9次。您可以通过仅运行particle.length次循环来修复它:

for(var i = 0;  i < this.particle.length; i++) {

错误3:

this错误。当您拨打this时,您的代码会丢失requestAnimationFrame。您可以使用Function.call,它将this对象作为第一个参数。将this绑定到其他变量(例如self)以解决这些问题很常见:​​

var self = this;
requestAnimationFrame(function() {
    self.blast.call(self);
});

错误4:

您指的是obj.radius,始终为0.您应该使用this.radius

this.particle[i].x = Math.round(window.innerWidth) / 2 + this.radius * Math.cos(this.particle[i].angle);
this.particle[i].y = Math.round(window.innerHeight) / 2 + this.radius * Math.sin(this.particle[i].angle);

错误5:

你可能不想总是旋转1/4轮,所以每帧的1/40圈动画:

this.particle[i].angle += this.interval * 0.1;

错误6:

您可能希望粒子均匀分布,因此使粒子初始化为适当的半径:

this.particle.push(new this.Properties(this.interval * i, obj.x, obj.y));

完整代码:

function explodeRocket(obj) {
  var self = this;
  this.elem = document.getElementsByTagName('div');
  this.particle = [];
  this.radius = obj.radius;
  this.color = ['red', 'yellow', 'cyan', 'orchid']
    this.interval = 2 * Math.PI / obj.particles;

  this.init = function() {
    this.create();
    this.blast();
  }

  this.create = function() {
    for(var i = 0;  i < obj.particles; i++) {
      document.body.appendChild(document.createElement('div'));
      this.elem[i].style.background = this.color[obj.colorIndex];
      this.particle.push(new this.Properties(this.interval * i, obj.x, obj.y));
      this.updatePosition(i);
    } 
  }

  this.Properties = function(angle, x, y) {
    this.angle = angle;
    this.x = x;
    this.y = y;
  }

    this.updatePosition = function(index) {
    this.elem[index].style.left = this.particle[index].x + 'px';
    this.elem[index].style.top = this.particle[index].y + 'px';
  }

  this.blast = function() {
    for(var i = 0;  i < this.particle.length; i++) {
      if(this.radius < obj.radiusMax) {
        this.radius += 0.2;
      }
      this.particle[i].x = Math.round(window.innerWidth) / 2 + this.radius * Math.cos(this.particle[i].angle);
      this.particle[i].y = Math.round(window.innerHeight) / 2 + this.radius * Math.sin(this.particle[i].angle);
      this.updatePosition(i);
      this.particle[i].angle += this.interval * 0.1;
    }
    requestAnimationFrame(function() {
        self.blast.call(self);
    });
  }

  this.init();
}


new explodeRocket({ 
    particles: 4, colorIndex: 0, radius: 0, radiusMax: 200, x: 0, y: 0 
})

应该这样做!

修改

工作jsfiddle:https://jsfiddle.net/v3nt2kd0/

答案 1 :(得分:1)

首先,尝试在构造函数的末尾移动this.init();

在执行此操作之后,在blast()方法中抛出了一些其他错误,这可能与this.particles数组只有4个元素且您正在尝试执行的事实有关迭代左右。

作为提示,您可以移动explodeRocket.prototype上的大多数(如果不是全部)方法,以便实例共享相同的方法实例,如下所示:

function ExplodeRocket(obj) {
    //yada yada
}

ExplodeRocket.prototype.blast = function blast() {
    //yada yada
}