Как написахме SVG джаджи за JavaScript

Опровержение.

Честно признавам, че първоначално бях изправен пред задачата да пиша на Habré за нашия продукт. Първоначално планирах да се огранича до редовно PR есе, описващо основните характеристики и функции на нашия компонент, без да се фокусирам върху детайлите. Разбира се, такава история би позволила да разкрием напълно всички чипове на нашия продукт. От друга страна, това със сигурност би ви накарало да се прозяете около третия параграф.

На пръв поглед тази задача е доста проста за решаване. Например има безплатен компонент Google Gauge и много различни неща, които попадат при поискване в същия Google. От друга страна, повечето от тези библиотеки са склонни да имат ограничен набор от опции. Веднага щом трябва да направите нещо свое, принципът „по-лесно е да пишете сам“ започва да работи.

Затова нашата задача беше да създадем система, която да позволява не само да персонализираме съществуващите „обрати“, но и създайте ги сами от нулата. Системата трябваше да направи възможно събирането на джаджа от графични примитиви (геометрични фигури, стрелки, специални елементи като „епруветки“, „пружини“) и т.н. Освен това искахме да разработим скриптов език, с който програмистът да може да обвърже стойностите на отделни елементи на приспособлението (например числото в текстовото поле и позицията на стрелката в скалата).

И така, екип от двама програмисти, QA (което се свърза малко по-късно) и продуктов мениджър (което постоянно пречеше на работата на всички, принуждавайки всичко да бъде преработено, „защото потребителят е неудобен или труден“), започна разработка веднага след новогодишните празници.

Изправихме се пред няколко технически проблема, които трябваше да бъдат решени:

В нашия случай въпросът се влоши от факта, че имахме професионален екип на Silverlight, който трябваше да бъде преквалифициран (уви, стратезите на Microsoft понякога могат да дразнят собствените си разработчици). Съответно, за да се достигне същото ниво при работа с „чист“ JS, ще са необходими няколко години и няколко „слети“ продукта.

Архитектура

SVG срещу Платно

Ако погледнете Canvas, тогава хардуерната поддръжка в много браузъри е несъмнено предимство, а очевидният недостатък е необходимостта от сложно преначертаване на обекти по време на анимация (например, когато стрелката се движи, ще трябва да прерисувате някои от обектите под него).

След малко размисъл разбрахме, че цялата система за рендиране трябва да бъде написана в абстракции, които не са специфични за SVG или Canvas (здравей, капачка). След това се реализира отделен набор от класове за рисуване и пребоядисване на обекти по специфична технология. В първата версия решихме да се ограничим до SVG, тъй като бяхме силно привлечени от възможността да завъртаме стрелките, използвайки атрибута ъгъл, и да не пречертаваме изображението при всеки завой. Освен това искахме да използваме стандартна SVG анимация (уви, това беше голям проблем) и CSS, за да контролираме стиловете на джаджата.

По този начин, докато всички джаджи са изчертани в чист SVG.

Обектен модел

Вземайки предвид факта, че разработката е извършена в Script #, пренасянето на модела е намалено до банално "copy-paste". Всички опити за оставяне на една кодова база, за съжаление, не са увенчани с успех. Имаше твърде много разлики в поведението, изобразяването и други подробности. Поради това се появиха куп условни директиви и клонове, които само затрудниха разбирането на кода и донесоха повече вреда, отколкото полза. В резултат беше решено, че принципът на СУХО няма да бъде нарушен. Както показа времето, направихме всичко както трябва - в кода на уеб частта практически няма парчета, които да са идентични с частта на Windows.

За да бъдем обективни обаче има и успешни примери за споделяне на код между продуктите C # и Script #.

Сериализация

Един от основните недостатъци, борбата срещу който вече се планира в близко бъдеще, е изобилието от ненужна ненужна информация в полученото описание на JSON. Това се случва поради факта, че използваме стандартни механизми за сериализация и получаваме копие на обекта "както е", включително куп ненужни свойства (уви, трябва да сериализираме всички публични полета). Това прави описанието на JSON чудовищно и заема доста място. Дори специално направихме JSON инспектор, за да могат програмистите да видят как работи тяхната джаджа, като заредим JSON с описание в специална форма.