מקרה לדוגמה - HTML5 ב-DeviantART Muro

Mike Dewey
Mike Dewey

מבוא

ב-7 באוגוסט 2010, ציינו ב-deviantART את יום ההולדת העשירי של האתר. כדי לחגוג את יום ההולדת שלנו, השקנו כלי ציור ב-HTML5 שנקרא deviantART muro. אפשר להשתמש בכלי כאפליקציית אינטרנט עצמאית, וגם ככלי קל לציור להוספת תמונות לתגובות בפורומים.

קהילת deviantART קיבלה את כלי הציור החדש הזה בהתלהבות רבה, והכלי עצמו זוכה עכשיו לתנועה כמו של נכסי אינטרנט מסוימים בגודל סביר. מאז ההשקה, ציור חדש נשלח באמצעות deviantART muro בערך כל 5 שניות. אלה רק מספרי הציורים שהושלמו. הרבה יותר ציורים החלו ולא נשמרו.

במאמר הבא מוסבר איך אנחנו משתמשים ב-HTML5, למה בחרנו להשתמש בטכנולוגיות האלה ומה גיליתי בזמן כתיבת אחת מהאפליקציות הראשונות ב-HTML5 לאתר גדול.

הרקע שלי

בסוף שנת 2005, הייתי אחד מהמפתחים שאחראים לכלי השרטוט שמשמש את Draw Here. הכלי היה כלי 'גרפיטי אינטרנט' שהופעל באמצעות סימנייה. הוא שימש לציור תמונות בכל דפי אינטרנט. Draw Here נוצר בהתחלה באמצעות SVG (גרסת הבטא של Firefox 1.5 הושקה זה עתה, והיא הייתה אחת מהדפדפנים הראשונים שתומכים ב-SVG).

ב-Internet Explorer, יצרנו קובץ SVG ברקע, אבל ביצענו רינדור של הציור באמצעות VML. באותו זמן, מערכת WebKit לא תמכה ב-SVG, ולכן העברתי את הקוד שלנו לעיבוד ה-SVG באמצעות canvas (שהייתה טכנולוגיה חדשה שרק ב-WebKit השתמשו בה באותו זמן). בשלב מסוים אפילו יצרתי גרסת פורט כדי שקוד ה-SVG שלנו יוכל להירנדר בדפדפנים ישנים יותר באמצעות כמה אלמנטים של div מודבקים יחד. (הסיפור הזה היה כמובן יותר בדיחה כדי להראות שאפשר לעשות את זה, והשימוש בו היה איטי מאוד).

בשיא הפופולריות של Draw Here, נוצרו בעזרתו כ-100 ציורים ביום. הוא היה מלא דיו כדי להיקרא יותר מניסוי, אבל הוא לא עבר את השיפורים האחרונים של אפליקציית אינטרנט גדולה. באמצע 2006 הפרויקט נטוש, אבל האתר עדיין פועל – בעיקר בשביל הכיף.

הטכנולוגיות שבהן נעשה שימוש ב-deviantART muro

בגלל הרקע שלי בשימוש בטכנולוגיות שונות של HTML5 בשלבים המוקדמים שלהן, התבקשתי להיות המפתח הראשי ב-deviantART muro. כל מי שקורא את המאמר הזה יכול להבין למה החלטנו להשתמש ב-HTML5 במקום בטכנולוגיה שמבוססת על יישומי פלאגין כמו Silverlight או Flash. רצינו משהו חזק וגם משהו שמשתמש בתקנים פתוחים.

איך בוחרים בין קנבס ל-SVG

החלטנו ליצור את שכבת הציור באמצעות קנבס. יכול להיות שחלק מהאנשים יתלבטו מתי כדאי להשתמש ב-canvas ומתי כדאי להשתמש ב-SVG. יש הרבה חפיפה בדברים שאפשר לעשות בשתי הטכנולוגיות – כפי שהוכח ב-Draw Here, אפשר להשתמש בשתי הטכנולוגיות כדי ליצור אפליקציית ציור.

גיליתי ש-SVG מצוין אם רוצים לשמור על רכיבי אחיזה של אובייקטים שציירתם. לדוגמה, אם רוצים שהמשתמש יוכל לצייר קו ואז לגרור חלקים מהקו כדי לשנות את הצורה שלו, זה קל מאוד באמצעות SVG. אבל זה מאוד לא נוח לעשות את אותו הדבר על קנבס.

