Wprowadzenie
7 sierpnia 2010 r. społeczność deviantART obchodziła 10-lecie istnienia. Z okazji urodzin udostępniliśmy narzędzie do rysowania w formacie HTML5 o nazwie deviantART muro. Narzędzie może być używane jako samodzielna aplikacja internetowa, a także jako lekkie narzędzie do rysowania, które umożliwia dodawanie obrazów do komentarzy na forum.
Użytkownicy deviantART przyjęli to nowe narzędzie do rysowania z wielkim entuzjazmem, a samo narzędzie cieszy się teraz taką samą popularnością jak niektóre duże witryny. Od czasu uruchomienia aplikacji użytkownicy przesyłają nowe rysunki za pomocą deviantART muro średnio co 5 sekund. To tylko liczba ukończonych rysunków. Wiele więcej zostało rozpoczętych, ale nie zapisanych.
Z tego artykułu dowiesz się, jak używamy HTML5, dlaczego zdecydowaliśmy się na te technologie i co odkryliśmy podczas pisania jednej z pierwszych pełnych aplikacji HTML5 dla dużej witryny.
Moje tło
Pod koniec 2005 r. byłem jednym z programistów odpowiedzialnych za narzędzie do rysowania używane przez Draw Here. Było to narzędzie do tworzenia „internetowego graffiti”, uruchomione przez zakładkę. Służyło do rysowania obrazów na dowolnych stronach internetowych. Draw Here został początkowo utworzony za pomocą SVG (właśnie pojawiła się wersja beta przeglądarki Firefox 1.5, która była jednym z pierwszych przeglądarek obsługujących SVG).
W Internet Explorerze plik SVG był tworzony w tle, ale renderowanie rysunku odbywało się za pomocą VML. W tamtym czasie WebKit nie obsługiwał formatu SVG, więc przeportowałem nasz kod, aby renderować SVG za pomocą canvas (która była nową technologią dostępną wtedy tylko w WebKit). W pewnym momencie stworzyłem nawet port, aby nasz kod SVG mógł być renderowany w starszych przeglądarkach za pomocą elementów div sklejonych razem. (To oczywiście żart, który miał pokazać, że jest to możliwe, ale korzystanie z tego rozwiązania jest bardzo powolne).
W okresie największej popularności Draw Here było używane do tworzenia około 100 rysunków dziennie. Było ono na tyle kompletne, że można je było nazwać czymś więcej niż tylko eksperymentem, chociaż nie było jeszcze w pełni dopracowane pod kątem głównej aplikacji internetowej. W połowie 2006 r. projekt został porzucony, ale strona nadal działa, choć głównie dla zabawy.
Technologie używane przez deviantART muro
Ze względu na moje doświadczenie w korzystaniu z różnych technologii HTML5 na ich początkowym etapie rozwoju poproszono mnie o zostanie głównym programistą w deviantART muro. Każdy, kto czyta ten artykuł, może zrozumieć, dlaczego zdecydowaliśmy się na HTML5 zamiast technologii opartej na wtyczkach, takiej jak Silverlight czy Flash. Chcieliśmy, aby było to rozwiązanie niezawodne i wykorzystujące otwarte standardy.
Wybór między Canvas a SVG
Postanowiliśmy utworzyć warstwę rysunku za pomocą płótna. Niektórzy mogą się zastanawiać, kiedy należy używać canvas, a kiedy SVG. Obie technologie mają wiele wspólnych zastosowań – jak pokazała aplikacja Draw Here, obie można wykorzystać do tworzenia aplikacji do rysowania.
Według mnie format SVG jest świetny, jeśli chcesz zachować uchwyty do narysowanych obiektów. Jeśli na przykład chcesz, aby użytkownik mógł narysować linię, a potem przeciągać jej fragmenty, aby zmieniać jej kształt, możesz to łatwo zrobić, używając SVG. Ale to samo jest bardzo niewygodne w przypadku korzystania z kanwy.
Gdy używasz rysunku, wrzucasz na niego różne rzeczy, a potem o nich zapominasz. Pusta i zapełniona przez godzinę paleta zachowują się w kodzie tak samo i zajmują mniej więcej tyle samo pamięci. Chociaż program do rysowania rastrowego zwykle dobrze sprawdza się w przypadku technologii typu „użyj i wyrzuć”, utrudnia ono wykonywanie niektórych zadań. Na przykład szybsze cofanie jest znacznie trudniejsze w Canvas niż w SVG. W pliku SVG możesz zachować uchwyt do kilku ostatnich linii, które zostały umieszczone, a cofniętym jest tylko wyjęcie tych obiektów. W przypadku obrazu po namalowaniu linii nie wiesz, co było pod nią, więc usunięcie linii wymaga przerysowania obszaru, na którym się znajdowała.
Gdy podjęliśmy decyzję o wykorzystaniu HTML5 do tworzenia obrazu, postanowiliśmy też wykorzystać inne funkcje HTML5. Przykładem jest użycie localStorage do śledzenia ustawień pędzla użytkownika. Dzięki temu, gdy użytkownicy skonfigurują różne pędzle tak, jak lubią, będą mogli przywrócić te ustawienia przy następnym użyciu narzędzia. Lokalny magazyn danych oznacza, że nie musimy używać pliku cookie ani łączyć się z serwerem, aby pobrać te ustawienia.
Korzystanie z Canvas
W ciągu ostatnich 5 lat Canvas bardzo się rozwinął. W przypadku Draw Here nie opublikowaliśmy wersji na płótnie, ponieważ nie osiągała ona dobrych wyników. Myślę, że można powiedzieć, że osiąga on lepsze wyniki, niż Ci się wydaje. Wyczyszczenie dużej części płótna i ponowna rysowanie skomplikowanych kształtów może odbywać się z prędkością większą niż ludzkie postrzeganie. Jedynym elementem, który okazał się czasami zbyt wolny, jest wywołanie getImageData() do próbkowania pikseli. Szybkość operacji zależy oczywiście od rozmiaru kanwy, ale w przypadku dużej kanwy wywołanie funkcji getImageData() w niewłaściwym momencie może zająć tyle czasu, że użytkownik może odnieść wrażenie, że aplikacja działa wolno.
Po przeczytaniu różnych samouczków na temat tworzenia aplikacji na kanwie miałam początkowo wrażenie, że jest to bardzo skomplikowana funkcja, której należy używać oszczędnie, może raz lub dwa razy na stronie. Nie wiem, czy wszyscy mają takie poczucie, ale ja tak miałem, więc oszczędnie go używałem, gdy zaczęliśmy kodować deviantART muro. Po pewnym czasie odkryłem jednak, że jest wiele drobnych rzeczy, w których przypadku użycie płótna może zaoszczędzić sporo wysiłku. Na przykład w makietyach naszej aplikacji określono, że selektor kolorów powinien składać się z 2 nachodzących na siebie trójkątów pokazujących kolory podstawowy i dodatkowy:

