Skip to main content

Animation Guidelines

หลักการ​

Animation ต้อง subtle, purposeful ไม่ใช่ decoration เกินจำเป็น — สอดคล้องกับ vibe minimal/premium/boardroom-ready ของแบรนด์ การเคลื่อนไหวมีไว้เพื่อ สื่อความสัมพันธ์และทิศทาง (อะไรมาจากไหน ไปไหน) ไม่ใช่เพื่อโชว์ ห้ามใช้เอฟเฟกต์ bounce/overshoot/หวือหวา

Duration Tokens​

ค่าที่แนะนำสำหรับทุก transition/animation — สั้นเข้าไว้ ยาวสุดของ UI ปกติไม่ควรเกิน 300ms:

Tokenค่าใช้กับ
motion.duration.instant100msmicro-interaction (checkbox, toggle)
motion.duration.fast150mshover, color/opacity transition
motion.duration.base200mstransition UI ทั่วไป (default)
motion.duration.slow300mscard/modal เข้า, dropdown
motion.duration.slower500mspage transition, overlay เต็มจอ
Duration Playback · กดปุ่มเลือกความเร็ว

ลูกบอลเคลื่อนที่ไป-กลับตาม duration ที่เลือก · กดเปลี่ยนความเร็วเพื่อสัมผัสความต่าง

Easing Curves​

Tokencubic-bezierใช้กับ
motion.ease.standard(0.4, 0, 0.2, 1)transition ทั่วไป (เข้า-ออกพร้อมกัน)
motion.ease.decelerate(0, 0, 0.2, 1)element ที่ เข้า (เข้าเร็ว ชะลอลงตอนจบ)
motion.ease.accelerate(0.4, 0, 1, 1)element ที่ ออก (เร่งออกไป)
linear—เฉพาะ spinner/progress ที่หมุนต่อเนื่อง
Easing Comparison · ชี้เมาส์ที่แถบเพื่อดูความต่าง
ease (standard)
(0.4, 0, 0.2, 1)
ease-in (decelerate)
(0, 0, 0.2, 1)
ease-out (accelerate)
(0.4, 0, 1, 1)
linear
linear

ชี้เมาส์ที่แถบสีเทา — ลูกบอลจะเคลื่อนที่ด้วย easing curve ที่ต่างกัน สังเกตความเร็วต้น-ปลายของแต่ละ curve

Enter / Exit Patterns​

  • Enter: fade-in + เลื่อนเบาๆ 8–16px หรือ scale จาก 0.98 → 1 ใช้ decelerate — ห้ามเลื่อนระยะไกลหรือ slide เต็มจอ
  • Exit: fade-out เร็วกว่า enter หนึ่งสเต็ป ใช้ accelerate (ของที่กำลังจากไปไม่ต้องดึงความสนใจ)
  • ระยะการเคลื่อนต้องเล็ก — premium คือ "รู้สึกได้แต่ไม่ตะโกน"

Loading States​

  • Skeleton shimmer เป็นค่าเริ่มต้น (ดู States & Feedback) — shimmer วนช้าๆ ~1.4s
  • Spinner ใช้ linear หมุนต่อเนื่อง สีเส้น #FF6727
  • Progress bar เคลื่อนแบบ linear สะท้อนความคืบหน้าจริง อย่าปลอม

Hover / Active Transitions​

  • Hover: เปลี่ยน background/สี/เงาใน fast (150ms) standard — ปุ่มยกตัวด้วย shadow.md (ดู Spacing, Radius & Elevation)
  • Active/pressed: scale 0.98 สั้นๆ ให้ feedback การกด แล้วคืนสภาพ
  • โทเคนสี hover ใช้ color.primary-hover (#C43400) ตามที่กำหนดใน component token — ดู Buttons & Cards

Page Transitions​

  • ใช้ fade อ่อนๆ base–slower (200–500ms) ตอนเปลี่ยนหน้า/route ห้ามใช้ slide/flip/zoom หวือหวา
  • คงตำแหน่งองค์ประกอบร่วม (โลโก้/นาว) ให้นิ่ง ไม่กระตุกระหว่างเปลี่ยนหน้า

Reduced Motion (บังคับ)​

เคารพ prefers-reduced-motion เสมอ — ผู้ใช้ที่ตั้งค่านี้ (เวียนหัวจากการเคลื่อนไหว) ต้องได้ประสบการณ์ที่นิ่ง โดยเนื้อยังครบ:

Reduced Motion Toggle · ลองปิด animation ทั้งหน้า
เปิด Reduced Motion (หยุด animation ทั้งหมด)

ปุ่มด้านบนจำลอง prefers-reduced-motion: reduce — กดเพื่อดูว่า animation ทั้งหมดหยุดอย่างไร ตัวเว็บจริงจะอ่านค่าจาก OS โดยอัตโนมัติ

@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
* {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}

JS-driven animation (เช่น Chart.js) ต้องเช็ค matchMedia('(prefers-reduced-motion: reduce)') เองด้วย (ดู Chart.js Theme)

Do / Don't​

✅ Do❌ Don't
duration ≤ 300ms สำหรับ UI ทั่วไปanimation ยืดยาด > 500ms ใน interaction
เลื่อน 8–16px + fade ตอน enterslide/zoom เต็มจอหวือหวา
exit เร็วกว่า enterเอฟเฟกต์ bounce/overshoot
เคารพ reduced-motion ทั้ง CSS และ JSบังคับ animation ทุกกรณี
ใช้ animation เพื่อสื่อทิศทาง/ความสัมพันธ์animation เพื่อตกแต่งอย่างเดียว