Motion ในการใช้งานจริง: Layout animations และรูปแบบที่รองรับ Accessibility
Framer-motion ได้เปลี่ยนไปแล้ว ตั้งแต่ช่วงปลายปี 2024 แพ็กเกจนี้ถูกเปลี่ยนชื่อเป็น Motion คุณต้องใช้ path การ import เป็น motion/react
บทช่วยสอนส่วนใหญ่นั้นล้าสมัยไปแล้ว เพราะยังคงแสดงการ import แบบเก่าและขาดเรื่อง Accessibility คู่มือนี้จะช่วยให้คุณใช้งาน Motion เวอร์ชันปัจจุบันในโปรเจกต์จริงได้อย่างถูกต้อง
การอัปเกรด
การเปลี่ยนผ่านนั้นง่ายมาก หากคุณใช้เวอร์ชัน 11 การเปลี่ยนเป็นเวอร์ชัน 12 ก็เป็นเพียงแค่การค้นหาและแทนที่ (find-and-replace) เท่านั้น
- ถอนการติดตั้ง:
npm uninstall framer-motion - ติดตั้ง:
npm install motion - อัปเดตการ import: เปลี่ยนจาก 'framer-motion' เป็น 'motion/react'
คุณสามารถรันทั้งสองแพ็กเกจควบคู่กันไปได้ในช่วงการย้าย (migration) แต่อย่าปล่อยให้พวกมันอยู่ใน codebase ของคุณตลอดไป
Layout Animations
prop layout จะบอกให้ Motion คอยเฝ้าดูขนาดและตำแหน่งของ element แทนที่จะปล่อยให้เบราว์เซอร์เปลี่ยนตำแหน่งแบบทันทีทันใด (snap) มันจะทำการสร้าง animation ให้กับการเปลี่ยนแปลงเหล่านั้นแทน
ใช้ layout="position" สำหรับรายการ (lists) วิธีนี้จะช่วยเคลื่อนย้าย element ข้างเคียง (siblings) เมื่อมีไอเทมหนึ่งขยายขนาดขึ้น แต่จะไม่ทำให้เนื้อหาภายในถูกบีบอัด
ใช้ AnimatePresence สำหรับการ mount และ unmount หากไม่มีสิ่งนี้ React จะลบ element ออกจาก DOM ก่อนที่มันจะสามารถทำ animation ขาออก (animate out) ได้
หลีกเลี่ยงการทำ animation กับ height: auto เพราะจะทำให้เกิดอาการภาพกระตุก (visual glitches) แต่ควรใช้ CSS grid wrapper (จาก 0fr เป็น 1fr) เพื่อให้การเปลี่ยนความสูงเป็นไปอย่างราบรื่นแทน
Accessibility
ผู้ใช้ iOS ประมาณ 30% เปิดใช้งาน prefers-reduced-motion อย่าเพียงแค่ปิด animation ทั้งหมด เพราะจะทำให้ layout ของคุณพัง
วิธีที่ผิด: เปลี่ยน <motion.div> เป็น <div> ธรรมดาหากผู้ใช้ต้องการลดการเคลื่อนไหว วิธีนี้จะทำให้ layout เกิดการกระตุก (snap) และดูเหมือนระบบทำงานผิดพลาด
วิธีที่ถูกต้อง: ควบคุมที่ตัว transition ไม่ใช่ที่ตัว component ให้คง <motion.div> ไว้ แต่ตั้งค่า duration เป็น 0 แทน
สร้าง custom hook เพื่อจัดการเรื่องนี้:
- ใช้ hook
useReducedMotion - หากเป็น true ให้คืนค่า duration เป็น 0
- หากเป็น false ให้คืนค่าการตั้งค่า spring มาตรฐานของคุณ
วิธีนี้จะช่วยให้มั่นใจว่า element ต่างๆ จะเคลื่อนที่ไปยังตำแหน่งที่ถูกต้องได้โดยไม่มีการเคลื่อนไหวที่รบกวนสายตา
เมื่อไหร่ควรใช้ Motion
ใช้ Web Animations API ของเบราว์เซอร์สำหรับการทำ fade แบบง่ายๆ เพราะไม่มี dependency ใดๆ
ใช้ Motion เมื่อคุณต้องการ:
- React-native APIs ที่เข้าใจ component lifecycles
- Layout animations ที่ติดตามการเปลี่ยนแปลงของ DOM
- AnimatePresence สำหรับ exit animations
- ระบบฟิสิกส์แบบ Spring ที่ให้ความรู้สึกเป็นธรรมชาติ