วิธีที่ NRK ใช้ภาพเคลื่อนไหวที่ทำงานตามการเลื่อนเพื่อทำให้เรื่องราวมีชีวิตชีวา

เผยแพร่: 26 กุมภาพันธ์ 2026

ภาพเคลื่อนไหวที่ทำงานตามการเลื่อนได้พัฒนาจากการใช้งาน JavaScript ในเธรดหลักที่กระตุกเป็นประสบการณ์การใช้งานที่ราบรื่นและเข้าถึงได้นอกเธรดหลักโดยใช้ฟีเจอร์ CSS และ UI ที่ทันสมัย เช่น ไทม์ไลน์การเลื่อนและไทม์ไลน์มุมมอง การเปลี่ยนแปลงนี้ช่วยให้สร้างต้นแบบได้อย่างรวดเร็วและสร้างภาพเคลื่อนไหวที่มีประสิทธิภาพสูง ทั้งยังช่วยให้ทีมสร้างหน้าการเล่าเรื่องแบบเลื่อนที่สมบูรณ์แบบได้ดังที่แสดงในบทความนี้

NRK และการเล่าเรื่อง

NRK (Norwegian Broadcasting Corporation) เป็นผู้ออกอากาศบริการสาธารณะในนอร์เวย์ ทีมที่อยู่เบื้องหลังการใช้งานที่อธิบายไว้ในบทความนี้เรียกว่า Visuelle Historier ในภาษานอร์เวย์ ซึ่งแปลเป็นภาษาอังกฤษคร่าวๆ ว่า Visual Stories ทีมนี้ทำงานเกี่ยวกับการออกแบบ กราฟิก และการพัฒนาโปรเจ็กต์ด้านบรรณาธิการสำหรับทีวี วิทยุ และเว็บ โดยพัฒนาเอกลักษณ์ทางภาพ กราฟิกเนื้อหา บทความแนะนำ และรูปแบบการเล่าเรื่องด้วยภาพใหม่ๆ นอกจากนี้ ทีมยังทำงานร่วมกับโปรไฟล์การออกแบบและแบรนด์ย่อยของ NRK รวมถึงสร้างเครื่องมือและเทมเพลตเพื่อให้เผยแพร่เนื้อหาตามเอกลักษณ์ของแบรนด์ NRK ได้ง่ายขึ้น

วิธีที่ NRK ใช้ภาพเคลื่อนไหวที่ทำงานตามการเลื่อน

ภาพเคลื่อนไหวที่ทำงานตามการเลื่อนและที่ทำงานเมื่อมีการเลื่อนจะช่วยเพิ่มประสิทธิภาพการเล่าเรื่องในบทความด้วยการทำให้เป็นบทความแบบอินเทอร์แอกทีฟ น่าสนใจ และน่าจดจำมากขึ้น แนวทางนี้มีประโยชน์อย่างยิ่งในเนื้อหาสารคดีที่มีรูปภาพเพียงไม่กี่รูปหรือไม่มีเลย

ภาพเคลื่อนไหวเหล่านี้ช่วยเสริมหรือสร้างจุดสำคัญของเรื่อง ขับเคลื่อนเรื่องราวให้ดำเนินต่อไป และสร้างการเล่าเรื่องด้วยภาพเล็กๆ น้อยๆ ที่สอดคล้องกับหรือเสริมข้อความ ภาพเคลื่อนไหวเหล่านี้จะทำงานตามการเลื่อน ทำให้ผู้ใช้ควบคุมความคืบหน้าของเรื่องเล่าได้ด้วยการเลื่อน

ยกระดับประสบการณ์ของผู้ใช้

ข้อมูลเชิงลึกของผู้ใช้ NRK แสดงให้เห็นว่าผู้อ่านชื่นชอบวิธีที่ภาพเคลื่อนไหวเหล่านี้ช่วยกำหนดจุดสนใจ การไฮไลต์ข้อความหรือภาพเคลื่อนไหวขณะที่ผู้ใช้เลื่อนดูจะช่วยให้ผู้ใช้ระบุประเด็นสำคัญและทำความเข้าใจแง่มุมที่สำคัญที่สุดของเรื่องราวได้ง่ายขึ้น โดยเฉพาะเมื่ออ่านผ่านๆ

