רינדור עם זמן אחזור קצר עם הינט המסונכרן

Joe Medley
Joe Medley

הבדלים ברינדור הסטיילוס

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

הרמז desynchronized של canvas.getContext() מפעיל נתיב קוד אחר שעוקף את מנגנון עדכון ה-DOM הרגיל. במקום זאת, הרמז מורה למערכת הבסיסית לדלג על האיחוד כך מבטלים את זמן האחזור שייגרם כתוצאה מהשימוש בתור של הקומפוזיטור של הרינדור.

מהי איכות המוצר?

רינדור בו-זמני של Sintel

כדי לגשת לקוד, גוללים קדימה. כדי לראות אותו בפעולה, תצטרכו מכשיר עם מסך מגע, ועדיף סטיילוס. (גם אצבעות לעשות זאת) אם יש לכם דוגמה, כדאי לנסות את הדוגמאות 2d או webgl. לכל שאר המשתתפים כדאי לצפות בהדגמה של מיגל קאסאס, אחד מהמהנדסים שהטמיעו את התכונה הזו. פתחו את ההדגמה, לחצו על 'הפעלה' ואז מזיזים את פס ההזזה באופן אקראי ובמהירות.

בדוגמה הזו נשתמש בקליפ באורך דקה ועשרים שניות מהסרט הקצר Sintel של דוריאן, פרויקט הסרט הפתוח 'בלנדר'. בדוגמה הזו, הסרט מופעל באלמנט <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!');
}

נמנעת הבהוב

יש שני מקרים שבהם אתם יכולים לגרום להבהוב אם לא תתכנתם את הקוד בצורה נכונה.

דפדפנים מסוימים, כולל ניקוי רכיבי WebGL בין מסגרות ל-Chrome. לשלט של הצג יכול להיות אפשרות לקרוא את המאגר בזמן שהוא ריק, וגורם לתמונה להבהב. כדי להימנע מכך, צריך להגדיר את preserveDrawingBuffer לערך true.

const canvas = document.querySelector('myCanvas');
const ctx = canvas.getContext('webgl', {
  desynchronized: true,
  preserveDrawingBuffer: true
});

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

ערוצי אלפא

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

יכולה להיות רק אפשרות אחת

אי אפשר לשנות את מאפייני ההקשר אחרי הקריאה הראשונה ל-canvas.getContext(). זה תמיד היה נכון, אבל חזרה על השלב הזה עלולה לחסוך לכם תסכול אם לא תדעו על כך או אם תשכחו .

לדוגמה, נניח שקיבלתי הקשר והגדרתי את אלפא כ-False, ואז בשלב מאוחר יותר בקוד שלי אני קורא/ת ל-canvas.getContext() בפעם השנייה, עם הגדרת האלפא כ-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, והקשר עם אלפא שווה ל-true לא נוצר אף פעם.

סוגי קנבס הנתמכים

הפרמטר הראשון שמועבר אל getContext() הוא contextType. אם אתם כבר מכירים את getContext(), אתם לא בטוחים אם יש תמיכה במשהו חוץ מסוגי ההקשר '2d'. בטבלה הבאה מוצגים סוגי ההקשר שתומכים ב-desynchronized.

contextType אובייקט סוג הקשר

'2d'

CanvasRenderingContext2D

'webgl'

WebGLRenderingContext

'webgl2'

WebGL2RenderingContext

סיכום

אם תרצו לראות עוד דוגמאות, תוכלו לראות את הדוגמאות. בנוסף לסרטון לדוגמה שכבר מתואר, יש דוגמאות שמציגות גם את ההקשרים '2d' ו-'webgl'.