การค่อยๆ เปลี่ยนตามหลักฟิสิกส์

ฟีเจอร์เว็บ: linear() easing

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

ขั้นตอนการติดตั้งใช้งาน

  1. สร้างจุดหยุดของเส้นโค้ง: การพล็อตจุดหลายสิบจุดด้วยตนเองสำหรับการเด้งหรือกระดอนนั้นทำได้ยาก ใช้ฟังก์ชันการกำหนดเวลาจากไลบรารีภายนอก หรือใช้เครื่องมือเพื่อแปลงฟังก์ชันการค่อยๆ เปลี่ยนของ JavaScript ที่มีอยู่หรือเส้นทาง SVG เป็นไวยากรณ์ linear() ไม่บังคับ: จัดเก็บฟังก์ชันการกำหนดเวลาเหล่านี้เป็นคุณสมบัติที่กำหนดเองของ CSS เพื่อนำมาใช้ซ้ำทั่วทั้งเว็บไซต์
  2. กำหนดฟังก์ชันการกำหนดเวลา: ใช้จุดพักที่สร้างขึ้นกับพร็อพเพอร์ตี้ transition-timing-function หรือ animation-timing-function หรือผ่านทางลัด transition หรือ animation
  3. ปรับระยะเวลา: CSS ยังคงต้องใช้ duration แบบคงที่ ซึ่งต่างจากระบบฟิสิกส์ของ JavaScript ที่ระยะเวลาได้มาจากคุณสมบัติทางกายภาพ (มวล ความแข็ง) คุณอาจต้องปรับระยะเวลาเพื่อให้ได้เอฟเฟกต์ที่ต้องการ

ตัวอย่าง: Spring Easing

ตัวอย่างนี้แสดงวิธีใช้ฟังก์ชัน linear() ที่กำหนดเองเพื่อสร้างเอฟเฟกต์สปริงที่พุ่งเกินค่าเป้าหมายก่อนที่จะหยุดนิ่ง

.spring {
  /* Define the physics-based easing as a reusable variable */
  --spring-easing: linear(0, 0.016 0.5%, 0.06 1%, 0.226 2%, 1.116 5.4%, 1.375 6.6%, 1.527 7.7%, 1.565 8.2%, 1.585 8.8%, 1.581 9.3%, 1.559 9.8%, 1.458 10.9%, 0.937 14.3%, 0.784 15.5%, 0.693 16.6%, 0.67 17.1%, 0.657 17.7%, 0.671 18.7%, 0.729 19.8%, 1.042 23.3%, 1.13 24.5%, 1.182 25.6%, 1.201 26.7%, 1.192 27.7%, 1.156 28.8%, 0.977 32.2%, 0.925 33.4%, 0.894 34.5%, 0.882 35.6%, 0.887 36.6%, 0.907 37.7%, 1.045 42.4%, 1.069 44.5%, 1.059 46.3%, 0.979 50.9%, 0.96 53.4%, 0.966 55.3%, 1.013 59.9%, 1.024 62.3%, 0.986 71.2%, 1.008 79.9%, 0.995 88.9%, 1);


  /* Apply the easing with a duration that fits the spring's complexity */
  /* MANDATORY: Always include a duration; linear() does not calculate it automatically */
  transition: scale 0.8s var(--spring-easing);
}

.spring:hover {
  scale: 1.2;
}

ตัวอย่าง: การตีกลับเพื่อหลบเลี่ยงการติดตาม

ตัวอย่างนี้แสดงวิธีใช้ฟังก์ชัน linear() ที่กำหนดเองเพื่อสร้างเอฟเฟกต์การเด้ง

.bounce {
  /* Define the physics-based easing as a reusable variable */
  --bounce-easing: linear(0, 0.214 14.7%, 0.386 23.7%, 0.598 31.9%, 0.999 44.7%, 0.807 52.6%, 0.762 56%, 0.747 59.4%, 0.758 62.4%, 0.793 65.6%, 0.999 77.4%, 0.961 81.2%, 0.949 84.8%, 0.956 88%, 0.993 95.5%, 1);


  /* Apply the easing with a duration that fits the bounce's complexity */
  /* MANDATORY: Always include a duration; linear() does not calculate it automatically */
  transition: scale 0.4s var(--bounce-easing);
}

.bounce:hover {
  scale: 1.2;
}

