שליטה בהפעלה של אנימציות באינטרנט ב-Chrome 39

מוקדם יותר השנה, Chrome 36 הפעיל את השיטה element.animate כחלק מהמפרט הרחב של אנימציות באינטרנט. כך ניתן ליצור אנימציות מקוריות ויעילות שנכתבו באופן חיוני, וכך המפתחים יכולים ליצור את האנימציות ואת המעברים בעזרת הגישה שהכי מתאימה להם.

כדי לרענן את הידע שלכם במהירות, תוכלו ליצור אנימציה של ענן שדומה למסך טקסט, באמצעות קריאה חוזרת (callback) אחרי שתבצעו את הפעולות הבאות:

var player = cloud.animate([
    {transform: 'translateX(' + start + 'px)'},
    {transform: 'translateX(' + end + 'px)'}
], 5000);
player.onfinish = function() {
    console.info('Cloud moved across the screen!');
    startRaining(cloud);
};

זו לבדו היא קלה מאוד וכדאי מאוד להביא אותה בחשבון כחלק מארגז הכלים שלכם כשיוצרים אנימציות או מעברים באופן חיוני. עם זאת, ב-Chrome 39, תכונות של בקרת הפעלה נוספו לאובייקט AnimationPlayer שהוחזר על ידי element.animate. בעבר, אחרי שהאנימציה נוצרה, אפשר היה להתקשר רק למספר cancel() או להאזין לאירוע הסיום.

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

השהיה או הרצה אחורה או שינוי של קצב ההפעלה

נתחיל מעדכון הדוגמה שלמעלה כדי להשהות את האנימציה אם לוחצים על הענן:

cloud.addEventListener('mousedown', function() {
    player.pause();
});

אפשר גם לשנות את המאפיין playbackRate:

function changeWindSpeed() {
    player.playbackRate *= (Math.random() * 2.0);
}

אפשר גם לקרוא לשיטה reverse(), שבדרך כלל מקבילה להיפוך של הפונקציה playbackRate הנוכחית (מכפילים ב-1-). עם זאת, יש שני מקרים מיוחדים:

  • אם השינוי שייגרם בשיטת ה-reverse() יגרום לאנימציה הרצה להסתיים ביעילות, גם הערך של currentTime הפוך.למשל, אם הפוך אנימציה חדשה לחלוטין, האנימציה כולה תופעל אחורה.

  • אם הנגן מושהה, האנימציה תתחיל לפעול.

שריטות על הנגן

עכשיו AnimationPlayer מאפשר לשנות את currentTime בזמן שאנימציה פועלת. בדרך כלל, הערך הזה יגדל עם הזמן (או ירד, אם הערך של playbackRate שלילי). מצב כזה מאפשר שליטה חיצונית על מיקום האנימציה, אולי באמצעות אינטראקציה של המשתמש. פעולה זו נקראת בדרך כלל החלקה.

לדוגמה, אם דף ה-HTML ייצג את השמיים, ואתם רוצים באמצעות תנועת גרירה כדי לשנות את המיקום של הענן שמופעל כרגע, תוכלו להוסיף כמה handlers למסמך:

var startEvent, startEventTime;
document.addEventListener('touchstart', function(event) {
    startEvent = event;
    startEventTime = players.currentTime;
    player.pause();
});
document.addEventListener('touchmove', function(event) {
    if (!startEvent) return;
    var delta = startEvent.touches[0].screenX -
        event.changedTouches[0].screenX;
    player.currentTime = startEventTime + delta;
});

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

document.addEventListener('touchend', function(event) {
    startEvent = null;
    player.play();
});

אפשר אפילו לשלב את האפשרות הזו עם היפוך, בהתאם למיקום שבו העכבר הורם מהדף (הדגמה משולבת).

במקום לקרצף AnimationPlayer בתגובה לאינטראקציה של משתמש, אפשר להשתמש ב-currentTime גם כדי להציג התקדמות או סטטוס, לדוגמה, להצגת סטטוס של הורדה.

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

מעברים ותנועות בממשק המשתמש

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

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

var steps = [ /* animation steps */ ];
var duration = 1000;
var player = target.animate(steps, duration);
player.pause();
configureStartMoveListeners(player);

var setpoints = [0, 500, 1000];
document.addEventListener('touchend', function(event) {
    var srcTime = player.currentTime;
    var dstTime = findNearest(setpoints, srcTime);
    var driftDuration = dstTime - srcTime;

    if (!driftDuration) {
    runCallback(dstTime);
    return;
    }

    var driftPlayer = target.animate(steps, {
    duration: duration,
    iterationStart: Math.min(srcTime, dstTime) / duration,
    iterations: Math.abs(driftDuration) / duration,
    playbackRate: Math.sign(driftDuration)
    });
    driftPlayer.onfinish = function() { runCallback(dstTime); };
    player.currentTime = dstTime;
});

הפעולה הזו יוצרת אנימציה נוספת שמבצעת 'דריפט'. המעבר מתבצע בין המקום שבו התנועה הושלמה, עד ליעד הטוב הידוע שלנו.

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

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

מעבר קדימה ו-Element.animate

השיטה element.animate לגמרי מתאימה כרגע – בין אם אתם משתמשים בה לאנימציות פשוטות ובין אם אתם ממנפים את AnimationPlayer שהוחזרה בדרכים אחרות.

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

גם המפרט של אנימציות באינטרנט ימשיך להתפתח. אם אתם רוצים להתנסות בתכונות חדשות, הן זמינות גם עכשיו ב-polyfill מפורט יותר: web-animations-next.