นอกจากนี้ กราฟิกเคลื่อนไหวยังช่วยลดความซับซ้อนของข้อมูล ทำให้ผู้ใช้เข้าใจความสัมพันธ์และการเปลี่ยนแปลงเมื่อเวลาผ่านไปได้ง่ายขึ้น การสร้าง การเพิ่ม หรือไฮไลต์ข้อมูลแบบไดนามิกช่วยให้ NRK นำเสนอเนื้อหาในลักษณะที่เน้นการเรียนรู้และน่าสนใจยิ่งขึ้น

การสร้างบรรยากาศ

ภาพเคลื่อนไหวเป็นเครื่องมือที่มีประสิทธิภาพในการกำหนดหรือเพิ่มอารมณ์ของเรื่องราว การปรับเวลา ความเร็ว และสไตล์ของภาพเคลื่อนไหวช่วยให้ NRK กระตุ้นอารมณ์ที่ตรงกับโทนของเรื่องเล่าได้

แบ่งข้อความและทำให้ภาพดูสบายตา

NRK มักใช้ภาพเคลื่อนไหวขนาดเล็กเพื่อแบ่งบล็อกข้อความยาวๆ ในรูปแบบของภาพเล็กๆ ง่ายๆ ซึ่งช่วยให้ผู้อ่านหยุดพักจากการอ่านเรื่องราวได้ชั่วขณะ ผู้ใช้จำนวนมากชื่นชอบรูปแบบนี้ โดยระบุว่าเป็นการแบ่งข้อความออกเป็นส่วนๆ และทำให้อ่านง่ายขึ้น ผู้ชมรู้สึกว่าการหยุดชั่วคราวนี้ช่วยสร้างช่วงพักที่พอเหมาะในคําบรรยาย

เคารพความต้องการด้านการช่วยเหลือพิเศษและค่ากําหนดของผู้ใช้

หน้าสาธารณะของ NRK ต้องเข้าถึงได้สำหรับพลเมืองทุกรายของนอร์เวย์ ดังนั้น หน้าเว็บต้องเป็นไปตามความต้องการของผู้ใช้ในการลดการเคลื่อนไหว เนื้อหาหน้าเว็บทั้งหมดต้องพร้อมใช้งานสําหรับผู้ใช้ที่เปิดใช้การตั้งค่าเบราว์เซอร์นี้

การออกแบบภาพเคลื่อนไหวที่ทำงานตามการเลื่อน

NRK ได้ปรับปรุงเวิร์กโฟลว์การออกแบบโดยการพัฒนาและผสานรวมเครื่องมือภาพเคลื่อนไหวแบบเลื่อนใหม่เข้ากับระบบจัดการเนื้อหา (CMS) ของ Sanity โดยตรง เครื่องมือนี้พัฒนาขึ้นโดยความร่วมมือระหว่างทีมที่พัฒนาและดูแลรักษาเว็บไซต์และโซลูชัน CMS ซึ่งช่วยให้นักออกแบบสามารถสร้างต้นแบบและใช้งานภาพเคลื่อนไหวในการเลื่อนได้อย่างง่ายดายด้วยตัวช่วยแสดงภาพสำหรับตำแหน่งเริ่มต้นและสิ้นสุดขององค์ประกอบภาพเคลื่อนไหว รวมถึงสามารถดูตัวอย่างภาพเคลื่อนไหวแบบเรียลไทม์ นวัตกรรมนี้ช่วยให้นักออกแบบมีการควบคุมมากขึ้นและเร่งกระบวนการออกแบบได้โดยตรงภายใน CMS

แสดงพื้นที่ที่เลื่อนเข้ามาในมุมมองในเครื่องมือ
ตัวอย่างที่คล้ายกันของคำแนะนำภาพสำหรับตำแหน่งเริ่มต้นและสิ้นสุดขององค์ประกอบภาพเคลื่อนไหว ไม่ใช่เครื่องมือ CMS จริง

ภาพเคลื่อนไหวที่ทำงานตามการเลื่อนในเบราว์เซอร์

ภาพเคลื่อนไหวที่เน้นเรื่องราว

ชายที่ไม่มีใครคิดถึง

บทความนี้เกี่ยวกับชายคนหนึ่งที่เสียชีวิตในอพาร์ตเมนต์เป็นเวลา 9 ปีต้องใช้ภาพประกอบเป็นอย่างมากเนื่องจากไม่มีองค์ประกอบภาพอื่นๆ ภาพประกอบมีภาพเคลื่อนไหวเมื่อเลื่อนเพื่อเน้นการเล่าเรื่อง เช่น ในภาพเคลื่อนไหวที่เวลาล่วงเลยเข้าสู่ช่วงกลางคืน ไฟในอาคารสูงหลายชั้นค่อยๆ เปิดขึ้นจนเหลือเพียงอพาร์ตเมนต์เดียวที่ยังไม่ได้เปิดไฟ ภาพเคลื่อนไหวสร้างขึ้นโดยใช้เครื่องมือภาพเคลื่อนไหวแบบเลื่อนที่ NRK พัฒนาขึ้นเอง

ภาพเคลื่อนไหวข้อความค่อยๆ จางหายไป

permafrost

บทความนี้เริ่มต้นด้วยการแนะนำสั้นๆ ซึ่งเลียนแบบช่วงเปิดของภาพยนตร์ ข้อความที่กระชับซึ่งมาพร้อมกับภาพแบบเต็มหน้าจอได้รับการออกแบบมาเพื่อบอกใบ้ถึงเนื้อหาของบทความ สร้างความคาดหวังเพื่อกระตุ้นให้ผู้อ่านอ่านบทความฉบับเต็ม หน้าปกออกแบบมาให้คล้ายกับโปสเตอร์ภาพยนตร์ โดยมีการใช้ภาพเคลื่อนไหวที่ทำงานตามการเลื่อนเพื่อเสริมความรู้สึกนี้ด้วยการแสดงภาพข้อความขึ้นและออกอย่างราบรื่น

.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 ต้องการแนะนำบทความเดียวให้อ่านต่อ ขณะเดียวกันก็ให้ตัวเลือกบทความอื่นๆ แก่ผู้อ่านด้วยหากต้องการ โซลูชันคือการนำทางแบบปัดที่ใช้การเลื่อนแบบ Snap และภาพเคลื่อนไหวที่ทำงานด้วยการเลื่อน ภาพเคลื่อนไหวช่วยให้แน่ใจว่าองค์ประกอบที่ใช้งานอยู่อยู่ในโฟกัส ขณะที่องค์ประกอบที่เหลือจะสลัวลง

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"
    }
  );
}

"เราใช้ภาพเคลื่อนไหวที่ทำงานตามการเลื่อนมาเป็นเวลานานแล้ว ก่อนหน้านี้เราต้องใช้เหตุการณ์การเลื่อน ซึ่งต่อมาได้รวมเข้ากับ Intersection Observer API การดำเนินการนี้มักจะใช้เวลานานมาก แต่ตอนนี้กลายเป็นเรื่องง่ายดายด้วย Web Animations และ Scroll-Driven Animations API" - Helge Silset นักพัฒนาซอฟต์แวร์ฝั่งเฟรมเวิร์ก (Front-end) ที่ 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: 1 มิลลิวินาที
  • ระยะเวลาของงาน SDA: 0.16 มิลลิวินาที
แท็บประสิทธิภาพของเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome
การบันทึกในแท็บประสิทธิภาพของเครื่องมือสําหรับนักพัฒนาเว็บใน Chrome ที่การทํางานของ CPU ช้าลง 6 เท่าแสดง 0.16 มิลลิวินาทีสําหรับแต่ละงานในเฟรมใหม่

