Как да си направим ротатор на картинки с JavaScript

Съвсем наскоро, във връзка с един от курсовете, които посещавам в момента, ми се наложи да правя статичен уебсайт по даден дизайн. В даденото psd беше предвидено да има нещо като панел, в който се сменят различни публикации (новини с картинки и допълнителна информация) като функционалността изискваше както автоматично сменяне, така и ръчно чрез бутони напред / назад. Под въпросния панел има и част с т. нар. thumbnails, които представляват малък размер на това, което се изобразява горе. Ако се click-не на тях, автоматично картинката горе се сменя с текущата посочена. Цялото това нещо е подобно на widget и е по-известно като image rotator.
Подобни ротатори на картинки (и не само картинки, а цели панели с информация) може да откриете на сайтове като Yahoo, playlist-а на YouTube и още куп други.

В настоящият урок ще ви покажа как сами да си направите нещо подобно:

Демонстрация

Какво ще ни е нужно за целта?

  • Познания по HTML, CSS, JavaScript  (+ библиотеката jQuery).
  • Сорс код редактор, за демото съм ползвал Notepad++.
  • Някакъв опростен редактор за картинки, може да се ползва и Paint.
    Ще ви трябва за оразмеряване на картинките и crop-ване на малките thumbnails по-късно.
  • Малко свободно време, желание и готини идеи.

Какво точно ще направим и как ще изглежда?

За демонстрацията реших да направя съвсем семпъл вариант на image rotator. Вие сами може да експериментирате, да направите коренно различни неща, по-богати на съдържание, стил и функционалност. Няма да влизам в детайли относно html-а и стиловете използвани в моя вариант. Накратко имам контейнер, в който се съдържат ротатора и панелчето с малки картинки под него. Ротаторът има два бутона за навигация между картинките и средна част с големия формат на картинките (новината или статия с различно съдържание). Под тях има панелче, в което се визуализират малките картинки (thumbnails). Добавени са някои ефекти, като смяна на фона с бял при hover на мишката и оранжев при показване на текущата картинка. Накрая на тази публикация ще откриете link към целия проект и сорс код, които съм ползвал и ще може да видите самата структура и стилизиране на елементите.

По какъв начин функционира въртенето и как да го направим?

Тук идва същинската част. За по-лесно ориентиране, докато четете, може да отворите script файла от този адрес и да следите кода заедно с обясненията.

Ще започнем с променливите. Нуждаем се от един предварително деклариран масив imageURLArray, в който да се съдържат имената на файловете с големи картинки, включително разширението им. Пътят до тях няма да се специфицира тук. Останалите променливи са съответно imgHolder, която по-късно при зареждането на страницата ще открие елемента, чиято фонова картинка ще променяме, nextPictureToShow – индекс на следващата картинка за показване, refreshedIntervalId – ще я ползваме, за да стопираме и подновяваме автоматичното въртене и smallContainers, в която ще се съдържат всички елементи с малки картинки от крайния долен панел.