כשמשתמשים בקנבס, פשוט מציבים את הדברים על הקנבס וממשיכים הלאה. לוח ציור ריק ולוח ציור שציירתם עליו במשך שעה פועלים בדיוק באותו אופן בקוד, והם תופסים בערך את אותה כמות זיכרון. תוכנת ציור רסטר בדרך כלל עובדת מצוין עם הטכנולוגיה 'אש ושכחה', אבל יש דברים מסוימים שהיא מקשה עליהם. לדוגמה, קשה הרבה יותר ליצור פונקציית ביטול מהיר ב-Canvas מאשר ב-SVG. ב-SVG, אפשר פשוט לשמור על הידית של כמה הקווים האחרונים שהנחתם, ולבטל את הפעולה פשוט על ידי הסרת האובייקטים האלה. בקנבס, אחרי שציירתם קו, אתם לא יודעים מה היה מתחתיו, ולכן כדי להסיר את הקו צריך לצייר מחדש את האזור שבו הוא היה.

אחרי שהחלטנו להשתמש ב-HTML5 לקנבס, החלטנו להשתמש בקטעים קטנים של תכונות HTML5 אחרות פה ושם. דוגמה לכך היא האופן שבו השתמשנו ב-localStorage כדי לעקוב אחרי הגדרות המברשת של המשתמש. כך, אחרי שהם מגדירים את המברשות השונות בדיוק כמו שהם אוהבים, הם יכולים לחזור להגדרות האלה בפעם הבאה שהם משתמשים בכלי שלנו. localStorage מאפשר לנו לא להשתמש בקובץ ה-cookie או לבצע נסיעות לשרת כדי לקבל את ההעדפות האלה.

שימוש בלוח הציור

התמונות בפורמט 'קנבס' עברו כברת דרך ארוכה בחמש השנים האחרונות. ב-Draw Here לא פרסמנו את הגרסה שלי לקנבס כי הביצועים לא היו טובים. עכשיו, לדעתי, אפשר לומר בבטחה שהביצועים שלה טובים יותר ממה שאתם חושבים. בדרך כלל אפשר למחוק קטע גדול מהקנבס ולצייר מחדש צורות מורכבות במהירות גבוהה מהתפיסה האנושית. הדבר היחיד שגיליתי שהוא איטי מדי לפעמים הוא השימוש ב-getImageData() כדי לדגום פיקסלים. כמובן שהמהירות של הפעולה תלויה בגודל הלוח, אבל בלוח גדול, ביצוע של getImageData() בזמן הלא נכון יכול להימשך זמן רב מספיק כדי שהמשתמש ירגיש שהאפליקציה מגיבה לאט.

אחרי שקראתי מדריכים שונים בנושא קנבס, בהתחלה נראה לי שמדובר בעניין כבד שצריך להשתמש בו במשורה, אולי פעם או פעמיים בדף. לא בטוח שכל אחד מבין את זה, אבל אני הבנתי את זה, ולכן השתמשתי בו במשורה כשהתחלנו לכתוב את הקוד של deviantART muro. עם זאת, אחרי זמן מה גיליתי שיש הרבה מקומות קטנים שבהם קנבס יכול לחסוך הרבה מאמץ. לדוגמה, בתצוגות המקדמות של האפליקציה שלנו צוין שצריך להיות בוחר צבעים שמורכב משני משולשים חופפים שמוצגים בהם צבעים ראשיים ומשניים:

בוחר צבעים
בורר צבעים

האינסטינקט הראשון שלי היה להתחיל לחשוב על דרך ליצור את הכלי הקטן הזה לממשק המשתמש באמצעות HTML ו-CSS רגילים. אנשים שמומחים לפריצה ל-CSS עשויים להצביע על הדרכים שבהן אפשר לעשות את כל זה באמצעות CSS, אבל צורת המשולש של שני החלקים שמשתנים צבע לא מובנת מאליה.

כשחברי הצוות שלי הציע לי להשתמש רק בקנבס, יצרתי את הווידג'ט באמצעות רכיב DOM אחד וכמה שורות של JavaScript. ב-deviantART muro נעשה שימוש בצומתי קנבס בכל מקום. כל שכבה היא קנבס, ושינוי סדר השכבות הוא פשוט עניין של שינוי אינדקס-z. לוח ה 'ניווט' של הזום, שבו מוצגת תצוגה מוקטנת של אזור הציור, הוא רק קנבס נוסף שמפעיל מדי פעם את drawImage() באמצעות קנבסי השכבות כתמונות מקור. גם הסמן של אזור הציור (עיגול דו-גווני שמשתנה בהתאם לגודל המברשת ולרמת הזום) הוא קנבס שצף מתחת לעכבר.

הסיבה לכך שאנחנו נוהגים באופן ליברלי יותר בשימוש ב-Canvas בהשוואה לטכנולוגיות HTML5 אחרות היא שספריית ExplorerCanvas של Google מאפשרת לדמות את Canvas ב-Internet Explorer. זה מוביל אותי לקטע הבא.

Internet Explorer‏ (IE)

הסיבה העיקרית לכך שעדיין יש אתרים גדולים שלא משתמשים ב-HTML5 היא שהם לא רוצים לאבד את משתמשי Internet Explorer. אני בטוח שהשאלה הראשונה שעולה בראשם של רוב המפתחים כשהם שומעים ש-deviantART יצרה אפליקציית ציור ב-HTML5 היא "מה נעשה לגבי IE?"

כבר בהתחלה החלטנו שנשתדל מאוד לגרום לדברים לפעול ב-Internet Explorer, אבל שסיימנו עם סגנון הפיתוח של האינטרנט שמתבסס על המכנה המשותף הנמוך ביותר. קהילת האינטרנט קבעה שאי אפשר להשיק אתר עד שהוא נראה אותו דבר בכל דפדפן ידוע, ולכן המשתמשים לא יכולים לדעת מתי הדפדפן שלהם חסר. בעיות מהירות נראות למשתמש הממוצע כבעיות בחיבור האינטרנט, וכל דף נטען בערך באותו זמן. לכן הם מחליטים על הדפדפן האהוב עליהם על סמך דברים קטנים ושרירותיים בממשק המשתמש, כמו הצבע של לחצן החזרה אחורה.

החלטנו ליצור כל תכונה מגניב שתחזור לנו בראש באמצעות מפרט HTML5, לנסות לגרום לה לפעול ב-Internet Explorer, ואם היא לא תפעל, פשוט להציג חלון קופץ עם הסבר שהתכונה לא זמינה כי הדפדפן עדיין לא הטמיע תקן אינטרנט.

בהתחלה ניסינו להפעיל את התכונה באמצעות ExplorerCanvas (exCanvas) של Google. הוא מצליח לחקות את ההדפסה על קנבס בצורה מפתיעה ברוב המקרים. עם זאת, יש לכך צד שלילי אחד. כל קו שנוצר בקנבס הוא אובייקט DOM בתרגום ה-VML הבסיסי. זה בסדר גמור לרוב הדברים שאפשר לנסות על קנבס, אבל חלק מהמכחולים של deviantART muro יוצרים צורות על ידי שכבות של הרבה קווים יחד. כש-Internet Explorer נתקל ב-VML עם אלפי צמתים – גם במכונה מהירה – הוא נכשל. לכן, בחלק גדול מהקריאות לציור, נאלצנו לכתוב קוד ב-VML בפועל, ולהשתמש בטריקים שבהם אנו מקשרים את הצמתים יחד ומשתמשים בפקודת ההעברה כדי לציין איפה צריכים להיות פערים. הרבה מהפקדים הקטנים והדברים האחרים בממשק משתמשים בתג canvas, כי בדרך כלל השימושים הקטנים האלה עבדו טוב עם exCanvas.

בנוסף לכך שחלק מהדברים פועלים עם exCanvas, הצענו למשתמשים להמשיך להשתמש בגרסה שלהם של Internet Explorer אם הם מתקינים את הפלאגין Google Chrome Frame. Google Chrome Frame הוא פלאגין שמטמיע את מנוע הרינדור של Google Chrome ב-Internet Explorer. מנקודת המבט של המשתמש, הוא עדיין משתמש בדפדפן המוכר לו, אבל מתחת לפני השטח הדף עובר עיבוד באמצעות יכולות ה-HTML5 של Chrome ו-JavaScript מהיר יותר.

ידעתי שצריך להיות קל להעביר דברים לעבודה עם Chrome Frame, אבל לא הבנתי עד כמה זה פשוט. פשוט מוסיפים מטא תג נוסף… וזהו, הדברים מתחילים לפעול ב-IE.

סיכום

נהניתי מאוד לעבוד עם הטכנולוגיות החדשות במפרט HTML5, ואני יכול לומר שכל מה שהשתמשתי בו מוכן לשימוש. גם אם אתם צריכים שהדברים יפעלו בצורה חלקה ב-IE, יש כמות מפתיעה של דברים שאפשר לעשות בשילוב של canvas ו-exCanvas. וגם קל מאוד לכתוב שכבת תרגום בין SVG ל-VML. אחרי שמתחילים להשתמש בטכנולוגיה, זה כמו להיכנס לעולם חדש לגמרי.

קובצי עזר