เจาะลึก CSS - matrix3d() สำหรับแถบเลื่อนที่กำหนดเองแบบเฟรมที่สมบูรณ์แบบ

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

TL;DR

คุณไม่สนใจเรื่องเล็กๆ น้อยๆ ใช่ไหม คุณแค่ต้องการดูตัวอย่างเพลงของ Nyan Cat และรับคลังเพลงใช่ไหม คุณดูโค้ดของเดโมได้ในที่เก็บ GitHub

LAM;WRA (ยาวและเกี่ยวกับคณิตศาสตร์ แต่จะอ่านอยู่ดี)

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

สรุป

มาเริ่มกันด้วยการทบทวนวิธีการทำงานของภาพสไลด์แบบพารัลแลกซ์

ดังที่แสดงในภาพเคลื่อนไหว เราสร้างเอฟเฟกต์ภาพพารัลแลกซ์โดยการผลักองค์ประกอบ "ถอยหลัง" ในอวกาศ 3 มิติตามแนวแกน Z การเลื่อนเอกสารเป็นการเลื่อนตามแนวแกน Y ดังนั้นหากเราเลื่อนลง 100 พิกเซล องค์ประกอบทั้งหมดจะเลื่อนขึ้น 100 พิกเซล ซึ่งมีผลกับองค์ประกอบทั้งหมด แม้แต่องค์ประกอบที่อยู่ "ด้านหลัง" ก็ตาม แต่เนื่องจากองค์ประกอบเหล่านี้อยู่ห่างจากกล้องมากกว่า การเคลื่อนไหวที่สังเกตได้บนหน้าจอจะน้อยกว่า 100 พิกเซล จึงทำให้เกิดเอฟเฟกต์ภาพพารัลแลกซ์ตามที่ต้องการ

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

ขั้นตอนที่ 0: เราต้องการทําอะไร

แถบเลื่อน นั่นคือสิ่งที่เราจะสร้าง แต่คุณเคยคิดไหมว่าพวกเขาทำอะไร เราไม่ได้ทำเช่นนั้น แถบเลื่อนเป็นตัวบ่งชี้ปริมาณเนื้อหาที่มีอยู่ซึ่งแสดงอยู่ในขณะนี้ และความคืบหน้าที่คุณในฐานะผู้อ่านอ่านไปแล้ว เมื่อคุณเลื่อนลง แถบเลื่อนก็จะเลื่อนลงด้วยเพื่อบ่งบอกว่าคุณกำลังดำเนินการใกล้จะเสร็จสิ้น หากเนื้อหาทั้งหมดพอดีกับวิวพอร์ต ระบบมักจะซ่อนแถบเลื่อนไว้ หากเนื้อหามีความสูง 2 เท่าของวิวพอร์ต แถบเลื่อนจะกินพื้นที่ ½ ของความสูงของวิวพอร์ต เนื้อหาที่สูง 3 เท่าของวิวพอร์ตจะปรับแถบเลื่อนให้มีขนาด 1/3 ของวิวพอร์ต เป็นต้น คุณจะเห็นรูปแบบนี้ คุณยังคลิกและลากแถบเลื่อนเพื่อไปยังส่วนต่างๆ ของเว็บไซต์ได้เร็วขึ้นแทนการเลื่อน นี่เป็นลักษณะการทำงานที่น่าประหลาดใจสำหรับองค์ประกอบที่มองไม่เห็นเช่นนี้ มาสู้กันทีละปัญหา

ขั้นตอนที่ 1: เปลี่ยนเป็นโหมดถอยหลัง

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

หากต้องการใช้การฉายภาพเชิงมุมในเชิงคณิตศาสตร์ คุณอาจต้องใช้พิกัดแบบสม่ำเสมอ เราจะไม่ลงรายละเอียดว่า 3D Coord นั้นคืออะไรและทํางานอย่างไร แต่คุณอาจจํากัดความ 3D Coord ว่าเป็นพิกัด 3 มิติที่มีพิกัดที่ 4 เพิ่มเติมที่เรียกว่า w พิกัดนี้ควรเป็น 1 เว้นแต่ว่าคุณต้องการให้ภาพบิดเบี้ยวตามมุมมอง เราไม่จำเป็นต้องกังวลเกี่ยวกับรายละเอียดของ w เนื่องจากเราจะไม่ใช้ค่าอื่นนอกเหนือจาก 1 ดังนั้นนับจากนี้ไปจุดทั้งหมดจะเป็นเวกเตอร์ 4 มิติ [x, y, z, w=1] และเมทริกซ์จึงต้องเป็น 4x4 ด้วย