В моментът, в който страницата е заредена ($(document).ready(function() { … }) и всички елементи на нейното DOM дърво са правилно възприети и конструирани,
променливите ще бъдат инициализирани. Ще открием всички div-чета с клас SmallPic, който държат thumbnail-овете на големите картинки. В imgHolder ще запишем и елемента, който държи за фон главната голяма картинка на rotator-а.
Даваме начална стойност на индексатора 0 и продължаваме напред. За всеки от div-овете с малки картинки присвояваме следните event-и:
mouseover – когато курсора на мишката е над съответния елемент, към него ще се добавя клас .HoveredPic, който ще сменя фона на контейнера с бял и ще слага познатата ръчичка за курсор.
mouseout – просто ще премахва гореспоменатия клас, връщайки стиловете, както са били преди това.
click – ще извика функцията ChangeRotatorPic с параметър index сочещ към текущо извикания обект.

Ще обясня отделните методи малко по-надолу, но първо да приключим с първоначалните инициализации и извиквания при зареждане на страницата.
Останалото от тази част е закачането на event-а click за бутона наляво със съответното извикване на метода PreviousPicture() и този за надясно NextPicture().
За финал, викаме методът StartRotator(), който пуска автоматичното въртене на картинките.

ОТДЕЛНИТЕ МЕТОДИ

function StartRotator()
{
refreshedIntervalId = window.setInterval(“RotateImages()”, 3500);
}

Накратко, задавайки тази стойност на променливата, чрез методът setInterval ние заявяваме, че на всеки 3,5 секунди ще бъде извиквана функцията RotateImages().
Със съдържащите се в RotateImages() условия, въртенето ще продължава безкрайно. По-късно ще разберем как да го спрем и в кои случаи ще е нужно.
Повече за метода setInterval – тук и тук.

RotateImages()

В този основен метод правим няколко стъпки. Чрез eval() се изпълняват различни statement-и или се изчисляват изрази. Върнатите обекти могат да се ползват по-напред в работата с различни методи на чистия JavaScript или библиотеката към него jQuery. Правим проверка дали не излизаме от размера на масива с картинките. Ако това е така, връщаме стойността на nextPictureToShow на 0 (по този начин осигуряваме преминаването от последна към първа картинка). Със следващия ред
var urlToImg = “url(img/” + array[nextPictureToShow] + “)”;
създаваме променливата, която ще ползваме като стойност на свойството background на елемента, който държи главната картинка. Библиотеката jQuery предоставя изключително удобни методи за директен достъп до елемента и неговите свойства. В този случай ще работим директно върху стиловете му чрез .css(), който приема като параметрите property и value. Нагласяме някои други свойства на фоновото изображение. Премахваме предишно добавения клас .ClickedPic, а после го добавяме само за текущия елемент.
$(“.SmallPic”).eq(nextPictureToShow) обхожда всички елементи с клас .SmallPic, но връща онзи от колекцията, което е с индекс nextPictureToShow.
В jQuery, разликата между .eq(n) и .nth-child(n) е в това, че при eq n е 0-базирано, а при nth-child броенето започва от 1.
Голямата ни картинка е вече сменена, както и фона на малката, която й отговаря и стои под нея. Увеличаваме nextPictureToShow с 1 за следващата итерация.

PreviousPicture()

Този метод се вика при натискане бутона наляво за ръчна смяна на картинката (спомняте си event-а, който закачихме по-нагоре, нали?!). По-особеното е if-else частта. Ако nextPictureToShow е 0 или 1, то ние сме все още на първата картинка. Или сме заредили страницата и веднага сме натиснали назад, стойността е още 0 и не е увеличена, или RotateImages() е минало вече веднъж и стойността е 1. И в двата случая, трябва да зададем стойност на променливата равна на последния валиден индекс от масива с картинки. Така, когато сме на първата картинка и дадем назад или наляво, ще ни бъде показана последната, което е очакваното преминаване.

В противен случай, намаляме стойността на променливата за индекса с 2.
Тук идва важния момент с изпълнението на clearInterval(refreshedIntervalId);
По този начин “нулираме” таймера и прекратяваме изпълнението на RotateImages() на всеки 3 секунди и половина. Извикваме RotateImages(), за да изпълни смяната и след това стартираме отново автоматичното сменяне чрез StartRotator().

NextPicture()

работи по общо взето същия начин като предния метод. Разликата е единствено в проверката. Ако натиснем веднага след зареждане на страницата бутона за следваща снимка, може да сме изпреварили събитията с инкрементацията и смяната да зацикли. Затова, ако е 0, увеличаваме с 1, за да е всичко ОК.

ChangeRotatorPic(itemNumber)

Това е закачения за event-a click метод. Присвояваме на nextPictureToShow стойността на itemNumber, зачистваме таймера, викаме RotateImages() и накрая стартираме отново автоматичния ротатор.

Да не повярва човек, но това е всичко!

“Омръзна ми да чета, не разбрах нищо и искам код … “

Ако сте scroll-нали дотук в гнева си (ако вече не сте натиснали X-а на браузъра), ще ви разбера. Всички сме изпадали в това положение, когато думите просто не са достатъчни. Затова, ще си спазя обещанието като ви дам адрес към архивче с целия проект и всички файлове към него.

Целият сорс код и файловете към проекта

 

С този урок се опитах да ви покажа един от начините да си направим по сравнително лесен и бърз начин image rotator с възможност за автоматично и ръчно сменяне на съдържанието. Надявам се тези знания да ви послужат като основа за създаването на нещо далеч по-функционално, красиво и приложимо в бъдещите проекти, по които ще работите. Желая ви успех! : )