ข้อควรพิจารณาที่สำคัญ

  • ประสิทธิภาพ: หากต้องการภาพเคลื่อนไหวที่อิงตามหลักฟิสิกส์ที่ราบรื่นที่สุด ให้ใช้ linear() กับพร็อพเพอร์ตี้ที่ทำงานในเทรดแยกต่างหาก เช่น transform และ opacity
  • ความแม่นยำเทียบกับเพย์โหลด: แม้ว่าการหยุดที่มากขึ้นจะทำให้เส้นโค้งราบรื่นขึ้น แต่ก็เพิ่มขนาดของ CSS ด้วย เครื่องมือสร้างส่วนใหญ่จะช่วยให้คุณ "ลดความซับซ้อน" ของเส้นโค้งเพื่อค้นหาสมดุลที่เหมาะสมที่สุดระหว่างความราบรื่นและขนาดโค้ด
  • หลีกเลี่ยงการใช้ความทึบแสงสำหรับการเด้ง: การใช้การผ่อนความเร็วแบบเด้งกับ opacity อาจทำให้เกิดการกะพริบที่ดูไม่น่ามองหากค่าเกิน 0 หรือ 1
  • การช่วยเหลือพิเศษ: ภาพเคลื่อนไหวที่อิงตามหลักฟิสิกส์ที่ซับซ้อนอาจทำให้ผู้ใช้บางรายเสียสมาธิหรือทำให้เกิดความไวต่อการเคลื่อนไหว เคารพค่ากำหนดของผู้ใช้เสมอโดยลดหรือปิดใช้ภาพเคลื่อนไหวเหล่านี้
@media (prefers-reduced-motion: reduce) {
  .element {
    transition: none;
  }
}

กลยุทธ์สำรอง

CSS สำรอง

สำหรับเบราว์เซอร์ที่ไม่รองรับ linear() ให้ใช้ฟังก์ชันการค่อยๆ เปลี่ยนมาตรฐานเป็นทางเลือกสำรอง เบราว์เซอร์จะละเว้นค่า linear() หากไม่รู้จัก และจะกลับไปใช้การประกาศที่ถูกต้องก่อนหน้า

.element {
  /* Fallback for older browsers (standard smooth exit) */
  transition: transform 0.8s ease-out;
  
  /* Modern browsers will override with the physics-based easing */
  transition-timing-function: linear(0, 1.1, 0.95, 1.02, 1);
}

JavaScript Library Fallback (Motion/GSAP)

ไม่บังคับ: หากภาพเคลื่อนไหวที่อิงตามหลักฟิสิกส์ที่มีความแม่นยำสูงเป็นสิ่งสำคัญแม้ในเบราว์เซอร์รุ่นเก่า ให้ใช้ไลบรารี JavaScript เช่น Motion (motion.dev) หรือ GSAP (greensock.com) เพื่อจัดการภาพเคลื่อนไหวเมื่อไม่รองรับ linear()

  1. การตรวจหาการรองรับ: ใช้ CSS.supports() เพื่อตรวจสอบว่าเบราว์เซอร์จัดการฟังก์ชัน linear() หรือไม่
  2. โหลด/ใช้แบบมีเงื่อนไข: หากไม่รองรับ ให้ใช้การติดตั้งใช้งานสปริงหรือการเด้งของไลบรารี
/* Detect if the browser supports the linear() function */
const supportsLinearEasing = window.CSS && CSS.supports('animation-timing-function', 'linear(0, 1)');

if (!supportsLinearEasing) {
  /* 
     Example using Motion (motion.dev) for a spring fallback.
     This should only be initialized if native CSS support is missing.
  */
  import("https://cdn.jsdelivr.net/npm/motion@latest/dist/motion.js").then(({ animate, spring }) => {
    animate(".element", { transform: "scale(1.2)" }, {
      easing: spring({ stiffness: 100, damping: 10 })
    });
  });
}

นอกจากนี้ คุณยังใช้ @supports ใน CSS เพื่อตรวจหาฟีเจอร์ที่ชัดเจนยิ่งขึ้นได้ด้วย ดังนี้

@supports not (animation-timing-function: linear(0, 1)) {
  .element {
    /* Alternative experience for unsupported browsers */
    transition-duration: 0.4s;
    transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1);
  }
}