תאריך פרסום: 26 בפברואר 2026
אנימציות שמבוססות על גלילה התפתחו מהטמעות JavaScript לא חלקות בשרשור הראשי לחוויה חלקה, נגישה ומחוץ לשרשור הראשי באמצעות תכונות מודרניות של CSS ושל ממשק משתמש, כמו צירי זמן לגלילה וצירי זמן לתצוגה. המעבר הזה מאפשר ליצור אב טיפוס במהירות ואנימציות עם ביצועים גבוהים, וגם מאפשר לצוותים ליצור דפים מבריקים של סיפור בגלילה, כפי שמתואר במאמר הזה.
NRK וסיפורים
NRK (Norwegian Broadcasting Corporation) הוא שירות השידור הציבורי בשוודיה. הצוות שמאחורי ההטמעה שמתוארת במאמר הזה נקרא Visuelle Historier (נורווגית) – בתרגום משוער Visual Stories (סיפורים חזותיים). הצוות עובד עם עיצוב, גרפיקה ופיתוח בפרויקטים עיתונאיים לטלוויזיה, לרדיו ולאינטרנט, ומפתח זהויות חזותיות, גרפיקה של תוכן, מאמרים מיוחדים ופורמטים חדשים של סיפורים חזותיים. הצוות עובד גם עם פרופיל העיצוב של NRK ועם מותגי המשנה שלה, ויוצר כלים ותבניות שיעזרו לפרסם תוכן בקלות רבה יותר בהתאם לזהות המותג של NRK.
איך NRK משתמשת באנימציות שמתבססות על גלילה
אנימציות שמתבססות על גלילה או מופעלות על ידי גלילה משפרות את הכתבות שלהם, ומעניקות להן אופי אינטראקטיבי, מעניין ומרשים יותר. הגישה הזו שימושית במיוחד בסיפורים לא בדיוניים שבהם יש מעט תמונות או שאין תמונות בכלל.
האנימציות האלה עוזרות לחזק או ליצור נקודות דרמטיות, להניע את הסיפור קדימה ולפתח נרטיבים חזותיים קטנים שתואמים לטקסט או מחזקים אותו. האנימציות האלה מופעלות על ידי גלילה, ומאפשרות למשתמש לשלוט בהתקדמות הסיפור באמצעות הגלילה.
שיפור חוויית המשתמש
לפי תובנות המשתמשים של NRK, הקוראים מעריכים את האופן שבו האנימציות האלה מכוונות את המיקוד שלהם. כשמשתמשים מדגישים טקסט או אנימציות בזמן שהם גוללים, קל יותר להם לזהות נקודות עיקריות ולהבין את ההיבטים החשובים ביותר של הסיפור, במיוחד כשהם קוראים במהירות.
בנוסף, אנימציה של גרפיקה יכולה לפשט מידע מורכב, וכך למשתמשים יהיה קל יותר להבין את היחסים והשינויים לאורך זמן. בעזרת היכולת ליצור, להוסיף או להדגיש מידע באופן דינמי, NRK יכולה להציג תוכן בצורה חינוכית ומעניינת יותר.
הגדרת מצב רוח
אנימציות יכולות להיות כלים יעילים להגדרת האווירה של סיפור או לשיפורה. בעזרת שינוי התזמון, המהירות והסגנון של האנימציות, NRK יכולה לעורר רגשות שתואמים למיקום של העלילה.
פיצול הטקסט והוספת עניין חזותי
ב-NRK משתמשים לעיתים קרובות באיורים מונפשים קטנים כדי לפצל קטעי טקסט ארוכים, בצורת סמליל פשוט או איור קטן, וכך לתת לקוראים הפסקה קצרה מהסיפור. משתמשים רבים אהבו את הווריאציה, והעריכו את העובדה שהיא מפרידה את הטקסט ומקלה על הקריאה שלו. הם סבורים שהיא מספקת הפסקה נעימה ברצף הסיפור.
שמירה על העדפות המשתמשים ועל צרכים של נגישות
כל האזרחים של נורווגיה צריכים להיות יכולים לגשת לדפים הציבוריים של NRK. לכן, הדפים חייבים לפעול בהתאם להעדפות של המשתמשים לגבי תנועה מופחתת. כל תוכן הדף חייב להיות זמין למשתמשים שהפעילו את ההגדרה הזו בדפדפן.
תכנון אנימציות שמתבססות על גלילה
ב-NRK פיתחו ושלבו כלי חדש ליצירת אנימציות גלילה ישירות במערכת ניהול התוכן (CMS) שלהם, Sanity, כדי לייעל את תהליך העבודה שלהם בתכנון. הכלי הזה פותח בשיתוף פעולה בין הצוותים שמפתחים ומנהלים את האתר ואת פתרונות ה-CMS. הוא מאפשר למעצבים ליצור אב טיפוס של אנימציות גלילה ולהטמיע אותן בקלות, עם רמזים חזותיים למיקומי ההתחלה והסיום של אלמנט מונפש, וגם להציג תצוגה מקדימה של האנימציות בזמן אמת. החידוש הזה מעניק למעצבים שליטה רבה יותר ומאיץ את תהליך העיצוב ישירות במערכת ניהול התוכן.