Харесва ли ви това? Споделете:

Unit тестване на конзолни приложения

Като част от QA академията на Телерик, наскоро ми се наложи да пиша unit тестове за едно конзолно приложение, а именно една игра. В близко бъдеще се надявам да ми остане малко повече време, за да ви представя урок как да си създадем лесно, бързо и приятно някаква old school готина игричка, но засега, да караме направо.
Ще ви споделя накратко как да подкарате компонентни тестове, които симулативно да обработват изкарване / вкарване на информация от конзолата.

Unit testing image

Какво ще тестваме?

Няма да влизам в детайли относно същността и имплементацията на възложената задача. Ще дам конкретен пример за един метод от нея. В играта имаше изискване да има табло(таблица) с резултати или т. нар. scoreboard, който да пази имената на играчите и техния резултат. Също така, scoreboard-а трябва да изкарва играчите подредени във възходящ ред по резултата (в контекста на играта, това са брой опити за решаване на проблема, т. е. по-малкият брой опити е по-добър резултат). Ако двама играчи са с еднакъв резултат, то тогава да ги подрежда по имена (азбучен ред или още лексикално сортиране). Максималният брой играчи за показване е 5, а ако таблото е празно, се изкарва определено съобщение.

За целта използвах една много полезна структура от данни, а именно OrderedMultiDictionary. За нея, авторите й и повече информация относно другите многофункционални и интересни класове, които идват с безплатното assembly, посетете тази страница.

Ще пишем на C#. Работим с Microsoft Visual Studio 2010 Ultimate и
Team Test Framework
-а към него.

Може да видите кода на моята имплементациятук
или като картинка Test code snippet oneвляво.
Това е самият метод.

Компонентно тестване на нещо, което пише по конзолата

В същността на проблема стои въпроса как най-лесно да сравним отпечатаното на конзолата с това, което очакваме и сме посочили като expected value за нашия тест. За целта ще ни е нужно да пренасочим нанякъде стандартното печатане на конзолата. Това може да се направи лесно като използваме класа StringWriter дефиниран в namespace-а System.IO (за повече информация – MSDN).

Създаване на теста в стъпки

  1. Записваме някаква sample data в нашата структура. За целта използвам самостоятелно написан метод, който добавя в речника няколко играчи.
    Може да се направи и чрез стандартно викане на метода Add на класа OrderedMultiDictionary, който ще иска да му бъде подаден като параметър обект от тип KeyValuePair<int, Competitor>.
  2. Създаваме инстанция на класа StringWriter, например:
    StringWriter sw = new StringWriter();
  3. Използваме статичния метод на конзолата Console.SetOut(TextWriter newOut) и като параметър подаваме създадената от нас инстанция на класа StringWriter, а именно sw.
  4. Викаме метода, който ще тестваме и който стандартно пише по конзолата.
    В моя случай, това е споменатия вече по-горе статичен PrintScoreBoard(). Вече пренасочен, изходът ще се запише в обекта sw.
  5. Създаваме си променлива от тип string, която да съдържа в себе си очаквания от нас резултат.
    Важно е да се отбележи, че навсякъде, където очакваме нов ред, трябва да добавим към нашия низ литерал за нов ред. В примерчетата отдолу съм го направил използвайки placeholder и property-то NewLine на класа Environment, който универсално работи за всяка среда, под която се компилира приложението, добавяйки правилния литерал.
  6. Използваме Assert.AreEqual, сравнявайки обекта sw обърнат до string със създадената от нас променлива.
  7. Пускаме теста и ако всичко е наред, трябва да е минал успешно.

Test results image

Може да видите кода на моята имплементациятук
или като картинка вляво.Test code snippet two
Това са два теста на метода PrintScoreBoard().

 

 

 

 

Ами ако желаем да симулираме вкарване на информация от конзолата?

Това вече е малко по-абстрактно, но не толкова сложно. Използва се друг клас – StringReader (MSDN). Накратко казано, изходът отново се пренасочва към StringWriter, а входът към инстанция на StringReader.
Ще ви дам конкретен, лесен пример.