Na początku pomyślałem, że spróbuję stworzyć ten mały gadżet interfejsu za pomocą tradycyjnego kodu HTML i CSS. Osoby, które świetnie radzą sobie z hackowaniem kodu CSS, mogą wskazać, jak można to zrobić za pomocą kodu CSS, ale kształt trójkąta dwóch części, które zmieniają kolor, sprawia, że nie jest to tak oczywiste.
Gdy wpadł mi do głowy pomysł, żeby użyć tylko płótna, stworzyłem widżet z jednym elementem DOM i kilkoma wierszami kodu JavaScript. Każda warstwa jest płótnem, a zmiana kolejności warstw to tylko zmiana z-indexu. Paleta „przewodnika” powiększenia, która pokazuje pomniejszony widok obszaru rysunku, to tylko kolejne tworzywo, które od czasu do czasu wywołuje funkcję drawImage(), używając tworzywa warstwy jako obrazu źródłowego. Nawet kursor obszaru rysunku (dwukolorowe kółko, które zmienia rozmiar w zależności od rozmiaru pędzla i powiększenia) jest płótnem, które unosi się pod mysz.
Wyjątkiem jest tu biblioteka ExplorerCanvas od Google, która umożliwia symulowanie canvasa w Internet Explorerze. To prowadzi mnie do następnej sekcji.
Internet Explorer (IE)
Głównym powodem, dla którego większość większych witryn nie używa jeszcze HTML5, jest to, że nie chcą tracić użytkowników przeglądarki Internet Explorer. Jestem przekonana, że pierwsze pytanie, które pojawia się w głowie większości deweloperów, gdy dowiadują się, że deviantART stworzył aplikację do rysowania w HTML5, brzmi: „Co zrobiono w przypadku IE?”.
Na początku zdecydowaliśmy, że dołożymy wszelkich starań, aby wszystko działało w Internet Explorerze, ale nie będziemy stosować stylu tworzenia stron internetowych opartego na najmniejszym wspólnym mianowniku. Społeczność internetowa przyjęła podejście, że witryna nie może się uruchomić, dopóki nie będzie wyglądać tak samo we wszystkich znanych przeglądarkach, więc użytkownicy nie mogą stwierdzić, kiedy ich przeglądarka jest niewystarczająca. Zwykle użytkownicy obwiniają o problemy ze szybkością swoje połączenie internetowe, a każda strona renderuje się mniej więcej tak samo. Wybierają więc swoją ulubioną przeglądarkę na podstawie dowolnych elementów interfejsu, takich jak kolor przycisku Wstecz.
Postanowiliśmy stworzyć fajną funkcję, która przyszła nam do głowy, korzystając ze specyfikacji HTML5, spróbować ją uruchomić w Internet Explorerze, a jeśli nie byłoby to możliwe, wyświetlić okno modalne z informacją, że funkcja jest niedostępna, ponieważ przeglądarka nie obsługuje jeszcze standardu internetowego.
Początkowo próbowaliśmy użyć interfejsu ExplorerCanvas (exCanvas) od Google. zaskakująco dobrze radzi sobie z naśladowaniem płótna w większości przypadków. Ma jednak jedną wadę. Każdy obrys wykonany na kanwie jest obiektem DOM w tłumaczeniu VML. W przypadku większości działań, które możesz wykonywać na płótnie, to wystarczy, ale niektóre pędzle w deviantART muro tworzą kształty przez nakładanie wielu kresek. Gdy Internet Explorer napotyka VML z tysiącami węzłów – nawet na szybkim komputerze – przestaje działać i umiera. Z tego powodu w przypadku wielu wywołań rysowania musieliśmy kodować w formie VML, a także używać sztuczek, w których węzły były łączone ze sobą, a polecenie przesuwania było używane do określania, gdzie powinny być luki. Wiele małych elementów sterujących i innych elementów interfejsu korzysta z tagu canvas, ponieważ te małe elementy działają dobrze z exCanvas.
Oprócz dostosowania niektórych funkcji do exCanvas zaproponowaliśmy użytkownikom, aby nadal używali swojej wersji Internet Explorera, jeśli zainstalują wtyczkę Google Chrome Frame. Google Chrome Frame to wtyczka, która umieszcza w Internet Explorerze mechanizm renderowania Google Chrome. Z perspektywy użytkownika nadal korzysta on ze znanej sobie przeglądarki, ale pod maską nasza strona jest renderowana przy użyciu funkcji HTML5 i szybszego JavaScriptu w Chrome.
Wiedziałem, że przenoszenie aplikacji na Chrome Frame powinno być łatwe, ale nie zdawałem sobie sprawy, jak bardzo. Wystarczy dodać dodatkowy metatag i… tyle wystarczy, aby wszystko zaczęło działać w Internet Explorerze.
Podsumowanie
Praca z nowymi technologiami w specyfikacji HTML5 to czysta przyjemność. Wszystko, czego użyliśmy, jest gotowe do użycia. Nawet jeśli potrzebujesz, aby wszystko działało bez zarzutu w IE, możesz robić zaskakująco wiele rzeczy, łącząc canvas i exCanvas. Napisanie warstwy tłumaczenia między SVG a VML jest zaskakująco proste. Gdy zaczniesz korzystać z tej technologii, będzie to jak wejście do zupełnie nowego świata.
Odniesienia
- deviantART muro
- Forum deviantART, na którym możesz rysować (wymaga logowania).
- ExplorerCanvas
- Google Chrome Frame