אנימציות שמתבססות על גלילה בדפדפן
אנימציה מבוססת-סיפור
במאמר הזה על גבר שנשאר מת בדירה שלו במשך תשע שנים, נאלצנו להסתמך במידה רבה על איורים בגלל היעדר אלמנטים חזותיים אחרים. כדי להדגיש את העלילה, האנימציה של האיורים התבצעה באמצעות גלילה. לדוגמה, באנימציה שבה מגיע הלילה, התאורה בבניין רב-קומות מופעלת בהדרגה עד שנותרת דירה אחת בלבד שלא מוארת. האנימציה נוצרה באמצעות הכלי הפנימי של NRK ליצירת אנימציה שמבוססת על גלילה.
אנימציה של טקסט עם דהייה
המאמר הזה מתחיל בהקדמה קצרה, בדומה לרצף הפתיחה של סרט. טקסטים תמציתיים בשילוב עם רכיבים חזותיים במסך מלא נועדו לרמוז על תוכן המאמר, כדי לעורר ציפייה ולעודד את הקוראים להיכנס לכתבה המלאה. דף הכותרת עוצב כך שייראה כמו כרזת קולנוע, עם אנימציות שמתבססות על גלילה כדי לחזק את התחושה הזו, באמצעות אנימציה חלקה של הטקסט למעלה ולחוץ.
.article-section {
animation: fade-up linear;
animation-timeline: view();
animation-range: entry 100% exit 100%;
}
טיפוגרפיה עם אנימציה בזמן גלילה
טיפוגרפיה מונפשת בכותרת של מאמר – חופשת מחלה.
בעזרת הפתיח 'Sjukt sjuke' (בתרגום מילולי: 'חולה חולה'), NRK רצתה למשוך קוראים למאמר על העלייה בשיעורי ההיעדרות של עובדים בגלל מחלה בנורווגיה. הכוונה הייתה שהכותרת תהיה מושכת ויזואלית ותרמוז לקוראים שזה לא סיפור רגיל, משעמם ומבוסס-נתונים כפי שהם עשויים לצפות. צוות NRK רצה שהטקסט והאיורים ישקפו את הנושאים של הכתבה, והשתמש בגופנים ובאנימציות שמתרחשות בזמן גלילה כדי לשפר את התוצאה. הכתבה כוללת את הגופן ואת פרופיל העיצוב החדשים של NRK News.
<h1 aria-label="sjuke">
<span>s</span><span>j</span><span>u</span><span>k</span><span>e</span>
<h1>
h1 span {
display: inline-block;
}
if (window.matchMedia('print, (prefers-reduced-motion: reduce)').matches) {
return;
}
const heading = document.querySelector("h1");
const letters = heading.querySelectorAll("span");
const timeline = new ViewTimeline({ subject: heading });
const scales = [/**/];
const rotations = [/**/];
for ([index, el] of letters.entries()) {
el.animate(
{
scale: ["1", scales[index]],
rotate: ["0deg", rotations[index]]
},
{
timeline,
fill: "both",
rangeStart: "contain 30%",
rangeEnd: "contain 70%",
easing: "ease-out"
}
);
}
הדגשת פריטים שנמצאים בחלק העליון של המסך
קוראים שסיימו לקרוא מאמר לעיתים קרובות רוצים לקרוא מידע נוסף על אותה בעיה. בכתבות על בני נוער שמשתמשים בסמים במוסדות, ב-NRK רצו להמליץ על כתבה אחת לקריאה הבאה, תוך מתן אפשרות לקוראים לקרוא כמה כתבות נוספות אם הם רוצים. הפתרון היה ניווט באמצעות החלקה עם התאמה אוטומטית לגלילה ואנימציות שמבוססות על גלילה. האנימציות הבטיחו שהרכיב הפעיל יהיה בפוקוס, בעוד ששאר הרכיבים יהיו כהים יותר.
for (let item of items) {
const timeline = new ViewTimeline({ subject: item, axis: "inline" });
const animation = new Animation(effect, timeline);
item.animate(
{
opacity: [0.3, 1, 0.3]
},
{ timeline, easing: "ease-in-out", fill: "both" }
);
animation.rangeStart = "cover calc(50% - 100px)";
animation.rangeEnd = "cover calc(50% + 100px)";
}
אנימציית גלילה שמפעילה אנימציה רגילה
במאמר הזה על התקציב הלאומי של נורווגיה, NRK ניסתה להפוך את הכתבה, שמבוססת על מספרים כבדים ומשעממים, לנגישה יותר ולהתאים אותה אישית. המטרה הייתה לפרק נתון תקציב עצום ולא מובן, ולתת לקורא תמונה אישית של האופן שבו מוציאים את כספי המס שלו. כל קטע משנה התמקד בפריט ספציפי בתקציב הלאומי. התרומה הכוללת של הקורא לצורכי מס סומנה בסרגל כחול שחולק כדי להציג את התרומה של הקורא לפריטים האלה בנפרד. המעבר הושג באמצעות אנימציה שמבוססת על גלילה, שהפעילה את האנימציה של הפריטים השונים.
const timeline = new ViewTimeline({
subject: containerElement
});
// Setup scroll-driven animation
const scrollAnimation = containerElement.animate(
{
"--cover-color": ["blue", "lightblue"],
scale: ["1 0.2", "1 3"]
},
{
timeline,
easing: "cubic-bezier(1, 0, 0, 0)",
rangeStart: "cover 0%",
rangeEnd: "cover 50%"
}
);
// Wait for scroll-driven animation to complete
await scrollAnimation.finished;
scrollAnimation.cancel();
// Trigger time-driven animations
for (let [index, postElement] of postElements.entries()) {
const animation = postElement?.animate(
{ scale: ["1 3", "1 1"] },
{
duration: 200,
delay: index * 33,
easing: "ease-out",
fill: "backwards"
}
);
}
"אנחנו משתמשים באנימציה שמבוססת על גלילה כבר הרבה זמן. לפני שהיה Web Animations API, היינו צריכים להשתמש באירועי גלילה, בשילוב מאוחר יותר עם Intersection Observer API. בעבר, העבודה הזו הייתה דורשת הרבה זמן, אבל עכשיו היא פשוטה מאוד בעזרת ממשקי ה-API של Web Animations ו-Scroll-Driven Animations" – הלג סילסט (Helge Silset), מפתח ממשק משתמש ב-NRK
ל-NRK יש הרבה רכיבי אינטרנט שונים שאפשר לחבר לאחד מהרכיבים המותאמים אישית שלהם, שנקרא ScrollAnimationDriver
(<scroll-animation-driver>
), שתומך באנימציות הבאות:
- שכבות עם
[KeyframeEffects](https://developer.mozilla.org/docs/Web/API/KeyframeEffect)
- אנימציות Lottie
- mp4
- three.js
<canvas>
בדוגמה הבאה נעשה שימוש בשכבות עם KeyframeEffects
:
<scroll-animation-driver data-range-start='entry-crossing 50%' data-range-end='exit-crossing 50%'>
<layered-animation-effect>
<picture>
<source />
<img />
</picture>
<picture>
<source />
<img />
</picture>
<picture>
<source />
<img />
</picture>
</layered-animation-effect>
</scroll-animation-driver>
ההטמעה של NRK ב-JavaScript של הרכיב המותאם אישית <scroll-animation-driver>
:
export default class ScrollAnimationDriver extends HTMLElement {
#timeline
connectedCallback() {
this.#timeline = new ViewTimeline({subject: this})
for (const child of this.children) {
for (const effect of child.effects ?? []) {
this.#setupAnimationEffect(effect)
}
}
}
#setupAnimationEffect(effect) {
const animation = new Animation(effect, this.#timeline)
animation.rangeStart = this.rangeStart
animation.rangeEnd = this.rangeEnd
if (this.prefersReducedMotion) {
animation.currentTime = CSS.percent(this.defaultProgress * 100)
} else {
animation.play()
}
}
}
export default class LayeredAnimationEffect extends HTMLElement {
get effects() {
return this.layers.flatMap(layer => toKeyframeEffects(layer))
}
}
ביצועי הגלילה
לפני שהתחילו להשתמש באנימציות שמבוססות על גלילה, ל-NRK הייתה הטמעה של JavaScript עם ביצועים טובים מאוד. עכשיו, האנימציות שמבוססות על גלילה מאפשרות להם לשפר את הביצועים עוד יותר בלי לדאוג לתנודות בגלילה, גם במכשירים עם הספק נמוך.
- משך זמן של משימה ללא SDA: 1 אלפית השנייה.
- משך המשימה ב-SDA: 0.16 אלפיות השנייה.

מידע נוסף על ההבדל בביצועים בזמן גלילה בין הטמעות של JavaScript לבין אנימציות שמבוססות על גלילה מפורט במאמר מחקר מקרה על ביצועי אנימציות שמבוססות על גלילה.
שיקולים בנושא נגישות וחוויית משתמש
הנגישות ממלאת תפקיד חשוב בדפים הציבוריים של NRK, כי הם צריכים להיות נגישים לכל האזרחים של נורווגיה במגוון נסיבות. ב-NRK מוודאים שהאנימציות של גלילה נגישות בכמה דרכים:
- התאמה להעדפות של המשתמשים לגבי תנועה מופחתת: שימוש ב-media query
screen and (prefers-reduced-motion: no-preference)
כדי להחיל את האנימציה כהשבחה הדרגתית. מומלץ גם לטפל בסגנונות ההדפסה בו-זמנית. - התחשבות במגוון הרחב של מכשירים וברמת הדיוק המשתנה של קלט הגלילה: משתמשים מסוימים עשויים לגלול בצעדים (לחיצה על מקש הרווח או על מקשי החיצים למעלה/למטה, ניווט לנקודות ציון באמצעות קורא מסך) ולא לראות את כל האנימציה. מוודאים שלא פספסתם מידע חיוני.
- שימוש זהיר באנימציות שמציגות או מסתירות תוכן: משתמשים שמשתמשים בהגדרות הזום של מערכת ההפעלה (OS) עשויים לא להבחין בכך שתוכן מוסתר יופיע כשהם גוללים. אל תאלצו את המשתמשים לחפש אותו. אם צריך להסתיר או להציג תוכן, חשוב לוודא שהוא מופיע ונעלם באותו מקום.
- הימנעות משינויים גדולים בהירות או בניגודיות באנימציה: מאחר שהאנימציות שמבוססות על גלילה תלויות בשליטת המשתמש, שינויים חדים בבהירות עשויים להיראות כהבזקים, שעלולים לגרום להתקפי פרכוס אצל חלק מהמשתמשים.
@media (prefers-reduced-motion: no-preference) {
.article-image {
opacity: 0;
transition: opacity 1s ease-in-out;
}
.article-image.visible {
opacity: 1;
}
}
תמיכה בדפדפנים
כדי לקבל תמיכה רחבה יותר בדפדפנים ב-ScrollTimeline וב-ViewTimeline, NRK משתמשת ב-polyfill בקוד פתוח, שיש לו קהילה פעילה שתורמת לו.
נכון לעכשיו, ה-polyfill נטען באופן מותנה כש-ScrollTimeline
לא זמין, תוך שימוש בגרסה מופחתת של ה-polyfill ללא תמיכה ב-CSS.
if (!('ScrollTimeline' in window)) {
await import('scroll-timeline.js')
}
זיהוי ותמיכה בדפדפנים ב-CSS:
@supports not (animation-timeline: view()) {
.article-section {
translate: 0 calc(-15vh * var(--fallback-progress));
opacity: var(--fallback-progress);
}
}
@supports (animation-timeline: view()) {
.article-section {
animation: --fade-up linear;
animation-timeline: view();
animation-range: entry 100% exit 100%;
}
}
בדוגמה הקודמת לדפדפנים לא נתמכים, ב-NRK משתמשים במשתנה CSS, --fallback-progress
, כחלופה לצורך בקרה על ציר הזמן של האנימציה למאפיינים translate
ו-opacity
.
לאחר מכן, משתנה ה-CSS --fallback-progress
מתעדכן באמצעות מאזין לאירועים scroll
ו-requestAnimationFrame
ב-JavaScript באופן הבא:
function updateProgress() {
const end = el.offsetTop + el.offsetHeight;
const start = end - window.innerHeight;
const scrollTop = document.scrollingElement.scrollTop;
const progress = (scrollTop - start) / (end - start);
document.body.style.setProperty('--fallback-progress', clamp(progress, 0, 1));
}
if (!CSS.supports("animation-timeline: view()")) {
document.addEventListener('scroll', () => {
if (!visible || updating) {
return;
}
window.requestAnimationFrame(() => {
updateProgress();
updating = false;
});
updating = true;
});
}
משאבים
- מקרים לדוגמה של אנימציות שמתבססות על גלילה
- הדגמות: אנימציות שמבוססות על גלילה
- אנימציה של רכיבים בזמן גלילה באמצעות אנימציות מבוססות-גלילה
- Codelab: תחילת העבודה עם אנימציות שמבוססות על גלילה ב-CSS
- תוסף ל-Chrome: תכונת ניפוי באגים של אנימציות שמבוססות על גלילה
- Scroll-timeline Polyfill
- רוצים לדווח על באג או להציע תכונה חדשה? דעתך חשובה לנו.
תודה מיוחדת ל-Hannah Van Opstal, Bramus ו-Andrew Kean Guan מ-Google, ול-Ingrid Reime מ-NRK על התרומות החשובות שלהם לעבודה הזו.