Snippet one imageSnippet two image
Това е написаният от нас метод и теста към него (двете картинки отгоре).

Питаме потребителя как се казва, четем отговора му и после отпечатваме поздрав.
Тестът работи по следния начин:

  1. Пренасочваме стандартния изход на конзолата към обект от тип StringWriter.
  2. Създаваме инстанция на класа StringReader и като параметър подаваме всичко, което очакваме от потребителя. В нашия случай, това е име последвано от нов ред (тъй като стандартно се вика Console.ReadLine()).
  3. Пренасочваме входа на конзолата към нашия обект от тип StringReader.
  4. Създваме си променлива от тип string, в която вписваме очаквания резултат. Важно е да се отбележи, че това ще е само изходната информация. Прочитането вече е извършено и ние очакваме резултат на базата на него.
    Внимавайте също и с местата, на които се очаква да бъде отпечатан нов ред.
    Често това води до грешки и пропадане на теста.
  5. Сравняваме очакваното с обекта от тип StringWriter обърнат до string.

Ако всичко е наред, тестът минава успешно.

Писането на компонентни тестове е важно за осигуряване качеството на нашата разработка без значение дали тя е desktop, web или просто конзолно приложение. Надявам се този урок да е в помощ на онези от вас, които са се сблъскали със задачата да изтестват метод, който стандартно изкарва нещо на конзолата или пък чете от нея. Желая ви успех! : )

Харесва ли ви това? Споделете:

Как да инсталираме Windows 8 на виртуална машина?

С предстоящото излизане на новата операционна система на Microsoft се повиши и интереса към нея. Преди известно време излезе бета или така наречената “Consumer Preview” версия, която беше достъпна за всеки по-любопитен софтуерен разработчик или потребител. В момента вече има “Release Preview“, който ще инсталираме заедно малко по-надолу. Това е много близко подобие на онова, което ще излезе като официална версия наесен.  Много мои приятели и познати изявиха желания да изпробват “осмицата” . За тяхно и ваше улеснение съм подготвил кратък урок как в няколко лесни стъпки да инсталираме Windows 8 на виртуална машина ипозлвайки VMware Workstation без да засягаме по никакъв начин работата на текущата ни среда.

Windows 8 logo

Какво ще ни е нужно за инсталацията?

За целта ще са ни нужни:

1. Image файл с операционната система:
Windows 8 Consumer / Release Preview – достъпна напълно безплатно оттук.
Свалете 32 или 64-битова версия в зависимост то това с какви ресурси разполагате. По-надолу ще разберем, че ще е нужно и да споделим част от системните си ресурси с виртуалната операционна система.
2. Софтуер за създаване на виртуална машина: съществуват различни варианти, но ние ще се спрем на работата с VMware Workstation.
Има опция да изпробвате безплатно за определен период от време текущата осма версия, посетете официалния сайт.
Важно е да се отбележи, че с по-стари версии има проблеми при инсталация на операционната система, затова използвайте 8.0 и нагоре.
3. Около 15 GB свободно дисково пространство.
4. Малко свободно време и желание.

Инсталацията в стъпки

Конфигуриране

След като имаме всичко нужно, можем да пристъпим към инсталацията.
На някой от дяловете (за предпочитане пасивен) на вашия твърд диск създайте папка с някакво име, например “Win 8 test”. Убедете се, че имате повече от 15 GB свободно място на текущия дял. Принципно инсталацията не отнема повече от 9-10 GB, но в процеса на работа може да ви се наложи да използвате файлове директно върху операционната система, а тя се разпростира в предварително заделенето място.
Стартирайте VMware Workstation и следвайте стъпките:

Step 1


За голям размер, click-нете с мишката върху снимката.

 

 

 

1. Избираме “Create a New Virtual Machine“.

Step 2

 

 

 

 

 

2. Нямаме нужда от специфични настройки, затова “Typical” конфигурация.

Step 3

 

 

 

 

 

3. Избираме втората опция и чрез “Browse...” намираме пътя до сваления image файл с операционната система.

Step 4

 

 

 

 

 

4. Операционната система е Windows. В падащото меню няма Windows 8 като опция, затова избираме Windows 7, в моя случай 64-битова версия.

