ดูวิธีใช้งานไทม์ไลน์แบบเลื่อนและดูไทม์ไลน์เพื่อสร้างภาพเคลื่อนไหวแบบเลื่อนที่ขับเคลื่อนด้วยการประกาศ
ภาพเคลื่อนไหวแบบเลื่อน
ภาพเคลื่อนไหวที่เลื่อนดูได้เป็นรูปแบบ UX ที่พบได้ทั่วไปบนเว็บ ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนลิงก์กับตำแหน่งการเลื่อนของคอนเทนเนอร์แบบเลื่อน ซึ่งหมายความว่าเมื่อคุณเลื่อนขึ้นหรือลง ภาพเคลื่อนไหวที่ลิงก์จะสครับไปข้างหน้าหรือถอยหลังในการตอบกลับโดยตรง เช่น ภาพพื้นหลังพารัลแลกซ์หรือสัญญาณบอกสถานะการอ่านที่เคลื่อนไหวขณะที่คุณเลื่อน
ภาพเคลื่อนไหวแบบเลื่อนที่คล้ายกันอีกประเภทหนึ่งคือภาพเคลื่อนไหวที่ลิงก์กับตำแหน่งขององค์ประกอบภายในคอนเทนเนอร์แบบเลื่อน ตัวอย่างเช่น เมื่อมีองค์ประกอบนี้ องค์ประกอบต่างๆ อาจค่อยๆ ปรากฏขึ้นเมื่อปรากฏให้เห็น
วิธีคลาสสิกในการบรรลุผลประเภทนี้คือการตอบกลับเหตุการณ์การเลื่อนในเทรดหลัก ซึ่งนําไปสู่ปัญหาหลัก 2 ประการดังนี้
- เบราว์เซอร์สมัยใหม่จะเลื่อนบนกระบวนการที่แยกต่างหาก ดังนั้นจึงแสดงเหตุการณ์การเลื่อนแบบไม่พร้อมกัน
- ภาพเคลื่อนไหวของชุดข้อความหลักมีการเปลี่ยนแปลงที่การกระตุก
ซึ่งทำให้การสร้างภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนที่มีประสิทธิภาพซึ่งซิงค์กับการเลื่อนเป็นไปไม่ได้หรือทำได้ยากมาก
ตั้งแต่ Chrome เวอร์ชัน 115 เป็นต้นไป เรามี API และแนวคิดชุดใหม่ที่คุณสามารถใช้เพื่อเปิดใช้ภาพเคลื่อนไหวแบบเลื่อนที่ต้องประกาศแบบเลื่อนประกาศ ซึ่งได้แก่ ไทม์ไลน์ของการเลื่อนและดูไทม์ไลน์
แนวคิดใหม่เหล่านี้ผสานรวมกับ Web Animations API (WAAPI) และ CSS Animations API ที่มีอยู่ ทำให้โมเดลนี้ได้รับประโยชน์จาก API ที่มีอยู่เหล่านี้ ซึ่งรวมถึงความสามารถในการทำให้ภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนออกจากเทรดหลัก ใช่ อ่านถูกต้อง: ตอนนี้คุณสามารถใช้ภาพเคลื่อนไหวที่ลื่นไหลซึ่งขับเคลื่อนโดยการเลื่อน ออกจากชุดข้อความหลัก โดยมีโค้ดเพิ่มเติมเพียง 2-3 บรรทัด สิ่งที่ไม่ชอบ
ภาพเคลื่อนไหวบนเว็บ สรุปสั้นๆ
ภาพเคลื่อนไหวบนเว็บด้วย CSS
หากต้องการสร้างภาพเคลื่อนไหวใน CSS ให้กำหนดชุดคีย์เฟรมโดยใช้กฎ @keyframes
ลิงก์องค์ประกอบกับองค์ประกอบโดยใช้พร็อพเพอร์ตี้ animation-name
ไปพร้อมกับตั้งค่า animation-duration
เพื่อกำหนดระยะเวลาที่จะใช้ภาพเคลื่อนไหว มีพร็อพเพอร์ตี้ลองมือ animation-*
เพิ่มเติม เช่น animation-easing-function
และ animation-fill-mode
เพียงไม่กี่รายการ ซึ่งทั้งหมดสามารถรวมกันได้ในชวเลข animation
ลองดูตัวอย่างภาพเคลื่อนไหวต่อไปนี้ที่ปรับขนาดองค์ประกอบบนแกน X ขณะที่เปลี่ยนสีพื้นหลัง
@keyframes scale-up {
from {
background-color: red;
transform: scaleX(0);
}
to {
background-color: darkred;
transform: scaleX(1);
}
}
#progressbar {
animation: 2.5s linear forwards scale-up;
}
ภาพเคลื่อนไหวบนเว็บด้วย JavaScript
ใน JavaScript คุณสามารถใช้ Web Animations API เพื่อบรรลุเป้าหมายเดียวกันได้ ซึ่งทำได้โดยการสร้างอินสแตนซ์ Animation
และ KeyFrameEffect
ใหม่ หรือใช้เมธอด Element
animate()
ที่สั้นกว่านี้
document.querySelector('#progressbar').animate(
{
backgroundColor: ['red', 'darkred'],
transform: ['scaleX(0)', 'scaleX(1)'],
},
{
duration: 2500,
fill: 'forwards',
easing: 'linear',
}
);
ผลลัพธ์ที่เป็นภาพของข้อมูลโค้ด JavaScript ด้านบนนี้เหมือนกับ CSS เวอร์ชันก่อนหน้า
ไทม์ไลน์ของภาพเคลื่อนไหว
โดยค่าเริ่มต้น ภาพเคลื่อนไหวที่แนบกับองค์ประกอบจะทำงานในไทม์ไลน์ของเอกสาร เวลาต้นทางของหน้านั้นจะเริ่มต้นที่ 0 เมื่อโหลดหน้าเว็บ และเริ่มก้าวไปข้างหน้าเมื่อเวลาของนาฬิกาดำเนินไป นี่คือไทม์ไลน์ภาพเคลื่อนไหวเริ่มต้น และก่อนหน้านี้เป็นไทม์ไลน์ภาพเคลื่อนไหวเดียวที่คุณมีสิทธิ์เข้าถึง
ข้อกำหนดเกี่ยวกับภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อนกำหนดไทม์ไลน์ใหม่ 2 ประเภทที่คุณสามารถใช้ได้ ได้แก่
- ไทม์ไลน์ความคืบหน้าในการเลื่อน: ไทม์ไลน์ที่ลิงก์กับตำแหน่งการเลื่อนของคอนเทนเนอร์แบบเลื่อนตามแกนที่เฉพาะเจาะจง
- ดูไทม์ไลน์ความคืบหน้า: ไทม์ไลน์ที่ลิงก์กับตำแหน่งที่เกี่ยวข้องกับองค์ประกอบหนึ่งๆ ภายในคอนเทนเนอร์แบบเลื่อน
ไทม์ไลน์ความคืบหน้าของการเลื่อน
ไทม์ไลน์การเลื่อนคืบหน้าเป็นไทม์ไลน์ภาพเคลื่อนไหวที่ลิงก์กับความคืบหน้าในตำแหน่งการเลื่อนของคอนเทนเนอร์แบบเลื่อน หรือที่เรียกว่า scrollport หรือ scroller ร่วมกับแกนหนึ่งๆ โดยจะแปลงตำแหน่งในช่วงการเลื่อนเป็นเปอร์เซ็นต์ของความคืบหน้า
ตำแหน่งการเลื่อนเริ่มต้นแสดงความคืบหน้า 0% และตำแหน่งการเลื่อนสิ้นสุดจะแสดงความคืบหน้า 100% ในการแสดงภาพต่อไปนี้ คุณจะเห็นความคืบหน้านับจาก 0% ถึง 100% เมื่อคุณเลื่อนแถบเลื่อนจากบนลงล่าง
✨ ลองด้วยตัวเองเลย
ไทม์ไลน์การเลื่อนคืบหน้ามักจะย่อให้เหลือเพียง "ไทม์ไลน์การเลื่อน"
ดูไทม์ไลน์ความคืบหน้า
ไทม์ไลน์ประเภทนี้จะลิงก์กับความคืบหน้าที่เกี่ยวข้องขององค์ประกอบหนึ่งๆ ภายในคอนเทนเนอร์แบบเลื่อน ระบบจะติดตามออฟเซ็ตการเลื่อนของตัวเลื่อน เช่นเดียวกับไทม์ไลน์ความคืบหน้าของการเลื่อน ไทม์ไลน์ของการเลื่อนคือตำแหน่งที่เกี่ยวข้องกับวัตถุภายในแถบเลื่อนซึ่งเป็นตัวกำหนดความคืบหน้า ซึ่งต่างจากไทม์ไลน์ความคืบหน้าของการเลื่อน
วิธีนี้ค่อนข้างเทียบได้กับวิธีการทำงานของ IntersectionObserver
ซึ่งจะติดตามได้ว่าองค์ประกอบแสดงในแถบเลื่อนได้มากน้อยเพียงใด หากองค์ประกอบไม่ปรากฏในตัวเลื่อน แสดงว่าองค์ประกอบนั้นไม่ทับซ้อนกัน หากตัวเลื่อนมองเห็นตัวเลื่อนได้ แม้ส่วนที่เล็กที่สุดจะตัดกัน
ไทม์ไลน์ความคืบหน้าการดูจะเริ่มนับจากขณะที่วัตถุเริ่มตัดกับตัวเลื่อน และจะสิ้นสุดลงเมื่อวัตถุหยุดตัดตัวเลื่อน จากการแสดงภาพต่อไปนี้ คุณจะเห็นได้ว่าความคืบหน้าจะเริ่มนับตั้งแต่ 0% เมื่อวัตถุเข้าสู่คอนเทนเนอร์การเลื่อนและถึง 100% ในขณะที่วัตถุออกจากคอนเทนเนอร์แบบเลื่อนแล้ว
✨ ลองด้วยตัวเองเลย
ไทม์ไลน์ความคืบหน้าการดูมักจะย่อให้เหลือเพียง "ดูไทม์ไลน์" คุณสามารถกําหนดเป้าหมายเฉพาะส่วนหนึ่งๆ ของไทม์ไลน์ดูตามขนาดของหัวข้อ แต่จะเพิ่มหัวข้ออื่นๆ ในภายหลังได้
การนำไปใช้งานจริงด้วยไทม์ไลน์ความคืบหน้าของการเลื่อน
การสร้างไทม์ไลน์ความคืบหน้าของการเลื่อนแบบไม่ระบุชื่อใน CSS
วิธีที่ง่ายที่สุดในการสร้างไทม์ไลน์แบบเลื่อนใน CSS คือการใช้ฟังก์ชัน scroll()
การดำเนินการนี้จะสร้างไทม์ไลน์แบบเลื่อนที่ไม่ระบุตัวตนซึ่งคุณตั้งค่าเป็นค่าสำหรับพร็อพเพอร์ตี้ animation-timeline
ใหม่ได้
ตัวอย่าง
@keyframes animate-it { … }
.subject {
animation: animate-it linear;
animation-timeline: scroll(root block);
}
ฟังก์ชัน scroll()
ยอมรับอาร์กิวเมนต์ <scroller>
และอาร์กิวเมนต์ <axis>
ค่าที่ยอมรับสำหรับอาร์กิวเมนต์ <scroller>
คือ
nearest
: ใช้คอนเทนเนอร์การเลื่อนระดับบนที่ใกล้ที่สุด (ค่าเริ่มต้น)root
: ใช้วิวพอร์ตเอกสารเป็นคอนเทนเนอร์แบบเลื่อนself
: ใช้องค์ประกอบนั้นๆ เป็นที่เก็บแบบเลื่อน
ค่าที่ยอมรับสำหรับอาร์กิวเมนต์ <axis>
คือ
block
: ใช้การวัดความคืบหน้าตามแกนบล็อกของคอนเทนเนอร์แบบเลื่อน (ค่าเริ่มต้น)inline
: ใช้การวัดความคืบหน้าตามแกนในบรรทัดของคอนเทนเนอร์แบบเลื่อนy
: ใช้การวัดความคืบหน้าตามแกน y ของคอนเทนเนอร์แบบเลื่อนx
: ใช้การวัดความคืบหน้าตามแกน x ของคอนเทนเนอร์แบบเลื่อน
ตัวอย่างเช่น ในการเชื่อมโยงภาพเคลื่อนไหวกับตัวเลื่อนรูทบนแกนบล็อก ค่าที่ส่งผ่านไปยัง scroll()
คือ root
และ block
เมื่อนำมารวมกันแล้ว ค่าคือ scroll(root block)
การสาธิต: สัญญาณบอกสถานะความคืบหน้าในการอ่าน
การสาธิตนี้มีตัวบ่งชี้ความคืบหน้าในการอ่านซึ่งตรึงไว้ที่ด้านบนของวิวพอร์ต เมื่อคุณเลื่อนหน้าลง แถบความคืบหน้าจะขยายออกจนใช้ความกว้างเต็มของวิวพอร์ตเมื่อถึงจุดสิ้นสุดของเอกสาร ระบบจะใช้ไทม์ไลน์ความคืบหน้าของการเลื่อนแบบไม่ระบุชื่อในการขับเคลื่อนภาพเคลื่อนไหว
✨ ลองด้วยตัวเองเลย
ตัวบ่งชี้ความคืบหน้าในการอ่านจะอยู่ในตำแหน่งด้านบนของหน้าโดยใช้ตำแหน่งคงที่ หากต้องการใช้ประโยชน์จากภาพเคลื่อนไหวแบบผสม ไม่ใช่ width
กำลังเป็นภาพเคลื่อนไหว แต่องค์ประกอบลดขนาดลงบนแกน x โดยใช้ transform
<body>
<div id="progress"></div>
…
</body>
@keyframes grow-progress {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}
#progress {
position: fixed;
left: 0; top: 0;
width: 100%; height: 1em;
background: red;
transform-origin: 0 50%;
animation: grow-progress auto linear;
animation-timeline: scroll();
}
ไทม์ไลน์ของภาพเคลื่อนไหว grow-progress
ในองค์ประกอบ #progress
ได้รับการตั้งค่าเป็นไทม์ไลน์แบบไม่ระบุตัวบุคคลซึ่งสร้างขึ้นโดยใช้ scroll()
ไม่ได้ให้อาร์กิวเมนต์กับ scroll()
ไว้ ระบบจึงจะกลับไปใช้ค่าเริ่มต้น
แถบเลื่อนเริ่มต้นที่จะติดตามคือ nearest
และแกนเริ่มต้นคือ block
การดำเนินการนี้จะกำหนดเป้าหมายแถบเลื่อนรูทได้อย่างมีประสิทธิภาพ เนื่องจากเป็นตัวเลื่อนที่อยู่ใกล้ที่สุดขององค์ประกอบ #progress
ขณะที่ติดตามทิศทางการบล็อกของรายการนั้น
การสร้างไทม์ไลน์ความคืบหน้าของการเลื่อนที่มีชื่อใน CSS
อีกวิธีในการกำหนดไทม์ไลน์ความคืบหน้าของการเลื่อนคือการใช้ไทม์ไลน์ที่มีชื่อ วิธีนี้อาจมีรายละเอียดมากขึ้นเล็กน้อย แต่ก็มีประโยชน์เมื่อคุณไม่ได้กำหนดเป้าหมายไปยังแถบเลื่อนระดับบนสุดหรือรูทของแถบเลื่อน หรือเมื่อหน้าเว็บใช้ไทม์ไลน์หลายไทม์ไลน์หรือเมื่อการค้นหาอัตโนมัติไม่ทำงาน วิธีนี้จะทำให้ระบุไทม์ไลน์ความคืบหน้าของการเลื่อนได้จากชื่อที่คุณตั้งให้
หากต้องการสร้างไทม์ไลน์ความคืบหน้าของการเลื่อนที่มีชื่อในองค์ประกอบ ให้ตั้งค่าพร็อพเพอร์ตี้ CSS scroll-timeline-name
ในคอนเทนเนอร์แบบเลื่อนเป็นตัวระบุที่คุณชอบ ค่าต้องขึ้นต้นด้วย --
หากต้องการปรับแต่งแกนที่จะติดตาม ให้ประกาศพร็อพเพอร์ตี้ scroll-timeline-axis
ด้วย ค่าที่ใช้ได้จะเหมือนกับอาร์กิวเมนต์ <axis>
ของ scroll()
สุดท้าย หากต้องการลิงก์ภาพเคลื่อนไหวกับไทม์ไลน์ความคืบหน้าของการเลื่อน ให้ตั้งค่าพร็อพเพอร์ตี้ animation-timeline
ในองค์ประกอบที่ต้องทำให้เคลื่อนไหวเป็นค่าเดียวกับตัวระบุที่ใช้สำหรับ scroll-timeline-name
ตัวอย่างโค้ด
@keyframes animate-it { … }
.scroller {
scroll-timeline-name: --my-scroller;
scroll-timeline-axis: inline;
}
.scroller .subject {
animation: animate-it linear;
animation-timeline: --my-scroller;
}
หากต้องการ คุณสามารถรวม scroll-timeline-name
และ scroll-timeline-axis
ในชวเลข scroll-timeline
เช่น
scroll-timeline: --my-scroller inline;
การสาธิต: สัญญาณบอกสถานะขั้นตอนภาพสไลด์แนวนอน
การสาธิตนี้มีสัญญาณบอกขั้นตอนที่แสดงอยู่เหนือภาพสไลด์แต่ละภาพ เมื่อภาพหมุนมีรูปภาพ 3 รูป แถบตัวบ่งชี้จะเริ่มต้นที่ความกว้าง 33% เพื่อบ่งบอกว่าคุณกำลังดูรูปภาพหนึ่งใน 3 รูป เมื่อภาพสุดท้ายอยู่ในมุมมอง ซึ่งกำหนดโดยตัวเลื่อนที่เลื่อนไปจนสุด ตัวบ่งชี้จะใช้ความกว้างเต็มของแถบเลื่อน ระบบจะใช้ไทม์ไลน์ความคืบหน้าของการเลื่อนที่มีชื่อในการขับเคลื่อนภาพเคลื่อนไหว
✨ ลองด้วยตัวเองเลย
มาร์กอัปพื้นฐานสำหรับแกลเลอรีคือ
<div class="gallery" style="--num-images: 2;">
<div class="gallery__scrollcontainer">
<div class="gallery__progress"></div>
<div class="gallery__entry">…</div>
<div class="gallery__entry">…</div>
</div>
</div>
องค์ประกอบ .gallery__progress
อยู่ในตำแหน่งสัมบูรณ์ภายในองค์ประกอบ Wrapper .gallery
ขนาดเริ่มต้นของครีเอทีฟโฆษณาจะกำหนดโดยพร็อพเพอร์ตี้ที่กำหนดเองของ --num-images
.gallery {
position: relative;
}
.gallery__progress {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 1em;
transform: scaleX(calc(1 / var(--num-images)));
}
.gallery__scrollcontainer
จะจัดวางองค์ประกอบ .gallery__entry
ที่มีอยู่ในแนวนอนและเป็นองค์ประกอบที่เลื่อนได้ .gallery__progress
จะเคลื่อนไหวเมื่อติดตามตำแหน่งการเลื่อน ซึ่งสามารถทำได้โดยอ้างอิงไทม์ไลน์ความคืบหน้าของการเลื่อน --gallery__scrollcontainer
ที่ชื่อ
@keyframes grow-progress {
to { transform: scaleX(1); }
}
.gallery__scrollcontainer {
overflow-x: scroll;
scroll-timeline: --gallery__scrollcontainer inline;
}
.gallery__progress {
animation: auto grow-progress linear forwards;
animation-timeline: --gallery__scrollcontainer;
}
การสร้างไทม์ไลน์ความคืบหน้าของการเลื่อนด้วย JavaScript
หากต้องการสร้างไทม์ไลน์การเลื่อนใน JavaScript ให้สร้างอินสแตนซ์ใหม่ของคลาส ScrollTimeline
ส่งกระเป๋าสถานที่โดยมี source
และ axis
ที่คุณต้องการติดตาม
source
: การอ้างอิงถึงองค์ประกอบที่มีแถบเลื่อนที่คุณต้องการติดตาม ใช้document.documentElement
เพื่อกำหนดเป้าหมายแถบเลื่อนรากaxis
: กำหนดแกนที่จะติดตาม ค่าที่ยอมรับคือblock
,inline
,x
และy
เช่นเดียวกับตัวแปร CSS
const tl = new ScrollTimeline({
source: document.documentElement,
});
หากต้องการแนบกับ Web Animation ส่งเข้ามาเป็นพร็อพเพอร์ตี้ timeline
และไม่ต้องใส่ duration
(หากมี)
$el.animate({
opacity: [0, 1],
}, {
timeline: tl,
});
การสาธิต: สัญญาณบอกสถานะความคืบหน้าในการอ่าน กลับไปแล้ว
หากต้องการสร้างตัวบ่งชี้ความคืบหน้าในการอ่านใหม่ด้วย JavaScript ในขณะที่ใช้มาร์กอัปเดียวกัน ให้ใช้โค้ด JavaScript ต่อไปนี้:
const $progressbar = document.querySelector('#progress');
$progressbar.style.transformOrigin = '0% 50%';
$progressbar.animate(
{
transform: ['scaleX(0)', 'scaleX(1)'],
},
{
fill: 'forwards',
timeline: new ScrollTimeline({
source: document.documentElement,
}),
}
);
ผลการค้นหาภาพจะเหมือนกันในเวอร์ชัน CSS โดย timeline
ที่สร้างขึ้นจะติดตามแถบเลื่อนรูทและปรับขนาด #progress
ขึ้นบนแกน x จาก 0% เป็น 100% ขณะที่คุณเลื่อนหน้าเว็บ
✨ ลองด้วยตัวเองเลย
การนำไปใช้งานจริงด้วย "ดูไทม์ไลน์ความคืบหน้า"
การสร้างไทม์ไลน์ความคืบหน้าของการดูแบบไม่ระบุชื่อใน CSS
หากต้องการสร้างไทม์ไลน์ความคืบหน้า ให้ใช้ฟังก์ชัน view()
อาร์กิวเมนต์ที่ยอมรับคือ <axis>
และ <view-timeline-inset>
<axis>
จะเหมือนกับในไทม์ไลน์ความคืบหน้าของการเลื่อนและเป็นตัวกำหนดว่าจะติดตามแกนใด ค่าเริ่มต้นคือblock
- เมื่อใช้
<view-timeline-inset>
คุณจะระบุออฟเซ็ต (บวกหรือค่าลบ) เพื่อปรับขอบเขตเมื่อระบบพิจารณาว่าองค์ประกอบอยู่ในมุมมองหรือไม่ ค่าต้องเป็นเปอร์เซ็นต์หรือauto
โดยมีauto
เป็นค่าเริ่มต้น
เช่น หากต้องการเชื่อมโยงภาพเคลื่อนไหวกับองค์ประกอบที่ตัดกับตัวเลื่อนบนแกนบล็อก ให้ใช้ view(block)
คล้ายกับ scroll()
ให้ตั้งเป็นค่าสำหรับพร็อพเพอร์ตี้ animation-timeline
และอย่าลืมตั้งค่า animation-duration
เป็น auto
เมื่อใช้รหัสต่อไปนี้ img
ทุกรายการจะค่อยๆ จางลงเมื่อข้ามวิวพอร์ตในขณะที่คุณเลื่อน
@keyframes reveal {
from { opacity: 0; }
to { opacity: 1; }
}
img {
animation: reveal linear;
animation-timeline: view();
}
Intermezzo: ดูช่วงไทม์ไลน์
โดยค่าเริ่มต้น ภาพเคลื่อนไหวที่ลิงก์กับไทม์ไลน์การดูจะแนบไปกับช่วงไทม์ไลน์ทั้งหมด ซึ่งเริ่มต้นจากช่วงเวลาที่วัตถุจะเข้าสู่แถบเลื่อนและสิ้นสุดลงเมื่อวัตถุออกจากแถบเลื่อนไปทั้งหมด
คุณยังจะลิงก์ไทม์ไลน์กับส่วนที่เจาะจงของ "ดูไทม์ไลน์" ได้โดยระบุช่วงที่ควรแนบกับไทม์ไลน์ เช่น จะทำได้เฉพาะเมื่อวัตถุกำลังป้อนแถบเลื่อน ในการแสดงภาพต่อไปนี้ ความคืบหน้าจะเริ่มนับเพิ่มจาก 0% เมื่อวัตถุเข้าสู่คอนเทนเนอร์การเลื่อน แต่ถึง 100% แล้วนับจากช่วงที่วัตถุดังกล่าวเข้ามาตัดกันทั้งหมด
ช่วงการดูไทม์ไลน์ที่เป็นไปได้ซึ่งคุณกำหนดเป้าหมายได้มีดังนี้
cover
: แสดงไทม์ไลน์ความคืบหน้าการดูทั้งหมดentry
: แสดงช่วงที่ช่องหลักกำลังเข้าสู่ช่วงระดับการมองเห็นความคืบหน้าในการดูexit
: แสดงช่วงที่ช่องหลักออกจากช่วงระดับการมองเห็นความคืบหน้าของมุมมองentry-crossing
: แสดงช่วงที่ช่องหลักเกินขอบสิ้นสุดexit-crossing
: แสดงช่วงที่ช่องหลักพาดผ่านขอบเส้นขอบเริ่มต้นcontain
: แสดงช่วงที่ช่องหลักอยู่ภายในแถบเลื่อน ขึ้นอยู่กับว่าวัตถุนั้นสูงหรือสั้นกว่าตัวเลื่อน
หากต้องการกำหนดช่วง คุณต้องตั้งค่าจุดเริ่มต้นและจุดสิ้นสุดของช่วง แต่ละค่าประกอบด้วยชื่อช่วง (ดูรายการด้านบน) และออฟเซ็ตช่วงเพื่อกำหนดตำแหน่งภายในชื่อช่วงนั้น ปกติแล้วช่วงออฟเซ็ตจะเป็นเปอร์เซ็นต์ตั้งแต่ 0%
ถึง 100%
แต่คุณสามารถระบุความยาวคงที่ก็ได้ เช่น 20em
เช่น หากต้องการเรียกใช้ภาพเคลื่อนไหวจากช่วงเวลาที่ป้อนวัตถุ ให้เลือก entry 0%
เป็นช่วงเริ่มต้น หากต้องการให้อ่านจบตามเวลาที่ป้อนเรื่อง ให้เลือก entry 100%
เป็นค่าสำหรับช่วงสิ้นสุด
ใน CSS คุณจะตั้งค่านี้ได้โดยใช้พร็อพเพอร์ตี้ animation-range
ตัวอย่าง
animation-range: entry 0% entry 100%;
ใช้พร็อพเพอร์ตี้ rangeStart
และ rangeEnd
ใน JavaScript
$el.animate(
keyframes,
{
timeline: tl,
rangeStart: 'entry 0%',
rangeEnd: 'entry 100%',
}
);
ใช้เครื่องมือที่ฝังอยู่ด้านล่างเพื่อดูว่าชื่อช่วงแต่ละชื่อแสดงถึงอะไร และเปอร์เซ็นต์ส่งผลต่อตำแหน่งเริ่มต้นและสิ้นสุดอย่างไร ลองตั้งค่าจุดเริ่มต้นของช่วงเป็น entry 0%
และจุดสิ้นสุดของช่วงเป็น cover 50%
จากนั้นลากแถบเลื่อนเพื่อดูผลลัพธ์ภาพเคลื่อนไหว
ดูวิดีโอที่บันทึกไว้
คุณอาจสังเกตเห็นว่าเมื่อทดลองใช้เครื่องมือดูช่วงไทม์ไลน์นี้ บางช่วงสามารถกำหนดเป้าหมายโดยใช้ชื่อช่วงและช่วงออฟเซ็ตที่ต่างกัน 2 แบบ ตัวอย่างเช่น entry 0%
, entry-crossing 0%
และ cover 0%
ล้วนกำหนดเป้าหมายพื้นที่เดียวกัน
เมื่อจุดเริ่มต้นและจุดสิ้นสุดของช่วงกำหนดเป้าหมายโดยใช้ชื่อเดียวกันและครอบคลุมทั้งช่วงตั้งแต่ 0% ถึง 100% คุณสามารถย่อค่าให้สั้นลงเหลือเพียงแค่ชื่อช่วง ตัวอย่างเช่น สามารถเขียน animation-range: entry 0% entry 100%;
ใหม่เป็น animation-range: entry
ที่สั้นลงมากได้
การสาธิต: การเปิดเผยรูปภาพ
การสาธิตนี้จะค่อยๆ จางหายไปในรูปภาพเมื่อเข้าสู่แถบเลื่อน โดยใช้ไทม์ไลน์ของมุมมองที่ไม่ระบุชื่อ มีการปรับช่วงของภาพเคลื่อนไหวเพื่อให้แต่ละภาพมีความทึบแสงเต็มที่เมื่อเลื่อนอยู่ครึ่งทาง
✨ ลองด้วยตัวเองเลย
เอฟเฟกต์การขยายนั้นทำได้โดยใช้เส้นทางคลิปที่เป็นภาพเคลื่อนไหว CSS ที่ใช้สำหรับเอฟเฟกต์นี้คือ
@keyframes reveal {
from { opacity: 0; clip-path: inset(0% 60% 0% 50%); }
to { opacity: 1; clip-path: inset(0% 0% 0% 0%); }
}
.revealing-image {
animation: auto linear reveal both;
animation-timeline: view();
animation-range: entry 25% cover 50%;
}
การสร้างไทม์ไลน์ความคืบหน้าที่มีชื่อใน CSS
คุณยังสร้าง "ดูไทม์ไลน์" ที่มีชื่อได้เช่นเดียวกับชื่อ "ไทม์ไลน์ของการเลื่อน" แทนที่จะใช้พร็อพเพอร์ตี้ scroll-timeline-*
คุณจะใช้ตัวแปรที่มีคำนำหน้า view-timeline-
ซึ่งได้แก่ view-timeline-name
และ view-timeline-axis
จะมีการใช้ค่าประเภทเดียวกัน และจะใช้กฎเดียวกันในการค้นหาไทม์ไลน์ที่มีชื่อ
การสาธิต: เปิดเผยรูปภาพ กลับไปอีกครั้ง
การซ่อมแซมเดโมที่เปิดเผยรูปภาพจากก่อนหน้านี้ โค้ดที่แก้ไขแล้วจะมีลักษณะดังนี้
.revealing-image {
view-timeline-name: --revealing-image;
view-timeline-axis: block;
animation: auto linear reveal both;
animation-timeline: --revealing-image;
animation-range: entry 25% cover 50%;
}
เมื่อใช้ view-timeline-name: revealing-image
ระบบจะติดตามองค์ประกอบภายในแถบเลื่อนที่อยู่ใกล้ที่สุด จากนั้นระบบจะใช้ค่าเดียวกันนี้เป็นค่าของพร็อพเพอร์ตี้ animation-timeline
เอาต์พุตภาพจะไม่เหมือนกับก่อนหน้านี้
✨ ลองด้วยตัวเองเลย
การสร้างไทม์ไลน์ความคืบหน้าการดูใน JavaScript
หากต้องการสร้างไทม์ไลน์การดูใน JavaScript ให้สร้างอินสแตนซ์ใหม่ของคลาส ViewTimeline
ส่งกระเป๋าสถานที่โดยมีsubject
ที่คุณต้องการติดตาม, axis
และinset
subject
: การอ้างอิงไปยังองค์ประกอบที่คุณต้องการติดตามภายในแถบเลื่อนขององค์ประกอบนั้นaxis
: แกนที่จะติดตาม ค่าที่ยอมรับคือblock
,inline
,x
และy
เช่นเดียวกับตัวแปร CSSinset
: การปรับแถบเลื่อน (เชิงบวก) หรือการกำหนดค่าเริ่มต้น (เชิงลบ) เมื่อพิจารณาว่าช่องอยู่ในมุมมองหรือไม่
const tl = new ViewTimeline({
subject: document.getElementById('subject'),
});
หากต้องการแนบกับ Web Animation ส่งเข้ามาเป็นพร็อพเพอร์ตี้ timeline
และไม่ต้องใส่ duration
(หากมี) คุณสามารถเลือกที่จะส่งผ่านข้อมูลช่วงโดยใช้พร็อพเพอร์ตี้ rangeStart
และ rangeEnd
ก็ได้
$el.animate({
opacity: [0, 1],
}, {
timeline: tl,
rangeStart: 'entry 25%',
rangeEnd: 'cover 50%',
});
✨ ลองด้วยตัวเองเลย
สิ่งอื่นๆ ที่น่าลอง
การแนบกับช่วง "ดูไทม์ไลน์" หลายช่วงด้วยชุดคีย์เฟรมเดียว
มาดูการสาธิตข้อมูลรายชื่อติดต่อนี้ซึ่งข้อมูลในรายการจะเคลื่อนไหวกัน รายการจะเข้าสู่แถบเลื่อนจากด้านล่างและค่อยๆ ปรากฏขึ้น และเมื่อออกจากแถบเลื่อนที่ด้านบน สไลด์ก็จะค่อยๆ จางลง
✨ ลองด้วยตัวเองเลย
สำหรับการสาธิตนี้ องค์ประกอบแต่ละรายการจะตกแต่งด้วย "ดูไทม์ไลน์" 1 รายการ ซึ่งจะติดตามองค์ประกอบขณะที่ข้ามพอร์ตเลื่อน แต่ยังมีภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน 2 รายการแนบอยู่ ภาพเคลื่อนไหว animate-in
แนบอยู่กับช่วง entry
ของไทม์ไลน์ และภาพเคลื่อนไหว animate-out
กับช่วง exit
ของไทม์ไลน์
@keyframes animate-in {
0% { opacity: 0; transform: translateY(100%); }
100% { opacity: 1; transform: translateY(0); }
}
@keyframes animate-out {
0% { opacity: 1; transform: translateY(0); }
100% { opacity: 0; transform: translateY(-100%); }
}
#list-view li {
animation: animate-in linear forwards,
animate-out linear forwards;
animation-timeline: view();
animation-range: entry, exit;
}
แทนที่จะเรียกใช้ภาพเคลื่อนไหว 2 ภาพที่แนบมากับ 2 ช่วงที่ต่างกัน คุณยังสามารถสร้างชุดคีย์เฟรม 1 ชุดที่มีข้อมูลของช่วงอยู่แล้วได้อีกด้วย
@keyframes animate-in-and-out {
entry 0% {
opacity: 0; transform: translateY(100%);
}
entry 100% {
opacity: 1; transform: translateY(0);
}
exit 0% {
opacity: 1; transform: translateY(0);
}
exit 100% {
opacity: 0; transform: translateY(-100%);
}
}
#list-view li {
animation: linear animate-in-and-out;
animation-timeline: view();
}
เนื่องจากคีย์เฟรมมีข้อมูลช่วง คุณจึงไม่จำเป็นต้องระบุ animation-range
ผลลัพธ์ที่ได้ยังคงเหมือนเดิมทุกประการ
✨ ลองด้วยตัวเองเลย
การแนบกับไทม์ไลน์การเลื่อนที่ไม่ใช่ระดับบน
กลไกการค้นหาสำหรับไทม์ไลน์การเลื่อนที่มีชื่อและการดูไทม์ไลน์จะจำกัดเฉพาะการเลื่อนระดับบนเท่านั้น แต่บ่อยครั้งที่องค์ประกอบที่ต้องเคลื่อนไหวได้นั้นไม่ใช่องค์ประกอบย่อยของแถบเลื่อนที่ต้องติดตาม
คุณต้องนำพร็อพเพอร์ตี้ timeline-scope
มาใช้จึงจะดำเนินการนี้ได้ คุณสามารถใช้คุณสมบัตินี้เพื่อประกาศลำดับเวลาที่มีชื่อนั้นโดยไม่ต้องสร้างจริง ซึ่งจะทำให้ไทม์ไลน์ที่มีชื่อดังกล่าวมีขอบเขตที่กว้างขึ้น ในทางปฏิบัติ คุณจะใช้พร็อพเพอร์ตี้ timeline-scope
ในองค์ประกอบระดับบนสุดที่แชร์เพื่อให้ไทม์ไลน์ของแถบเลื่อนย่อยแนบไปกับไทม์ไลน์ได้
เช่น
.parent {
timeline-scope: --tl;
}
.parent .scroller {
scroll-timeline: --tl;
}
.parent .scroller ~ .subject {
animation: animate linear;
animation-timeline: --tl;
}
ในข้อมูลโค้ดนี้
- องค์ประกอบ
.parent
ประกาศไทม์ไลน์ชื่อว่า--tl
ระดับย่อยของพร็อพเพอร์ตี้จะค้นหาและใช้เป็นค่าสำหรับพร็อพเพอร์ตี้animation-timeline
ได้ - องค์ประกอบ
.scroller
กำหนดไทม์ไลน์การเลื่อนโดยใช้ชื่อ--tl
โดยค่าเริ่มต้น รายการนี้จะปรากฏแก่ผู้เผยแพร่โฆษณาย่อยเท่านั้น แต่เนื่องจาก.parent
ได้ตั้งค่าเป็นscroll-timeline-root
จึงเชื่อมโยงด้วย - องค์ประกอบ
.subject
ใช้ไทม์ไลน์--tl
มันเดินขึ้นต้นบรรพบุรุษและพบ--tl
บน.parent
เนื่องจาก--tl
บน.parent
ชี้ไปยัง--tl
ของ.scroller
.subject
จะติดตามไทม์ไลน์ความคืบหน้าในการเลื่อนของ.scroller
กล่าวอีกนัยหนึ่งคือ คุณสามารถใช้ timeline-root
เพื่อเลื่อนไทม์ไลน์ขึ้นไปยังระดับบน (หรือการยกเครื่องใหม่) เพื่อให้องค์ประกอบย่อยทั้งหมดของระดับบนเข้าถึงได้
คุณสามารถใช้พร็อพเพอร์ตี้ timeline-scope
กับทั้งไทม์ไลน์แบบเลื่อนและดูไทม์ไลน์
การสาธิตและแหล่งข้อมูลเพิ่มเติม
การสาธิตทั้งหมดที่พูดถึงในบทความนี้ที่ the Scroll-animations.style mini-site เว็บไซต์ดังกล่าวมีการสาธิตอีกมากมายเพื่อเน้นสิ่งที่เป็นไปได้ด้วยภาพเคลื่อนไหวที่ขับเคลื่อนด้วยการเลื่อน
การสาธิตเพิ่มเติมอีกอย่างหนึ่งคือรายการปกอัลบั้มนี้ หน้าปกแต่ละฉบับจะหมุนเป็น 3 มิติเมื่อถ่ายจุดกึ่งกลาง
✨ ลองด้วยตัวเองเลย
หรือการสาธิตการ์ดแบบเรียงซ้อนนี้ซึ่งใช้ประโยชน์จาก position: sticky
เมื่อการ์ดซ้อนกันอยู่ การ์ดที่ค้างอยู่แล้วจะลดขนาดลง สร้างเอฟเฟกต์ความลึกที่ดี ในตอนท้าย ทั้งกลุ่มจะเลื่อนออกจากมุมมองเป็นกลุ่ม
✨ ลองด้วยตัวเองเลย
นอกจากนี้ ยังปรากฏอยู่ใน scroll-scroll-enabled-animations.style คือชุดเครื่องมือ เช่น การแสดงภาพความคืบหน้าของช่วง Viewไทม์ไลน์ที่มีรวมอยู่ก่อนหน้านี้ในโพสต์นี้
นอกจากนี้ ภาพเคลื่อนไหวที่เลื่อนดูได้ยังพูดถึงในส่วนมีอะไรใหม่ในภาพเคลื่อนไหวบนเว็บที่งาน Google I/O ’23 ด้วย