تاريخ النشر: 26 شباط (فبراير) 2026
تطوّرت الرسومات المتحرّكة المستندة إلى الانتقال في الصفحة من عمليات تنفيذ JavaScript غير السلسة في سلسلة المهام الرئيسية إلى تجارب سلسة وسهلة الاستخدام خارج سلسلة المهام الرئيسية باستخدام ميزات CSS وواجهة المستخدم الحديثة مثل "المخططات الزمنية للانتقال في الصفحة" و"المخططات الزمنية للعرض". يتيح هذا التغيير إنشاء نماذج أولية سريعة و صور متحركة عالية الأداء، كما يتيح للفِرق إنشاء صفحات سردية مُحسَّنة كما هو موضّح في هذه المقالة.
NRK وسرد القصص
NRK (الهيئة النرويجية للبث) هي خدمة بث عام في النرويج. يُعرف الفريق الذي نفّذ الخطوات الموضّحة في هذه المقالة باسم Visuelle Historier باللغة النرويجية، ويعني ذلك تقريبًا قصص مرئية باللغة الإنجليزية. يعمل الفريق على التصميم والرسومات والتطوير للمشاريع التحريرية التلفزيونية والإذاعية والويب، ويطوّر هويات مرئية ورسومات محتوى ومقالات ملفتة وتنسيقات جديدة لسرد القصص المرئية. يعمل الفريق أيضًا مع ملف العلامة التجارية وعلامات 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" (التي تعني تقريبًا "Sickly sick")، أرادت 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. كان هذا الإجراء يستغرق عادةً وقتًا طويلاً، ولكنّه أصبح الآن بسيطًا باستخدام واجهات برمجة التطبيقات Web Animations وScroll-Driven Animations".—هيلجي سيلست، مطوّر الواجهة الأمامية في 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>
تنفيذ JavaScript في NRK لعنصر <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: ملي ثانية واحدة
- مدة مهمة SDA: 0.16 ملي ثانية

للاطّلاع على مزيد من المعلومات عن الفرق في أداء الانتقال إلى الأسفل أو للأعلى بين عمليات تنفيذ JavaScript وعمليات تنفيذ الرسوم المتحرّكة المستندة إلى الانتقال إلى الأسفل أو للأعلى، يمكنك الاطّلاع على المقالة دراسة حالة عن أداء الرسوم المتحرّكة المستندة إلى الانتقال إلى الأسفل أو للأعلى التي تتناول المزيد من التفاصيل.
اعتبارات سهولة الاستخدام وإمكانية الوصول
تلعب ميزة تسهيل الاستخدام دورًا مهمًا في صفحات NRK العامة، إذ يجب أن تكون متاحة لجميع مواطني النرويج في العديد من الحالات. تتأكّد NRK من أنّه يمكن الوصول إلى الرسوم المتحرّكة للانتقال إلى أعلى أو أسفل الصفحة بعدة طرق مختلفة:
- احترام الإعدادات المفضّلة للمستخدم في ما يتعلّق بتقليل الحركة: استخدام طلب البحث عن الوسائط
screen and (prefers-reduced-motion: no-preference)
لتطبيق الصور المتحركة كتحسين تدريجي من المفيد أيضًا التعامل مع أنماط الطباعة في الوقت نفسه. - الأخذ في الاعتبار النطاق الواسع للأجهزة ودقة إدخال التمرير المتغيرة: قد ينتقل بعض المستخدمين للأعلى أو للأسفل خطوة خطوة (باستخدام مفتاح المسافة أو مفاتيح أعلى/أسفل، أو بالانتقال إلى المعالم باستخدام قارئ شاشة) ولا يظهر لهم المشهد المتحرك بالكامل. تأكَّد من عدم فقدان المعلومات المهمة.
- الحرص على استخدام الصور المتحركة التي تعرض المحتوى أو تخفيه: بالنسبة إلى المستخدمين الذين يعتمدون على ميزة التصغير/التكبير في نظام التشغيل، قد يكون من الصعب ملاحظة أنّه سيتم عرض المحتوى المخفي أثناء تصفّحه. تجنَّب جعل المستخدمين يبحثون عنه. إذا كان إخفاء المحتوى أو عرضه ضروريًا، تأكَّد من اتساق مواضع ظهوره واختفائه.
- تجنُّب إجراء تغييرات كبيرة في السطوع أو التباين في الصور المتحركة: بما أنّ الصور المتحركة التي يتم التحكم فيها من خلال التمرير تعتمد على التحكّم من قِبل المستخدم، يمكن أن تبدو التحولات المفاجئة في الإضاءة وكأنها وميض، ما قد يتسبب في نوبات تشنج لدى بعض المستخدمين.
@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 مفتوحة المصدر، التي تضم منتدى نشطًا يساهم في تطويرها.
يتم حاليًا تحميل العنصر البديل بشكل مشروط عندما لا يكون ScrollTimeline
متاحًا ويتم استخدام إصدار مُبسّط من العنصر البديل بدون إتاحة 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: أداة تصحيح أخطاء الرسوم المتحرّكة المستندة إلى الانتقال
- العناصر القابلة للتمرير في المخطط الزمني
- هل يهمّك الإبلاغ عن خطأ أو ميزة جديدة؟ يهمّنا معرفة رأيك.
نشكر بشكل خاص "هانا فان أوبستال" و"براموس" و"أندرو كين غوان" من Google، و"إنغريد ريم" من NRK على مساهماتهم القيّمة في هذا العمل.