אפליקציות ציור מבוססות-סטיילוס שנוצרו לאינטרנט סבלו במשך זמן רב מבעיות זמן אחזור, כי דף אינטרנט צריך לסנכרן עדכוני גרפיקה עם ה-DOM. בכל אפליקציית ציור, זמני אחזור ארוכים מ-50 אלפיות שנייה עלולים להפריע לקואורדינציה בין היד לעין של המשתמש, וכתוצאה מכך קשה להשתמש באפליקציות.
ההצעה desynchronized
ל-canvas.getContext()
מפעילה נתיב קוד אחר שעוקף את מנגנון העדכון הרגיל של DOM.
במקום זאת, ההצעה מורה למערכת הבסיסית לדלג על כמה שיותר שילובים, ובמקרים מסוימים מאגר הזיכרון הבסיסי של הלוח נשלח ישירות לבקר המסך. כך אפשר למנוע את זמן האחזור שנגרם כתוצאה משימוש בתור של ה-renderer compositor.
מה איכות המוצר?
כדי להגיע לקוד, גוללים קדימה. כדי לראות איך זה עובד, צריך מכשיר עם מסך מגע, רצוי עם עט. (אפשר להשתמש גם באצבעות). אם יש לכם, נסו את הדוגמאות ל-2d או ל-webgl. שאר האנשים יכולים לצפות בדמו של מיגל קאסאס, אחד מהמהנדסים שהטמיעו את התכונה הזו. פותחים את הדמו, לוחצים על 'הפעלה' ומזיזים את פס ההזזה קדימה ואחורה באופן אקראי ומהיר.
בדוגמה הזו נעשה שימוש בקליפ באורך דקה ועשרים ושלוש שניות מהסרט הקצר Sintel של Durian, פרויקט הסרטים הפתוח של Blender. בדוגמה הזו, הסרט מופעל ברכיב <video>
שהתוכן שלו מומר בו-זמנית לרכיב <canvas>
. הרבה מכשירים יכולים לעשות זאת בלי קריעה, אבל במכשירים עם רינדור של מאגר קדמי, כמו ChromeOS למשל, עשויה להיות קריעה. (הסרט מצוין, אבל הוא עצוב מאוד.
אחרי שראיתי את זה, לא הייתי מסוגלת לעשות כלום במשך שעה. זהו, קיבלתם אזהרה).
שימוש ברמיזה
השימוש בזמן אחזור נמוך כולל הרבה יותר מאשר הוספת desynchronized
ל-canvas.getContext()
. אעבור על הבעיות אחת אחרי השנייה.
יצירת לוח הציור
בממשק API אחר, הייתי מתחיל בתיאור של זיהוי התכונות. כדי להשתמש בהצעה desynchronized
, קודם צריך ליצור את לוח הציור. קוראים ל-canvas.getContext()
ומעבירים לו את ההצעה החדשה desynchronized
עם הערך true
.
const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('2d', {
desynchronized: true,
// Other options. See below.
});
זיהוי תכונות
בשלב הבא, מתקשרים למספר getContextAttributes()
. אם לאובייקט המאפיינים המוחזר יש מאפיין desynchronized
, צריך לבדוק אותו.
if (ctx.getContextAttributes().desynchronized) {
console.log('Low latency canvas supported. Yay!');
} else {
console.log('Low latency canvas not supported. Boo!');
}
הימנעות מבהוב
יש שני מקרים שבהם קוד שגוי עלול לגרום לרטט.
חלק מהדפדפנים, כולל Chrome, מנקים את משטחי הקנבס של WebGL בין הפריימים. יכול להיות שמתג המסך יקרא את המאגר בזמן שהוא ריק, וכתוצאה מכך התמונה שתוצג תהיה מהבהבת. כדי למנוע זאת, צריך להגדיר את preserveDrawingBuffer
לערך true
.
const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('webgl', {
desynchronized: true,
preserveDrawingBuffer: true
});
הבהוב יכול להתרחש גם כשמנקים את הקשר המסך בקוד הציור שלכם. אם אתם חייבים לנקות, ציירו ב-framebuffer מחוץ למסך ואז העבירו אותו למסך.
ערוצי אלפא
עדיין אפשר לבטל את הסנכרון של רכיב בד שקוף, שבו הערך של alpha מוגדר כ-true, אבל אסור שיהיו מעליו רכיבי DOM אחרים.
יכול להיות רק אחד
לא ניתן לשנות את מאפייני ההקשר אחרי הקריאה הראשונה ל-canvas.getContext()
. זה תמיד היה נכון, אבל כדאי לחזור על כך כדי למנוע תסכול אם לא ידעתם או שכחתם .
לדוגמה, נניח שאני מקבל הקשר ומציין את alpha כ-false, ואז במקום כלשהו בהמשך הקוד שלי אני קורא ל-canvas.getContext()
בפעם השנייה עם alpha מוגדר כ-true, כפי שמוצג בהמשך.
const canvas = document.querySelector('myCanvas');
const ctx1 = canvas.getContext('2d', {
alpha: false,
desynchronized: true,
});
//Some time later, in another corner of code.
const ctx2 = canvas.getContext('2d', {
alpha: true,
desynchronized: true,
});
לא ברור ש-ctx1
ו-ctx2
הם אותו אובייקט. הערך של alpha עדיין false, ולעולם לא נוצר הקשר שבו alpha שווה ל-true.
סוגי קנבס נתמכים
הפרמטר הראשון שמוענק ל-getContext()
הוא contextType
. אם אתם כבר מכירים את getContext()
, סביר להניח שאתם תוהים אם יש תמיכה בסוגי הקשר אחרים מלבד '2d'. בטבלה הבאה מוצגים סוגי ההקשרים שתומכים ב-desynchronized
.
contextType | אובייקט של סוג הקשר |
---|---|
|
|
|
|
|
|
סיכום
כדי לראות עוד דוגמאות, אפשר לעיין בדוגמאות. בנוסף לדוגמה לסרטון שכבר תיארה, יש דוגמאות שמציגות גם הקשרים מסוג '2d' וגם הקשרים מסוג 'webgl'.