กรณีที่คุณจะเห็นว่า CSS ใช้พิกัดแบบสม่ำเสมออยู่เบื้องหลังคือเมื่อคุณกำหนดเมทริกซ์ 4x4 ของคุณเองในพร็อพเพอร์ตี้ transform โดยใช้ฟังก์ชัน matrix3d() matrix3d ใช้อาร์กิวเมนต์ 16 รายการ (เนื่องจากเมทริกซ์มีขนาด 4x4) โดยระบุคอลัมน์ทีละคอลัมน์ เราจึงใช้ฟังก์ชันนี้เพื่อระบุการหมุน การแปล ฯลฯ ด้วยตนเองได้ แต่นอกจากนี้ เรายังใช้ฟังก์ชันนี้เพื่อเล่นกับพิกัด w ได้ด้วย

เราต้องสร้างบริบท 3 มิติก่อนจึงจะใช้ matrix3d() ได้ เนื่องจากหากไม่มีบริบท 3 มิติ จะไม่มีภาพบิดเบี้ยวตามมุมมองและไม่จำเป็นต้องใช้พิกัดแบบสม่ำเสมอ หากต้องการสร้างบริบท 3 มิติ เราต้องใช้คอนเทนเนอร์ที่มี perspective และองค์ประกอบบางอย่างภายในที่เราเปลี่ยนรูปแบบได้ในอวกาศ 3 มิติที่สร้างขึ้นใหม่ ตัวอย่างเช่น

โค้ด CSS บางส่วนที่บิดเบือน div โดยใช้แอตทริบิวต์ perspective ของ CSS

องค์ประกอบภายในคอนเทนเนอร์ภาพ 3 มิติจะได้รับการประมวลผลโดยเครื่องมือ CSS ดังนี้

  • เปลี่ยนแต่ละมุม (จุดยอด) ขององค์ประกอบเป็นพิกัดแบบสม่ำเสมอ [x,y,z,w] โดยสัมพันธ์กับคอนเทนเนอร์ภาพมุมมอง
  • ใช้การเปลี่ยนรูปแบบทั้งหมดขององค์ประกอบเป็นเมทริกซ์จากขวาไปซ้าย
  • หากเอลิเมนต์ภาพ 3 มิติเลื่อนได้ ให้ใช้เมทริกซ์การเลื่อน
  • ใช้เมทริกซ์มุมมอง

เมทริกซ์การเลื่อนคือการเปลี่ยนตำแหน่งตามแกน Y หากเราเลื่อนลง 400 พิกเซล องค์ประกอบทั้งหมดจะต้องเลื่อนขึ้น 400 พิกเซล เมทริกซ์มุมมองคือเมทริกซ์ที่ "ดึง" จุดให้ใกล้กับจุดที่เลือนหายไปมากขึ้นเมื่อจุดนั้นอยู่ด้านหลังในพื้นที่ 3 มิติ วิธีนี้ทำให้เกิดทั้ง 2 ผลลัพธ์ คือทำให้วัตถุดูเล็กลงเมื่ออยู่ไกลออกไป และทำให้วัตถุ "เคลื่อนไหวช้าลง" เมื่อมีการแปล ดังนั้นหากมีการผลักองค์ประกอบกลับ การเปลี่ยนตำแหน่ง 400 พิกเซลจะทำให้องค์ประกอบขยับเพียง 300 พิกเซลบนหน้าจอ

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

กล่องของเราอยู่ภายในคอนเทนเนอร์ภาพมุมมองที่มีค่า p สําหรับแอตทริบิวต์ perspective และสมมติว่าคอนเทนเนอร์เลื่อนได้และเลื่อนลง 200 พิกเซล

เมตริกซ์มุมมองคูณด้วยเมตริกส์เลื่อนคูณด้วยเมตริกการเปลี่ยนรูปแบบองค์ประกอบ equal 4x4 identity matrix with minus one over p in the fourth row 3rd column times 4x4 identity matrix with minus n in the second row 4th column times element transform matrix

เมทริกซ์แรกคือเมทริกซ์มุมมอง ส่วนเมทริกซ์ที่ 2 คือเมทริกซ์การเลื่อน โดยสรุปแล้ว หน้าที่ของเมทริกซ์การเลื่อนคือทําให้องค์ประกอบเลื่อนขึ้นเมื่อเราเลื่อนลง ด้วยเหตุนี้จึงมีเครื่องหมายลบ