step 5

 

 

 

 

 

5. Тук въвеждаме предоставения ни от Microsoft сериен номер (намира се в сайта за сваляне на image файла). Въвеждаме също Username и Password (optional).

step 6

 

 

 

 

 

6. Избираме си име за виртуалната машина и посочваме папката, в която ще са всички файлове обслужващи я (аз ще използвам създадената вече от мен папка “Win 8 test”).

step 7

 

 

 

 

 

7. Избираме максимален размер. Препоръчват ни 60 GB, които са абсолютно излишни за нашата цел. Задаваме 15 (по избор), маркираме първата опция (“Store virtual disk as a single file“) и продължаваме напред.

step 8

 

 

 

 

 

8. Излиза ни резюмирана информация за това как и къде ще бъде създадено всичко. Нуждаем се обаче от малко специфични настройки, затова кликваме на “Customize Hardware…

step 9

 

 

 

 

 

9. Hardware – Memory: За споделена памет препоръчвам 2 GB за 64-битова версия и поне 1 за 32-битова.

step 10

 

 

 

 

 

10. Hardware – Processors: Ако процесорът ви е single-core, оставете настройките по default. За двуядрените, изберете Number of cores per processor със стойност 2.

step 11

 

 

 

 

 

11. Hardware – Floppy: Важно! Уверете се, че сте изпълнили маркираното в червено, а именно да премахнете селекцията в кутийките “Connected” и “Connect at power on”. В противен случай, при стартиране по-късно ще получите досадна грешка – “Windows cannot read the ProductKey setting from the unattend answer file.”

step 12

 

 

 

 

 

12. Затваряме настройките на Hardware-а, можем да изберем да ни се стартира виртуалната машина след създаването й. Това е и краят на конфигурацията. Натискаме бутона “Finish“.

Инсталация на самата операционна система

step 13

 

 

 

 

 

13. След натискане на бутона “Finish”, автоматично се стартира виртуалната ни машина.

step 14

 

 

 

 

 

14. Добре дошли в инсталацията на Windows 8! Избираме си език и регионални настройки.

step 15

 

 

 

 

 

15. Въвеждаме отново серийния номер (същия като в стъпка 5).

step 16

 

 

 

 

 

16. “Отделяме” 2 часа да прочетем споразумението, съгласяваме се и продължаваме напред.

step 17

 

 

 

 

 

17. Започва копирането на файловете и инсталацията на компонентите. В зависимост от ресурсите на вашата машина, това може да отнеме различно време. При инсталацията, която направих аз, това отне 8-9 минути.

step 18

 

 

 

 

 

18. След края на инсталацията, следва рестартиране. Може и ръчно да натиснете бутона.

step 19

 

 

 

 

 

19. След рестарта и малко изчакване се появява този екран. Най-накрая нещо шаренко! Избираме си цветова схема и име на PC-то.

step 20

 

 

 

 

 

20. Избираме “Use express settings“. По любопитните могат и да се поровят в “Customize”.

step 21

 

 

 

 

 

21. В тази стъпка ни подканват да въведем Email, който ще ползваме за Microsoft-ския си account. Използвайки тази функционалост, бихме имали достъп до Windows Store, ще можем да свържем нашия content с Metro приложенията и други нови нещица засегнати в Windows 8. Лично на мен на този етап не са ми нужни, затова избирам “Sign in without a Microsoft account“.

step 22

 

 

 

 

 

22. Искаме да използваме локален акаунт, затова избираме “Local account“.

step 23

 

 

 

 

 

23. Избираме си стандартните име на потребител, парола и подсказка за нея. Натискаме “Finish“.

step 24

 

 

 

 

 

24. На черен екран ни се изписва, че всичко ще бъде готово след момент. А дано!

step 25 final

 

 

 

 

 

25. Изчакваме малко и воала! Това е началното и ново “Start menu” на Windows 8. Всичко е минало наред и вече сме готови да разгледаме новостите в операционната система, да се запознаем с Metro приложенията и всичко, което ни заинтригува.

Надявам се урокът да е бил полезен и да сте успели безпрепятствено да инсталирате всичко. Пожелавам ви приятно “рацъкване” на новия Windows 8! : )

 

Харесва ли ви това? Споделете: