[JS] Домашно Advanced-Functions - 2 задача


13
Create a module that works with moving div elements. Implement functionality for:
  • Add new moving div element to the DOM
    • The module should generate random background, font and border colors
    • All the div elements are with the same width and height
  • The movements of the div elements can be either circular or rectangular
  • The elements should be moving all the time

Demo

Source

Създал съм два типа - Circle и Rectangle. Създавам по една инстанция от всеки тип, на които добавям елементите. За по-плавна анимация ползвам requestAnimationFrame




Отговори



4

Ето един вариант от мен (взаимствал съм от демото на @Dimitar Bonev)

DEMO (тук има и source, но не се оцветява добре)

SOURCE

За закрепяне на евенти към бутоните изгледах тази лекция.

За да пази всеки шейп своята позиция съм добавил атрибути съответно: 
- атрибут за ъгъла, определящ движението на дивовете в окръжността;
- aтрибут за посоката на движение на дивовете в правоъгълника.

Другото може да го видите в кода.




16

Ето и моя вариант. Не съм много сигурен до колко е четим кода, но пък е малко на по елементарно ниво направена задачката.

Задачка.


от tankovski (2828 точки)


0
Линка не работи

от naso.003 (430 точки)

0
Мерси, нещо променях по домашното, може би от там се е "преебал", а може и аз да съм объркал нещо де. Сега трябва да е ок. Поздрави

от tankovski (2828 точки)



7

Отне ми доста време, но накрая стана както исках - а именно, с бутнчета да може да се добавя нов div и той да се върти независимо от другите. Тази статия ми беше полезна:

http://coding.smashingmagazine.com/2011/10/04/quick-look-math-animations-javascript/

А ето е демо:


от naso.003 (430 точки)


7

Ето още едно решение.

Демо.

Движението по елипса правя в метода moveInEllipse, като ползвам параметричните уравнения на елипса:

X = cX + a * cos( theta )

Y = cY + b * sin( theta ),

където (cX, cY) е центърът на елипсата. Когато ъгълът theta пробяга от 0 до 360 градуса (които обръщам в радиани), div-ът е направил едно завъртане по елипсата.

Оказва се обаче, че и за правоъгълник има удобни параметрични уравнения и отново може да се ползва ъгъл theta:

X = cX + p * ( abs(cos( theta )) * cos( theta ) + abs(sin( theta )) * sin( theta ) )

Y = cY + q * ( abs(cos( theta )) * cos( theta ) - abs(sin( theta )) * sin( theta ) ),

където p и q са полуширината и полувисочината на правоъгълника, т.е. правоъгълникът е с размери 2p x 2q. Това правя в метода moveInRectangle.

Това е форумът, от който взех формулата.

http://math.stackexchange.com/questions/69099/equation-of-a-rectangle

Ползвам и requestAnimationFrame, с което движещите се тела наистина изглеждат по-добре.


от vic.alexiev (2299 точки)


0
Здравей, И аз си играх да направя движение по елипса. Сега видях, че повечето колеги са направили движение в кръг. Не е ли подвеждащо условието? Чудя се дали да не добавя и движение в кръг. Поздрави!

от nikolaikolarov (2177 точки)

0
Здравей, Щом условието казва елипса, значи - елипса. Окръжността е частен случай на елипса. Като направим a = b (т.е. изравним голямата и малка полуос), те стават r (радиуса) и движението става по окръжност.

от vic.alexiev (2299 точки)



3

Един вариант и от мен.

Като цяло, просто reuse-вам задачата от предното домашно.

Разликата е функцията за rectangular movement, която просто проверява дали някой див е стигнал до определен ъгъл на правоъгълника и в зависимост от ъгъла намаля или увеличава top и left позицията на дива.

 


от iliyan.tanev (517 точки)


5

Ето и моето Решение, Демо.
Много ме изкефи резултата, харесва ми как се получи, малко зацикля браузера заради много малкия интервал на опресняване, но иначе се получи ясен код.
Имам два бутона за създаване на divs въртящи се  в кръг и divs движещи се по окръжност.
movingShapes, която има public метод add и доста private метода и променливи, имам два обекта съдържащи масиви от divs и допълнителни характеристики за всеки div. Два setInterval, с които си осигурявам повтарянето на функциите за местене на divs.
Функцията add просто добавя divs към списъците, а фунциите move... се грижат за промяната на координатите на всеки div.
Отделно имам допълнителни функции за улесняване и избягване на повтаряемост на кода.

Edit:
Написах и една статия с демо на тази задача, можете да я видите тук


от AsenVal (3487 точки)


0
Много разбираем код. Много ми помогна. Съветвам те да използваш === вместо == (за по-точни сравнения) и в циклите i += 1, вместо и i++ (работи по-бързо). :)

от el_b_k (424 точки)

0
Едва ли ти зацикля браузъра. Просто една десета от секундата е много голямо време. Сложи си в setInterval опресняването да е на 10 ms, a ne na 100, а за да не се движат прекалено бързо, промени стъпката. За окръжността 0,1 радиан ти е около 5,7 градуса, което е много. Сложи го 0,01! Също и за правоъгълника намали я от 10 на 1 и ще видиш, работи прекрасно! Поздравления!!! Хубаво решение! :)))

от jdimov (267 точки)



2

Ето малко дивове в движение и от мен:

source

demo

Правя dва типа дива - rect  и ellipse. За двата типа правя отделни функции за въртене. За елипсата само променям ъгъла. За правоъгълника съм добавил пропърти moves и сменям посоката като използвам следната формула:

currentDirection = directions[parseInt(shape.moves / 100)%4];

където directions ми е :

    var directions = [

        new direction(0, 1),
        new direction(1, 0),
        new direction(0, -1),
        new direction(-1, 0)
    ]
    function direction(top, left) {
        this.top = top;
        this.left = left;
    }
Така посоката се сменя, при определен брой ходове.

 


от krasi.nikolov (1412 точки)


0
Това с даването на газ нарочно ли го направи, или е страничен ефект? :))) На мен ми хареса, че като цъкам на бутона се вдига скоростта. Интересно е, но е интересно и да се избегне това. :)))

от jdimov (267 точки)

0
Ами не бях забелязал. :) Пазя всички обекти в масив и когато се натисне бутона започвам да ги местя, през определен интервал. Ускорението се получава, защото втори клик задейства нова функция за местене и т.н. Най лесно да се избегне е да изтривам бутона или да пазя едно пропърти inMove например. :)

от krasi.nikolov (1412 точки)



1

Здравейте, това е моето решение - демо.

Използвам няколко помощни функции - generateNumber и generateColor за генериране на случайно число и цвят, generateElement за генериране на елемент, Дефинирам обекти Circle и Rectangle и им добавям чрез prototype функциите drawAtDegrees и drawAtPosition.

Създавам по един обект от тип  Circle и Rectangle и два масива, в които да пазя генерираните елементи които се движат по различни траектории - кръг и правоъгълник.

Създавам модул със три функции - addaccelerate и rotate, като само първите две са публични. Първата функция създава елемент по зададена траектория, втората ускорява скоростта на движение, а третата движи елементите.

Публичните функции на модула се достъпват чрез бутоните Generate и Accelerate и съответно функциите onStartButtonClick и onAccelerateButtonClick.

Васко 


от vkv.1986 (250 точки)


0
Изглежда много красиво и подредено, както си го направил! Това, че независимо от броя, елементите са ти винаги на равни разстояния един от друг, много ми хареса! Поздрави! :)))

от jdimov (267 точки)


0

Това измислих аз:

Demo

Всеки div се генерира на random позиция и общо взето става голяма шарения :)


от GeorgiYolovski (1147 точки)


0

Здравейте,

И аз отделих повечко време на задачата.

Ето го и моето решение:

Сорс. 

Демо.

Още има неща за изчистване по него. Трябва да добавя по някой пояснителен коментар на функциите и тн...

Пускам го за да Ви задам следния въпрос:

Проблем ли е да закачаме къстъм пропъртира към html елементите?

Вместо да ги пазя в масив реших да пробвам на всеки елемент да му добавя необходимите данни за ротацията. По този начин той си ги пази, а аз само влизам и ги обновявам.

Говоря за:

 


node.centerX
node.centerY
node.currentAngle
node.moment
 
Много готино се получи така, но не съм сигурен дали е редно да го правя.
Благодаря предварително!
Поздрави!

 


от nikolaikolarov (2177 точки)