แต่สำหรับแถบเลื่อน เราต้องการผลลัพธ์ที่ตรงกันข้าม คือต้องการให้องค์ประกอบเลื่อนลงเมื่อเราเลื่อนลง ตรงนี้เราสามารถใช้เทคนิคในการพลิกพิกัด w ของมุมกล่อง หากพิกัด w มีค่าเป็น -1 การแปลทั้งหมดจะมีผลในทิศทางตรงกันข้าม เราจะทำอย่างไร เครื่องมือ CSS จะจัดการแปลงมุมของกล่องเป็นพิกัดแบบสม่ำเสมอ และตั้งค่า w เป็น 1 ได้เวลาให้ matrix3d() เฉิดฉายแล้ว

.box {
  transform:
    matrix3d(
      1, 0, 0, 0,
      0, 1, 0, 0,
      0, 0, 1, 0,
      0, 0, 0, -1
    );
}

เมทริกซ์นี้จะทําเพียงลบล้าง w ดังนั้นเมื่อเครื่องมือ CSS ได้เปลี่ยนแต่ละมุมเป็นเวกเตอร์ของรูปแบบ [x,y,z,1] แล้ว เมทริกซ์จะเปลี่ยนเป็น [x,y,z,-1]

เมทริกซ์เอกลักษณ์ 4x4 ที่มีลบ 1 หารด้วย p ในแถวที่ 4 คอลัมน์ที่ 3 คูณด้วยเมทริกซ์เอกลักษณ์ 4x4 ที่มีลบ n ในแถวที่ 2 คอลัมน์ที่ 4 คูณด้วยเมทริกซ์เอกลักษณ์ 4x4 ที่มีลบ 1 ในแถวที่ 4 คอลัมน์ที่ 4 คูณด้วยเวกเตอร์ 4 มิติ x, y, z, 1 เท่ากับเมทริกซ์เอกลักษณ์ 4x4 ที่มีลบ 1 หารด้วย p ในแถวที่ 4 คอลัมน์ที่ 3, ลบ n ในแถวที่ 2 คอลัมน์ที่ 4 และลบ 1 ในแถวที่ 4 คอลัมน์ที่ 4 เท่ากับเวกเตอร์ 4 มิติ x, y บวก n, z, ลบ z หารด้วย p ลบ 1

เราได้แสดงขั้นตอนกลางเพื่อแสดงผลขององค์ประกอบ transform matrix หากไม่ถนัดเรื่องคณิตศาสตร์เชิงเมทริกซ์ ก็ไม่เป็นไร แนวคิดสำคัญคือในบรรทัดสุดท้าย เราเพิ่มการเลื่อน n ลงในพิกัด y แทนที่จะลบ องค์ประกอบจะเลื่อนลงหากเราเลื่อนลง

อย่างไรก็ตาม หากเราใส่เมทริกซ์นี้ในตัวอย่าง องค์ประกอบจะไม่แสดง เนื่องจากข้อกำหนด CSS กําหนดว่าจุดยอดใดก็ตามที่มี w < 0 จะบล็อกไม่ให้องค์ประกอบแสดงผล และเนื่องจากตอนนี้พิกัด z ของเราคือ 0 และ p คือ 1 w จึงเท่ากับ -1

แต่โชคดีที่เราสามารถเลือกค่าของ z ได้ เราต้องตั้งค่า z = -2 เพื่อให้ w = 1

.box {
  transform:
    matrix3d(
      1, 0, 0, 0,
      0, 1, 0, 0,
      0, 0, 1, 0,
      0, 0, 0, -1
    )
    translateZ(-2px);
}

ในที่สุดแล้ว กล่องของเราก็กลับมาแล้ว

ขั้นตอนที่ 2: ทําให้ชิ้นงานเคลื่อนไหว

ตอนนี้กล่องของเราก็ปรากฏขึ้นแล้วและมีลักษณะเหมือนเดิมหากไม่มีการเปลี่ยนรูปแบบ ขณะนี้คอนเทนเนอร์ภาพ 3 มิติจะเลื่อนไม่ได้ เราจึงไม่เห็น แต่เราทราบว่าองค์ประกอบจะไปในอีกทิศทางหนึ่งเมื่อเลื่อน มาทำให้คอนเทนเนอร์เลื่อนกัน เราเพียงเพิ่มองค์ประกอบตัวเว้นวรรคที่กินพื้นที่

<div class="container">
    <div class="box"></div>
    <span class="spacer"></span>
</div>

<style>
/* … all the styles from the previous example … */
.container {
    overflow: scroll;
}
.spacer {
    display: block;
    height: 500px;
}
</style>

และตอนนี้ก็เลื่อนกล่อง กล่องสีแดงจะเลื่อนลง

ขั้นตอนที่ 3: กำหนดขนาด

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

โดยปกติแล้วแถบเลื่อนจะประกอบด้วย "แถบเลื่อน" และ "ร่อง" แต่ร่องอาจไม่แสดงเสมอไป ความสูงของภาพปกจะแปรผันโดยตรงกับปริมาณเนื้อหาที่มองเห็นได้

<script>
    const scroller = document.querySelector('.container');
    const thumb = document.querySelector('.box');
    const scrollerHeight = scroller.getBoundingClientRect().height;
    thumb.style.height = /* ??? */;
</script>

scrollerHeight คือความสูงขององค์ประกอบที่เลื่อนได้ ส่วน scroller.scrollHeight คือความสูงทั้งหมดของเนื้อหาที่เลื่อนได้ scrollerHeight/scroller.scrollHeight คือเศษส่วนของเนื้อหาที่มองเห็นได้ สัดส่วนพื้นที่แนวตั้งที่ภาพปกครอบคลุมควรเท่ากับสัดส่วนเนื้อหาที่มองเห็นได้ ดังนี้

ความสูงของจุดในสไตล์จุดของแถบเลื่อนหารด้วยความสูงของแถบเลื่อนเท่ากับความสูงของแถบเลื่อนหารด้วยความสูงของการเลื่อนจุดของแถบเลื่อนก็ต่อเมื่อความสูงของจุดในสไตล์จุดของแถบเลื่อนเท่ากับความสูงของแถบเลื่อนคูณด้วยความสูงของแถบเลื่อนหารด้วยความสูงของการเลื่อนจุดของแถบเลื่อน
<script>
    // …
    thumb.style.height =
    scrollerHeight * scrollerHeight / scroller.scrollHeight + 'px';
    // Accommodate for native scrollbars
    thumb.style.right =
    (scroller.clientWidth - scroller.getBoundingClientRect().width) + 'px';
</script>

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

ข้อมูลสำคัญคือเราต้องการให้ขอบด้านล่างของปุ่มโฮมตรงกับขอบด้านล่างขององค์ประกอบที่เลื่อนได้เมื่อเลื่อนลงจนสุด กล่าวคือ หากเลื่อนไป scroller.scrollHeight - scroller.height พิกเซล เราต้องการให้นิ้วหัวแม่มือเลื่อนไป scroller.height - thumb.height สําหรับพิกเซลของแถบเลื่อนแต่ละพิกเซล เราต้องการให้นิ้วหัวแม่มือเลื่อนไปเพียงเศษเสี้ยวของพิกเซล ดังนี้

ปัจจัยเท่ากับความสูงของจุดเลื่อนลบด้วยความสูงของจุดแตะหารด้วยความสูงของการเลื่อนจุดลบด้วยความสูงของจุดเลื่อน

นั่นคือตัวคูณมาตราส่วนของเรา ตอนนี้เราต้องแปลงปัจจัยการขยายเป็นการเปลี่ยนตำแหน่งตามแนวแกน z ซึ่งเราได้ทําไปแล้วในบทความการเลื่อนแบบพารัลแลกซ์ ตามส่วนที่เกี่ยวข้องในข้อกำหนด ค่าตัวคูณมาตราส่วนเท่ากับ p/(p − z) เราแก้สมการนี้หา z ได้เพื่อหาว่าต้องเลื่อนนิ้วหัวแม่มือตามแกน z เท่าใด แต่โปรดทราบว่าเนื่องจากความซับซ้อนของพิกัด w เราจึงต้องแปล -2px เพิ่มเติมตาม z นอกจากนี้ โปรดทราบว่าระบบจะใช้การเปลี่ยนรูปแบบขององค์ประกอบจากขวาไปซ้าย ซึ่งหมายความว่าการแปลทั้งหมดก่อนเมตริกพิเศษจะไม่กลับหัว แต่การแปลทั้งหมดหลังเมตริกพิเศษจะกลับหัว มาเขียนโค้ดกัน

