Меню

Уроци

Влез Излез

Partition – произход и подобрения

Преди 3 седмици написах blogpost, в който показвам demo на един partition ефект, който в последно време ми се струва доста нашумял. От тогава насам ми се случи да го срещна на още 2 места, което потвърждава разпространеността на ефекта, а днес най-сетне намерих от къде идва. Даже си и спомних, че за първи път съм го видял именно там. Ефектът тръгва от default cover картинката на профил в Google+ (https://www.google.com/search?q=google%2B+default+cover+photo&hl=en&safe=off&source=lnms&tbm=isch&sa=X&ei=6-NEUdehKIantAab44DQDA&ved=0CAoQ_AUoAQ&biw=1304&bih=707).

На http://magadanski.com/demo/partition/ можете да видите demo на ефекта (преди малко качих обновене версия, така че ако сте го виждали преди – може да ви е интересно да хвърлите нов поглед). Имайте едно на ум, че при refresh се генерира нов изглед.

Тъй като самият JavaScript, който съм написал съдържа интересни особености реших да напиша и кратко обяснение, което да го придружи. Като за начало ето го и самия код (можете да го видите и на https://gist.github.com/magadanskiuchen/5177953):

Коментарите по-долу се отнасят за func.js файла.

Още в самото начало ще видите Array.prototype.... Array е името на класа за масиви в JavaScript, а чрез prototype можем да редактираме методите на този клас. В нашия случай добавяме метод shuffle, който по подразбиране отсъства в JavaScript. Добавяйки метод посредством prototype той ще е валиден за всяка инстанция на обект от този клас. Така че ще можем да извикаме shuffle за всеки масив в кода ни.

Останалата част от кода ни се изпълнява на DOM ready.

Като цяло кодът разчита на произволни стойности, но все пак прилагаме известен контрол като ги ограничаваме в известни граници.

Използваме няколко конфигурационни променливи (minItems, maxItems, minDimensions, maxDimensions), в които записваме минималния/максималния брой кръгчета, които бихме рендирали на екрана, както минимален/максимален диаметър, който ще се приложи по отделно за всяко от тях.

В променливата cc записваме стойност на 3 цветови канала, които ще използваме по-нататък. Идеята за 3 фиксирани цветови канала е, че според теорията на цветовете, ако два цвята съдържат разменени, но еднакви по стойност интензитети на трите канала (червено, зелено и синьо), то те биха си подхождали. С други думи – #336699 си подхожда с #663399, както и с #996633 и т.н.

В нашия случай в масивя cc въвеждаме три произволни стойности от 0 до 255 (в 16-тична бройна система / HEX това би било от 0 до FF).

Помощната функция getColor() използва новият метод shuffle, който добавихме за масивите, за да разбърка стойностите на каналите и след това ги връща като string от числа, разделени със запетая. Този формат бихме могли да използваме в последствие с rgb(r, g, b) цветове в CSS.

На body елементът задаваме фон с преливащи цветове.

След това в itemsNum генерираме произволно число между minItems и maxItems.

Създаваме празен jQuery обект, в който в последствие ще добавяме кръгчетата си.

С цикъл добавяме itemsNum кръгчета, за които генерираме произволни белези. Все пак, колкото и да са произволни, ги контролираме в определена степен.

За dimensions задаваме стойност между minDimensions и maxDimensions.

За left и top задаваме стойност от 0 до широчината на страницата, като в цялата формула добавяме на два пъти размера на текущия елемент, за да добавим възможност той да започва малко по в ляво или по-горе от началото на екрана (да е частично изрязан).

В circleColor записваме цвят, който ще се използва за няколко белега на кръгчето (затова ни трябва в променлива).

Имайте предвид, че blur за момента работи само на Chrome. Чрез този филтър можем за постигнем ефект на размит фокус. С простичка формула се грижим и елементите, които не са на фокус, да са „по-далече“ в пространството, като им задаваме по-малък z-index (въпреки, че и елементи, които са твърде близо също биха били да не са на фокус – за този ефект аз си имам право на лична интерпретация).

След като сме създали нов елемент го добавяме в променливата items, а след като свършим с цикъла, добавяме елементите от тази променлива към DOM-а на страницата (и по-конкретно съм body-то). Добавяме елементите към DOM-а чак на края, защото по принцип работата с DOM натоварна процесора и по този начин оптимизираме кода си да работи по-бързо. Имайте предвид, все пак, че самата функционалност е достатъчно тежка, че тази оптимизация в момента е пренебрежимо малка, но е въпрос на добра практика и затова си направих труда да напиша и две думи по този въпрос.

  • Hristo Petrov каза:

    Здравей, това е интересен пост и затова реших да направя няколко теста и да споделя впечатленията си:
    Chrome 27 – works as intended (almost), оказва се че по-голямата част от кръговете получават цвят много близък до фона, на който се рисуват. Примерно при градиент от ляво на дясно зелене към червено, в ляво рисува повече зелени, а вдясно – червено. Като го комбинираш с факта че имаме blur или невидими граници, то тези обекти се сливат с фона и общият им брой намалява.
    Firefox 19 – резултат наподобяващ този от Chrome
    IE9 – градиента на фона никакъв го няма ( черен фон ), но затова пък имаме много по-добро разпределение на произволността на цветовете на обектите ( от 4те теста, най-приятният според мен резултат, все пак луд на шарено се радва )
    IE10 Mobile – тук фоновият градиент е наличен, но на 720р екрана (първите 3 теста са на 1080р) обектите изчертани са „леко претрупани“, както и част от тях са квадрати или кръгове в цветни квадрати…
    Това беше субективното мнение на програмист през нощта… Добра работа иначе за написването на урока. Поздрави

  • magadanski_uchen каза:

    Да – определено липсва compatibility за всички браузъри, но ако изключим blur филтъра (наличен само под Chrome) всичко останало работи правилно на последните версии на major браузъритъ: Firefox, Safari, Opera, IE (10 desktop).

    При IE9 единственият проблем е, че background linear-gradient изисква „-ms-“ префикс (трябва да правя проверка за user agent и версия на браузъра, за да го добавя, а ме мързи).

    За IE10 mobile – по обясненията разбирам, че box-shadow-а не върви съвсем правилно при наличен border-radius. На IE10 Metro не съм тествал дали е пак така, защото иска IE да ми е default browser-а, а не ми се разбутват настройки в момента.

    За останалото – който има мерак може лесно да промени бройката на елементите, както и да си hard-code-не трите цветови канала. След това малко refresh-ове и все ще си хареса нещо :).

Вашият коментар

Вашият имейл адрес няма да бъде публикуван. Задължителните полета са отбелязани с *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax