ทำ animation บน compositor ด้วย transform และ opacity จัดโครงสร้าง @keyframes ของคุณ และเคารพความชอบด้านการเคลื่อนไหวของผู้ใช้
เปิดบทเรียนนี้ใน Kodokonก่อนเลือกว่าจะ animate อะไร ให้ระลึกถึงไปป์ไลน์การเรนเดอร์: layout (เรขาคณิต), paint (พิกเซล), composite (การประกอบเลเยอร์บน GPU) การ animate width หรือ top จะกระตุ้น layout ในทุก ๆ เฟรม ตามด้วย paint บ่อยครั้ง นั่นคือสูตรของอาการกระตุก (jank) ที่ต่ำกว่า 60 fps ส่วน transform และ opacity ถูกจัดการโดย compositor โดยตรง โดยไม่ต้องย้อนกลับไปผ่านสองขั้นตอนแรก กฎแบบมืออาชีพ: animate เฉพาะสอง property นี้เมื่อทำได้ และจำลองส่วนที่เหลือ (translate แทน top, scale แทน width)
.button {
transform: translateY(0);
transition:
transform 0.2s cubic-bezier(0.2, 0.8, 0.2, 1),
opacity 0.15s ease-out;
}
.button:hover {
transform: translateY(-2px);
}
.button:active {
transform: translateY(0) scale(0.97);
}เมื่อ transition ไม่เพียงพออีกต่อไป (มีขั้นตอนระหว่างกลาง, การวนซ้ำ, การเริ่มอัตโนมัติ) ให้ย้ายไปใช้ @keyframes การตั้งค่าสองอย่างสร้างความแตกต่างระหว่าง animation ที่สะอาดกับบั๊กทางภาพ: animation-fill-mode ควบคุมสถานะ ก่อน เริ่ม (backwards ใช้ keyframe แรกในระหว่างช่วงหน่วง) และ หลัง จบ (forwards แช่แข็ง keyframe สุดท้ายไว้) ส่วน both รวมทั้งสองอย่างเข้าด้วยกัน โปรดสังเกตด้วยว่า timing function ทำงาน ระหว่าง keyframe แต่ละคู่ ไม่ใช่ตลอดระยะเวลาทั้งหมด: คุณสามารถกำหนดมันใหม่ภายใน keyframe ได้
@keyframes slide-in {
from {
transform: translateX(-100%);
opacity: 0;
}
70% {
transform: translateX(8px);
opacity: 1;
}
to {
transform: translateX(0);
}
}
.toast {
animation: slide-in 0.35s ease-out both;
}เครื่องมือเสริมสองอย่างที่ควรรู้ will-change: transform เลื่อนขั้นให้ element ไปอยู่บนเลเยอร์ของตัวเองก่อน animation เพื่อหลีกเลี่ยงการ raster ที่ล่าช้า แต่แต่ละเลเยอร์กินหน่วยความจำ GPU ดังนั้นจงใช้มันก่อน animation เพียงเล็กน้อยแล้วเอาออกหลังจากนั้น อย่าใช้เป็นสไตล์ถาวรบน element หลายสิบตัว ส่วน steps(n) แทนที่ interpolation แบบต่อเนื่องด้วยการกระโดดเป็นช่วง ๆ: จำเป็นสำหรับ sprite, เคอร์เซอร์แบบพิมพ์ดีด หรือนาฬิกา
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}transform: translateX(100px) มากกว่า left: 100px สำหรับการเคลื่อนที่แบบ animate?transform ได้รับการรองรับดีกว่าโดยเบราว์เซอร์รุ่นเก่าtransform ถูกจัดการโดย compositor โดยไม่ต้องคำนวณ layout ใหม่ในทุก ๆ เฟรมleft ทำงานเฉพาะกับ element ที่จัดตำแหน่งแบบ absolute เท่านั้น ส่วน transform ทำงานได้ทุกที่transform รับค่าติดลบได้ ต่างจาก leftanimation-fill-mode: both ทำอะไร?will-change ที่ถูกต้องคืออะไร?* เพื่อเร่งความเร็วทั้งหน้าtransform: translateZ(0) เสมอtransition สำหรับ micro-interaction