<script>
    // ... code from above...
    const factor =
    (scrollerHeight - thumbHeight)/(scroller.scrollHeight - scrollerHeight);
    thumb.style.transform = `
    matrix3d(
        1, 0, 0, 0,
        0, 1, 0, 0,
        0, 0, 1, 0,
        0, 0, 0, -1
    )
    scale(${1/factor})
    translateZ(${1 - 1/factor}px)
    translateZ(-2px)
    `;
</script>

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

แล้ว iOS ล่ะ

เพื่อนเก่าอย่าง iOS Safari เราพบปัญหาเช่นเดียวกับการเลื่อนแบบพารัลแลกซ์ เนื่องจากเรากำลังเลื่อนองค์ประกอบ จึงต้องระบุ -webkit-overflow-scrolling: touch แต่การระบุดังกล่าวจะทำให้ภาพ 3 มิติแบนราบและเอฟเฟกต์การเลื่อนทั้งหมดหยุดทำงาน เราได้แก้ปัญหานี้ในแถบเลื่อนภาพพารัลแลกซ์โดยการตรวจหา iOS Safari และใช้ position: sticky เป็นวิธีแก้ปัญหาชั่วคราว และเราจะทำแบบเดียวกันกับที่นี่ โปรดอ่านบทความเกี่ยวกับภาพพารัลแลกซ์เพื่อทบทวนความจำ

แล้วแถบเลื่อนของเบราว์เซอร์ล่ะ

ในบางระบบ เราจะต้องจัดการกับแถบเลื่อนแบบเนทีฟถาวร ที่ผ่านมา แถบเลื่อนจะซ่อนไม่ได้ (ยกเว้นตัวเลือกเสมือนที่ไม่เป็นมาตรฐาน) ดังนั้นในการซ่อนข้อมูลดังกล่าว เราจึงต้องใช้วิธีแฮ็ก (ไม่ต้องใช้คณิตศาสตร์) เราตัดสิ้นสุดองค์ประกอบที่เลื่อนในคอนเทนเนอร์ด้วย overflow-x: hidden และทำให้องค์ประกอบที่เลื่อนกว้างกว่าคอนเทนเนอร์ ตอนนี้แถบเลื่อนของเบราว์เซอร์จะมองไม่เห็นแล้ว

Fin

เมื่อนำทุกอย่างมารวมกัน ตอนนี้เราสามารถสร้างแถบเลื่อนที่ปรับแต่งเองซึ่งเฟรมจะพอดีกันทุกเฟรมได้ เช่น แถบเลื่อนในเดโมของ Nyan Cat

หากไม่เห็น Nyan Cat แสดงว่าคุณพบข้อบกพร่องที่เราพบและรายงานแล้วขณะสร้างเดโมนี้ (คลิกนิ้วโป้งเพื่อทำให้ Nyan Cat ปรากฏขึ้น) Chrome เก่งมากในการหลีกเลี่ยงการทำงานที่ไม่จำเป็น เช่น การวาดภาพหรือการสร้างภาพเคลื่อนไหวของสิ่งที่อยู่นอกหน้าจอ ข่าวร้ายคือการแสดงผลแบบ Matrix ของเราทําให้ Chrome คิดว่า GIF ของ Nyan Cat อยู่นอกหน้าจอ หวังว่าปัญหานี้จะได้รับการแก้ไขเร็วๆ นี้

เท่านี้ก็เรียบร้อย งานนี้ยากมาก เราชื่นชมที่คุณอ่านทุกอย่าง นี่เป็นวิธีที่ค่อนข้างซับซ้อนในการทำให้ใช้งานได้ และอาจไม่ค่อยคุ้มค่ากับเวลาและความพยายาม ยกเว้นในกรณีที่แถบเลื่อนที่ปรับแต่งเองเป็นส่วนสำคัญของประสบการณ์การใช้งาน แต่คุณก็ควรทราบว่าการดำเนินการดังกล่าวเป็นไปได้ การที่การทําแถบเลื่อนที่กําหนดเองนั้นทําได้ยากมากแสดงให้เห็นว่ายังมีงานที่ต้องทําในฝั่ง CSS แต่ไม่ต้องกังวล ในอนาคต AnimationWorklet ของ Houdini จะช่วยให้คุณสร้างเอฟเฟกต์ที่เชื่อมโยงกับการเลื่อนแบบเฟรมต่อเฟรมได้อย่างง่ายดาย