หากต้องการอ่านเพิ่มเติมเกี่ยวกับความแตกต่างของประสิทธิภาพการเลื่อนระหว่างการติดตั้งใช้งาน JavaScript กับภาพเคลื่อนไหวที่ทำงานตามการเลื่อน โปรดอ่านบทความกรณีศึกษาเกี่ยวกับประสิทธิภาพของภาพเคลื่อนไหวที่ทำงานตามการเลื่อนซึ่งจะอธิบายรายละเอียดเพิ่มเติม

การช่วยเหลือพิเศษและข้อควรพิจารณาเกี่ยวกับ UX

การช่วยเหลือพิเศษมีบทบาทสำคัญในหน้าสาธารณะของ NRK เนื่องจากหน้าดังกล่าวต้องเข้าถึงได้สำหรับพลเมืองทุกรายของนอร์เวย์ในหลายๆ สถานการณ์ NRK ช่วยให้ผู้ใช้เข้าถึงภาพเคลื่อนไหวในการเลื่อนได้หลายวิธีดังนี้

  • เคารพความต้องการของผู้ใช้ในการลดการเคลื่อนไหว: ใช้ Media Query screen and (prefers-reduced-motion: no-preference) เพื่อใช้ภาพเคลื่อนไหวเป็นการเพิ่มประสิทธิภาพแบบเป็นขั้นเป็นตอน ทั้งยังช่วยจัดการสไตล์การพิมพ์ได้ในเวลาเดียวกันด้วย
  • คำนึงถึงอุปกรณ์ที่หลากหลายและความละเอียดของอินพุตการเลื่อน: ผู้ใช้บางรายอาจเลื่อนทีละขั้น (Space หรือแป้นขึ้น/ลง การไปยังจุดสังเกตโดยใช้โปรแกรมอ่านหน้าจอ) และไม่เห็นภาพเคลื่อนไหวทั้งหมด ตรวจสอบว่าไม่พลาดข้อมูลสำคัญ
  • ระมัดระวังการใช้ภาพเคลื่อนไหวที่แสดงหรือซ่อนเนื้อหา: ผู้ใช้ที่พึ่งพาการซูมของระบบปฏิบัติการ (OS) อาจสังเกตไม่เห็นว่าเนื้อหาที่ซ่อนอยู่จะปรากฏขึ้นขณะที่เลื่อนดู หลีกเลี่ยงการทําให้ผู้ใช้ต้องค้นหา หากจำเป็นต้องซ่อนหรือแสดงเนื้อหา ให้ตรวจสอบว่าตำแหน่งที่เนื้อหาปรากฏและหายไปมีความสอดคล้องกัน
  • หลีกเลี่ยงการเปลี่ยนแปลงความสว่างหรือคอนทราสต์อย่างมากในภาพเคลื่อนไหว: เนื่องจากภาพเคลื่อนไหวที่ทำงานด้วยการเลื่อนขึ้นอยู่กับการควบคุมของผู้ใช้ การเปลี่ยนแปลงความสว่างอย่างฉับพลันจึงอาจดูเหมือนการกะพริบ ซึ่งอาจทำให้เกิดอาการชักในผู้ใช้บางราย
@media (prefers-reduced-motion: no-preference) {
  .article-image {
    opacity: 0;
    transition: opacity 1s ease-in-out;
  }
  .article-image.visible {
    opacity: 1;
  }
}

การสนับสนุนเบราว์เซอร์

NRK ใช้ Polyfill แบบโอเพนซอร์สเพื่อรองรับเบราว์เซอร์ที่หลากหลายมากขึ้นสำหรับ ScrollTimeline และ ViewTimeline โดยมีชุมชนที่มีส่วนร่วมในการพัฒนา

ปัจจุบันระบบจะโหลด 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 ด้วยevent listener และ requestAnimationFrame ใน JavaScript ดังนี้scroll

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;
  });
}

แหล่งข้อมูล

ขอขอบคุณเป็นพิเศษ Hannah Van Opstal, Bramus และ Andrew Kean Guan จาก Google และ Ingrid Reime จาก NRK ที่ให้ความร่วมมืออันมีค่าในงานนี้