2016-03-12 2 views
0

Задача: Я хочу расположить divs по кругу и анимировать радиус. К сожалению, у меня, похоже, какая-то проблема с моими переменными. Попытка понять это с 3 дней. Что я могу сделать, чтобы выбраться из этого затруднительного положения? Я имею в виду, как я могу решить эту проблему «элегантно»?Расположить divs по кругу и радиусу радиуса наружу

Что я пробовал: Я сделал несколько консольных журналов, и все подразумевает, что у javascript есть проблемы с интерпретацией того, что я имею в виду под «этим».

Я также обнаружил, что мне нужно связать параметр внутри 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

Ошибка 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/40th окружности на кадр:

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

ошибка 6:

Вы, вероятно, хотите частицы быть электронной venly разнесены, поэтому инициализировать частицу с правильным радиусом:

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 
}) 

Это должно сделать это!

Edit:

Работа jsfiddle: https://jsfiddle.net/v3nt2kd0/

+0

Wow thanks. Это объясняет многое:) – Asperger

1

Прежде всего, попытайтесь переместить ваш this.init(); в конце конструктора.

После этого в вашем методе blast() возникают некоторые другие ошибки, которые, вероятно, имеют отношение к тому факту, что массив this.particles имеет только 4 элемента, и вы пытаетесь выполнить 10 итераций или около того.

В конце, вы можете переместить большинство, если не все, из методов на explodeRocket.prototype так, что экземпляры один и тот же экземпляр метода, например, так:

function ExplodeRocket(obj) { 
    //yada yada 
} 

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

Я голосовал за jehna, но я дам вам точку, так как ваш отзыв является большим. Несмотря на то, что раньше я использовал прототип, я думал, что это не обязательно для этой конкретной работы. Ошибка с моей стороны. – Asperger

+0

Это не ошибка; если вы планируете использовать только один экземпляр, вам действительно не нужно переводить методы в «прототип». Cheers –

Смежные вопросы