ลองนึกภาพสิ่งนี้: คุณเข้าร่วมโปรเจ็กต์ใหม่ เจาะลึกโค้ดเบส และภายในสองสามชั่วโมงแรก คุณจะค้นพบบางสิ่งที่คุ้นเคยอย่างน่าหงุดหงิด คุณจะพบคำจำกัดความ @keyframes หลายคำสำหรับภาพเคลื่อนไหวพื้นฐานเดียวกันที่กระจัดกระจายไปทั่วสไตล์ชีต เอฟเฟกต์เฟดอินที่แตกต่างกันสามแบบ สไลด์สองหรือสามรูปแบบ แอนิเมชั่นการซูมจำนวนหนึ่ง และแอนิเมชั่นการหมุนที่แตกต่างกันอย่างน้อยสองอัน เพราะเหตุใด @keyframes พัลส์ { จาก { ขนาด: 1; } ถึง { ขนาด: 1.1; } }
@keyframes ชีพจรที่ใหญ่กว่า { 0%, 20%, 100% { ขนาด: 1; } 10%, 40% { ขนาด: 1.2; } }
หากสถานการณ์นี้ฟังดูคุ้นเคย แสดงว่าคุณไม่ได้อยู่คนเดียว จากประสบการณ์ของฉันในโปรเจ็กต์ต่างๆ หนึ่งในชัยชนะที่รวดเร็วสม่ำเสมอที่สุดที่ฉันสามารถให้ได้คือการรวมและกำหนดคีย์เฟรมให้เป็นมาตรฐาน มันกลายเป็นรูปแบบที่เชื่อถือได้จนตอนนี้ฉันตั้งตารอการล้างข้อมูลนี้ซึ่งเป็นหนึ่งในงานแรก ๆ ของฉันในโค้ดเบสใหม่ ตรรกะเบื้องหลังความโกลาหล ความซ้ำซ้อนนี้สมเหตุสมผลอย่างยิ่งเมื่อคุณคิดถึงมัน เราทุกคนใช้แอนิเมชั่นพื้นฐานเดียวกันในการทำงานในแต่ละวัน: การเฟด สไลด์ การซูม การหมุน และเอฟเฟกต์ทั่วไปอื่นๆ แอนิเมชั่นเหล่านี้ค่อนข้างตรงไปตรงมา และง่ายต่อการสร้างคำจำกัดความ @keyframes อย่างรวดเร็วเพื่อให้งานสำเร็จลุล่วง หากไม่มีระบบแอนิเมชั่นแบบรวมศูนย์ นักพัฒนาจะเขียนคีย์เฟรมเหล่านี้ตั้งแต่ต้น โดยไม่รู้ว่ามีแอนิเมชั่นที่คล้ายกันอยู่แล้วที่อื่นในโค้ดเบส นี่เป็นเรื่องปกติโดยเฉพาะอย่างยิ่งเมื่อทำงานในสถาปัตยกรรมแบบอิงคอมโพเนนต์ (ซึ่งพวกเราส่วนใหญ่ทำในทุกวันนี้) เนื่องจากทีมมักจะทำงานคู่ขนานในส่วนต่างๆ ของแอปพลิเคชัน ผลลัพธ์? ความวุ่นวายของแอนิเมชั่น ปัญหาเล็กๆ น้อยๆ ปัญหาที่ชัดเจนที่สุดเกี่ยวกับการทำสำเนาคีย์เฟรมคือการเสียเวลาในการพัฒนาและการขยายโค้ดโดยไม่จำเป็น คำจำกัดความของคีย์เฟรมหลายรายการหมายความว่ามีสถานที่หลายแห่งที่ต้องอัปเดตเมื่อข้อกำหนดเปลี่ยนแปลง ต้องการปรับระยะเวลาของแอนิเมชั่นการเฟดของคุณหรือไม่? คุณจะต้องค้นหาทุกอินสแตนซ์ในโค้ดเบสของคุณ ต้องการสร้างมาตรฐานฟังก์ชันการค่อยๆ เปลี่ยนหรือไม่? ขอให้โชคดีในการค้นหารูปแบบทั้งหมด การเพิ่มจุดบำรุงรักษาทำให้แม้แต่การอัพเดตแอนิเมชั่นธรรมดาๆ ก็เป็นงานที่ใช้เวลานาน ปัญหาที่ใหญ่กว่า การทำสำเนาคีย์เฟรมนี้ทำให้เกิดปัญหาร้ายกาจที่ซ่อนอยู่ใต้ผิวเผิน นั่นก็คือกับดักขอบเขตทั่วโลก แม้ว่าจะทำงานกับสถาปัตยกรรมแบบอิงคอมโพเนนต์ คีย์เฟรม CSS ก็ยังถูกกำหนดไว้ในขอบเขตส่วนกลางเสมอ ซึ่งหมายความว่าคีย์เฟรมทั้งหมดใช้กับส่วนประกอบทั้งหมด เสมอ. ใช่ ภาพเคลื่อนไหวของคุณไม่จำเป็นต้องใช้คีย์เฟรมที่คุณกำหนดไว้ในส่วนประกอบของคุณ โดยจะใช้คีย์เฟรมสุดท้ายที่ตรงกับชื่อเดียวกันทุกประการที่โหลดเข้าสู่ขอบเขตส่วนกลาง ตราบใดที่คีย์เฟรมทั้งหมดของคุณเหมือนกัน นี่อาจดูเหมือนเป็นปัญหาเล็กน้อย แต่ทันทีที่คุณต้องการปรับแต่งภาพเคลื่อนไหวสำหรับกรณีการใช้งานเฉพาะ คุณกำลังประสบปัญหา หรือแย่กว่านั้น คุณจะเป็นต้นเหตุ ภาพเคลื่อนไหวของคุณจะไม่ทำงานเพราะคอมโพเนนต์อื่นโหลดตามคุณ เขียนทับคีย์เฟรม หรือคอมโพเนนต์ของคุณโหลดครั้งสุดท้ายและเปลี่ยนลักษณะการทำงานของแอนิเมชันโดยไม่ได้ตั้งใจสำหรับคอมโพเนนต์อื่นๆ ทั้งหมดที่ใช้ชื่อคีย์เฟรมนั้น และคุณอาจไม่รู้ด้วยซ้ำ นี่เป็นตัวอย่างง่ายๆ ที่แสดงให้เห็นถึงปัญหา: .component-one { /* รูปแบบส่วนประกอบ */ แอนิเมชั่น: พัลส์ 1s ความสะดวกเข้า - ออกสลับไม่สิ้นสุด; }
/* คำจำกัดความ @keyframes นี้ใช้ไม่ได้ */ @keyframes พัลส์ { จาก { ขนาด: 1; } ถึง { ขนาด: 1.1; } }
/* ต่อมาในโค้ด... */
.component-สอง { /* รูปแบบส่วนประกอบ */ แอนิเมชั่น: พัลส์ 1 วินาที ความง่ายเข้า-ออกไม่มีที่สิ้นสุด; }
/* คีย์เฟรมนี้จะใช้กับทั้งสององค์ประกอบ */ @keyframes พัลส์ { 0%, 20%, 100% { ขนาด: 1; } 10%, 40% { ขนาด: 1.2; } }
คอมโพเนนต์ทั้งสองใช้ชื่อภาพเคลื่อนไหวเดียวกัน แต่คำจำกัดความ @keyframes ที่สองจะเขียนทับองค์ประกอบแรก ตอนนี้ทั้งคอมโพเนนต์หนึ่งและคอมโพเนนต์ที่สองจะใช้คีย์เฟรมที่สอง โดยไม่คำนึงว่าคอมโพเนนต์ใดจะกำหนดคีย์เฟรมใด ดูโทเค็นคีย์เฟรมปากกา - การสาธิต 1 [แยก] โดย Amit Sheen ส่วนที่แย่ที่สุด? สิ่งนี้มักจะทำงานได้อย่างสมบูรณ์แบบในการพัฒนาในท้องถิ่น แต่จะหยุดชะงักอย่างลึกลับในการผลิตเมื่อกระบวนการสร้างเปลี่ยนลำดับการโหลดของสไตล์ชีตของคุณ คุณจะได้ภาพเคลื่อนไหวที่มีพฤติกรรมแตกต่างออกไป ขึ้นอยู่กับส่วนประกอบที่โหลดและในลำดับใด โซลูชัน: คีย์เฟรมแบบรวม คำตอบสำหรับความวุ่นวายนี้ง่ายมากอย่างน่าประหลาดใจ: คีย์เฟรมไดนามิกที่กำหนดไว้ล่วงหน้าจัดเก็บไว้ในสไตล์ชีทที่ใช้ร่วมกัน แทนที่จะปล่อยให้ทุกองค์ประกอบกำหนดภาพเคลื่อนไหวของตัวเอง เราสร้างคีย์เฟรมแบบรวมศูนย์ที่มีการบันทึกไว้อย่างดี และง่ายต่อการใช้ บำรุงรักษา และปรับให้เหมาะกับความต้องการเฉพาะของโครงการของคุณ คิดว่ามันเป็นโทเค็นคีย์เฟรม เช่นเดียวกับที่เราใช้โทเค็นสำหรับสีและการเว้นวรรค และพวกเราหลายคนใช้โทเค็นสำหรับคุณสมบัติภาพเคลื่อนไหว เช่น ระยะเวลาและฟังก์ชันการค่อยๆ เปลี่ยน ทำไมไม่ใช้โทเค็นสำหรับคีย์เฟรมด้วย วิธีนี้สามารถผสานรวมเข้ากับเวิร์กโฟลว์โทเค็นการออกแบบปัจจุบันที่คุณใช้อยู่ได้อย่างเป็นธรรมชาติ ในขณะเดียวกันก็แก้ปัญหาเล็กๆ น้อยๆ (การทำซ้ำโค้ด) และปัญหาที่ใหญ่กว่า (ความขัดแย้งในขอบเขตทั่วโลก) ได้ในคราวเดียว แนวคิดนี้ตรงไปตรงมา: สร้างแหล่งความจริงแห่งเดียวสำหรับแอนิเมชันทั่วไปทั้งหมดของเรา สไตล์ชีตที่ใช้ร่วมกันนี้มีคีย์เฟรมที่สร้างขึ้นอย่างพิถีพิถันซึ่งครอบคลุมรูปแบบแอนิเมชั่นที่โปรเจ็กต์ของเราใช้จริง ไม่ต้องเดาอีกต่อไปว่าแอนิเมชั่นจางหายไปมีอยู่แล้วในโค้ดเบสของเราหรือไม่ ไม่มีการเขียนทับภาพเคลื่อนไหวจากส่วนประกอบอื่นๆ โดยไม่ได้ตั้งใจอีกต่อไป แต่นี่คือกุญแจสำคัญ: สิ่งเหล่านี้ไม่ใช่แค่ภาพเคลื่อนไหวแบบคัดลอกและวางแบบคงที่ ออกแบบมาให้เป็นไดนามิกและปรับแต่งได้ผ่านคุณสมบัติที่กำหนดเองของ CSS ช่วยให้เรารักษาความสอดคล้องในขณะที่ยังคงมีความยืดหยุ่นในการปรับภาพเคลื่อนไหวให้เหมาะกับกรณีการใช้งานเฉพาะ เช่น หากคุณต้องการภาพเคลื่อนไหวแบบ "ชีพจร" ที่ใหญ่ขึ้นเล็กน้อยในที่เดียว การสร้างโทเค็นคีย์เฟรมแรก ผลไม้แขวนต่ำชนิดแรกที่เราควรจัดการคือแอนิเมชั่น "เฟดอิน" ในโปรเจ็กต์ล่าสุดของฉัน ฉันพบคำจำกัดความเฟดอินที่แยกจากกันมากกว่าหนึ่งโหล และใช่ คำจำกัดความทั้งหมดเพียงแค่ทำให้ความทึบเคลื่อนไหวจาก 0 เป็น 1 ดังนั้น มาสร้างสไตล์ชีตใหม่ เรียกว่า kf-tokens.css นำเข้าสู่โปรเจ็กต์ของเรา และวางคีย์เฟรมของเราพร้อมความคิดเห็นที่เหมาะสมไว้ข้างใน /* คีย์เฟรม-tokens.css */
/* * Fade In - จางแอนิเมชั่นทางเข้า * การใช้งาน: แอนิเมชั่น: kf-fade-in 0.3s คลายออก; */ @keyframes kf-เฟดใน { จาก { ความทึบ: 0; } ถึง { ความทึบ: 1; } }
การประกาศ @keyframes เดี่ยวนี้จะแทนที่ภาพเคลื่อนไหวแบบเฟดอินที่กระจัดกระจายทั่วทั้งโค้ดเบสของเรา สะอาด เรียบง่าย และใช้ได้ทั่วโลก และตอนนี้เราได้กำหนดโทเค็นนี้แล้ว เราสามารถใช้มันจากส่วนประกอบใดก็ได้ตลอดโปรเจ็กต์ของเรา: .กิริยา { แอนิเมชั่น: kf-fade-in 0.3s คลายออก; }
.เคล็ดลับเครื่องมือ { แอนิเมชั่น: kf-fade-in 0.2s ง่ายต่อการเข้า - ออก; }
.การแจ้งเตือน { แอนิเมชั่น: kf-fade-in 0.5s คลายออก; }
ดูโทเค็นคีย์เฟรมปากกา - การสาธิต 2 [แยก] โดย Amit Sheen หมายเหตุ: เราใช้คำนำหน้า kf- ในชื่อ @keyframes ทั้งหมดของเรา คำนำหน้านี้ทำหน้าที่เป็นเนมสเปซที่ป้องกันการขัดแย้งในการตั้งชื่อกับภาพเคลื่อนไหวที่มีอยู่ในโปรเจ็กต์ และทำให้ชัดเจนทันทีว่าคีย์เฟรมเหล่านี้มาจากไฟล์โทเค็นของคีย์เฟรมของเรา การสร้างสไลด์แบบไดนามิก คีย์เฟรม kf-fade-in ใช้งานได้ดีเพราะมันเรียบง่ายและแทบไม่มีพื้นที่ให้ยุ่งวุ่นวาย อย่างไรก็ตาม ในแอนิเมชั่นอื่นๆ เราจำเป็นต้องมีไดนามิกมากกว่านี้ และที่นี่เราสามารถใช้ประโยชน์จากพลังอันมหาศาลของคุณสมบัติที่กำหนดเองของ CSS ได้ นี่คือจุดที่โทเค็นคีย์เฟรมโดดเด่นมากเมื่อเทียบกับภาพเคลื่อนไหวแบบคงที่ที่กระจัดกระจาย มาดูสถานการณ์ทั่วไปกัน: แอนิเมชั่นแบบ "สไลด์เข้า" แต่เลื่อนเข้ามาจากไหนล่ะ? 100px จากทางขวา? 50% จากซ้าย? ควรเข้าจากด้านบนของหน้าจอหรือไม่? หรืออาจจะลอยเข้ามาจากด้านล่าง? ความเป็นไปได้มากมาย แต่แทนที่จะสร้างคีย์เฟรมแยกกันสำหรับแต่ละทิศทางและแต่ละรูปแบบ เราสามารถสร้างโทเค็นที่ยืดหยุ่นได้หนึ่งอันที่ปรับให้เข้ากับทุกสถานการณ์: /* * Slide In - ภาพเคลื่อนไหวสไลด์ทิศทาง * ใช้ --kf-slide-from เพื่อควบคุมทิศทาง * ค่าเริ่มต้น: เลื่อนเข้าจากซ้าย (-100%) * การใช้งาน: * แอนิเมชั่น: kf-slide-in 0.3s คลายออก; * --kf-สไลด์จาก: -100px 0; //เลื่อนจากซ้าย * --kf-slide-จาก: 100px 0; //เลื่อนจากขวา. * --kf-สไลด์จาก: 0 -50px; //เลื่อนจากด้านบน */
@keyframes kf-สไลด์ใน { จาก { แปล: var(--kf-slide-from, -100% 0); } ถึง { แปล: 0 0; } }
ตอนนี้เราสามารถใช้โทเค็น @keyframes เดี่ยวนี้สำหรับทิศทางสไลด์ใดก็ได้ เพียงแค่เปลี่ยนคุณสมบัติ --kf-slide-from แบบกำหนดเอง: .แถบด้านข้าง { ภาพเคลื่อนไหว: kf-slide-in 0.3s คลายออก; /* ใช้ค่าเริ่มต้น: เลื่อนจากซ้าย */ }
.การแจ้งเตือน { แอนิเมชั่น: kf-slide-in 0.4s คลายออก; --kf-สไลด์จาก: 0 -50px; /* เลื่อนจากด้านบน */ }
.กิริยา { แอนิเมชั่น: kf-เฟดใน 0.5 วินาที kf-slide-in 0.5s ลูกบาศก์เบซิเยร์ (0.34, 1.56, 0.64, 1); --kf-สไลด์จาก: 50px 50px; /* เลื่อนจากขวาล่าง */ }
แนวทางนี้ทำให้เรามีความยืดหยุ่นอย่างไม่น่าเชื่อในขณะที่ยังคงรักษาความสม่ำเสมอ การประกาศคีย์เฟรมเดียว ความเป็นไปได้ที่ไม่มีที่สิ้นสุด ดูโทเค็นคีย์เฟรมปากกา - การสาธิต 3 [แยก] โดย Amit Sheen และหากเราต้องการทำให้แอนิเมชั่นของเรามีความยืดหยุ่นมากยิ่งขึ้น โดยให้มีเอฟเฟกต์ "เลื่อนออก" ด้วยเช่นกัน เราก็สามารถทำได้เพียงเพิ่มคุณสมบัติที่กำหนดเอง --kf-slide-to คล้ายกับที่เราจะเห็นในส่วนถัดไป คีย์เฟรมซูมแบบสองทิศทาง แอนิเมชันทั่วไปอีกประการหนึ่งที่ทำซ้ำทั่วทั้งโปรเจ็กต์คือเอฟเฟกต์ "ซูม" ไม่ว่าจะเป็นการเพิ่มขนาดเล็กน้อยสำหรับข้อความโทสต์ การซูมเข้าอย่างมากสำหรับโมดอล หรือเอฟเฟกต์การลดขนาดเล็กน้อยสำหรับส่วนหัว แอนิเมชั่นการซูมมีอยู่ทุกที่ แทนที่จะสร้างคีย์เฟรมแยกกันสำหรับแต่ละค่ามาตราส่วน เรามาสร้างชุดคีย์เฟรม kf-zoom ที่ยืดหยุ่นชุดหนึ่งกันดีกว่า:
/* * ซูม - ภาพเคลื่อนไหวขนาด * ใช้ --kf-zoom-from และ --kf-zoom-to เพื่อควบคุมค่ามาตราส่วน * ค่าเริ่มต้น: ซูมจาก 80% ถึง 100% (0.8 ถึง 1) * การใช้งาน: * แอนิเมชั่น: kf-zoom 0.2s คลายออก; * --kf-ซูมจาก: 0.5; --kf-ซูมเพื่อ: 1; // ซูมจาก 50% เป็น 100% * --kf-ซูมจาก: 1; --kf-ซูมเพื่อ: 0; // ซูมจาก 100% เป็น 0% * --kf-ซูมจาก: 1; --kf-ซูมเพื่อ: 1.1; // ซูมจาก 100% เป็น 110% */
@keyframes kf-zoom { จาก { สเกล: var(--kf-zoom-from, 0.8); } ถึง { สเกล: var(--kf-zoom-to, 1); } }
ด้วยคำจำกัดความเดียว เราสามารถบรรลุรูปแบบการซูมใดก็ได้ที่เราต้องการ: .ขนมปังปิ้ง { แอนิเมชั่น: kf-สไลด์เข้า 0.2 วินาที kf-zoom คลายออก 0.4 วินาที; --kf-สไลด์จาก: 0 100%; /* เลื่อนจากด้านบน */ /* ใช้การซูมเริ่มต้น: ปรับขนาดจาก 80% ถึง 100% */ }
.กิริยา { แอนิเมชั่น: kf-zoom 0.3s ลูกบาศก์เบซิเยร์ (0.34, 1.56, 0.64, 1); --kf-ซูมจาก: 0; /* ซูมได้อย่างมากจาก 0% ถึง 100% */ }
.หัวเรื่อง { แอนิเมชั่น: kf-เฟดใน 2 วินาที, kf-zoom 2s ใช้งานง่าย; --kf-ซูมจาก: 1.2; --kf ซูมไปที่: 0.8; /* ลดขนาดลงอย่างอ่อนโยน */ }
ค่าเริ่มต้นที่ 0.8 (80%) ทำงานได้อย่างสมบูรณ์แบบสำหรับองค์ประกอบ UI ส่วนใหญ่ เช่น ข้อความโทสต์และการ์ด ในขณะที่ยังคงปรับแต่งได้ง่ายสำหรับกรณีพิเศษ ดูโทเค็นคีย์เฟรมปากกา - การสาธิต 4 [แยก] โดย Amit Sheen คุณอาจสังเกตเห็นสิ่งที่น่าสนใจในตัวอย่างล่าสุด: เราได้รวมภาพเคลื่อนไหวเข้าด้วยกัน ข้อดีหลักประการหนึ่งของการทำงานกับโทเค็น @keyframes คือได้รับการออกแบบให้ผสานรวมเข้าด้วยกันได้อย่างราบรื่น การจัดองค์ประกอบภาพที่ราบรื่นนี้เป็นความตั้งใจ ไม่ใช่ความบังเอิญ เราจะหารือเกี่ยวกับองค์ประกอบของแอนิเมชั่นโดยละเอียดในภายหลัง รวมถึงจุดที่อาจเป็นปัญหาได้ แต่การผสมผสานส่วนใหญ่จะตรงไปตรงมาและใช้งานง่าย หมายเหตุ: ในขณะที่เขียนบทความนี้ และอาจเป็นเพราะการเขียนบทความนี้ ฉันพบว่าตัวเองกำลังคิดทบทวนแนวคิดทั้งหมดเกี่ยวกับแอนิเมชั่นตอนเข้าเรื่อง ด้วยความก้าวหน้าล่าสุดใน CSS เรายังต้องการมันอยู่หรือเปล่า? โชคดีที่ Adam Argyle สำรวจคำถามเดียวกันและแสดงความคิดเห็นได้อย่างยอดเยี่ยมในบล็อกของเขา สิ่งนี้ไม่ขัดแย้งกับสิ่งที่เขียนไว้ที่นี่ แต่นำเสนอแนวทางที่ควรค่าแก่การพิจารณา โดยเฉพาะอย่างยิ่งหากโปรเจ็กต์ของคุณอาศัยแอนิเมชั่นตอนทางเข้าเป็นอย่างมาก ภาพเคลื่อนไหวต่อเนื่อง ในขณะที่ภาพเคลื่อนไหวทางเข้า เช่น "จาง" "สไลด์" และ "ซูม" เกิดขึ้นครั้งเดียวแล้วหยุด ภาพเคลื่อนไหวต่อเนื่องจะวนซ้ำอย่างไม่มีกำหนดเพื่อดึงดูดความสนใจหรือบ่งบอกถึงกิจกรรมที่กำลังดำเนินอยู่ แอนิเมชันต่อเนื่องที่พบบ่อยที่สุดสองรายการที่ฉันพบคือ “หมุน” (สำหรับตัวบ่งชี้การโหลด) และ “ชีพจร” (สำหรับการเน้นองค์ประกอบที่สำคัญ) แอนิเมชั่นเหล่านี้นำเสนอความท้าทายที่ไม่เหมือนใครเมื่อพูดถึงการสร้างโทเค็นคีย์เฟรม ต่างจากแอนิเมชั่นทางเข้าที่ปกติจะเปลี่ยนจากสถานะหนึ่งไปอีกสถานะหนึ่ง แอนิเมชั่นต่อเนื่องจำเป็นต้องปรับแต่งได้สูงในรูปแบบพฤติกรรม หมอสปิน ดูเหมือนว่าทุกโปรเจ็กต์จะใช้แอนิเมชั่นการหมุนหลายอัน บ้างก็หมุนตามเข็มนาฬิกา บ้างก็หมุนทวนเข็มนาฬิกา บางรุ่นหมุนได้ 360 องศาเพียงครั้งเดียว บางรุ่นหมุนหลายรอบเพื่อให้ได้ผลเร็วขึ้น แทนที่จะสร้างคีย์เฟรมแยกกันสำหรับแต่ละรูปแบบ มาสร้างการหมุนที่ยืดหยุ่นที่จัดการทุกสถานการณ์กันดีกว่า:
/* * หมุน - แอนิเมชั่นการหมุน * ใช้ --kf-spin-from และ --kf-spin-to เพื่อควบคุมช่วงการหมุน * ใช้ --kf-spin-turns เพื่อควบคุมจำนวนการหมุน * ค่าเริ่มต้น: หมุนจาก 0deg ถึง 360deg (หมุนเต็ม 1 ครั้ง) * การใช้งาน: * แอนิเมชั่น: kf-spin 1s เชิงเส้นไม่สิ้นสุด; * --kf-หมุน-เปลี่ยน: 2; // 2 รอบเต็ม * --kf-หมุนจาก: 0deg; --kf-หมุนไป: 180deg; //หมุนครึ่งรอบ * --kf-หมุนจาก: 0deg; --kf-หมุนไป: -360deg; //ทวนเข็มนาฬิกา */
@keyframes kf-หมุน { จาก { หมุน: var(--kf-spin-from, 0deg); } ถึง { หมุน: calc(var(--kf-spin-from, 0deg) + var(--kf-spin-to, 360deg) * var(--kf-spin-turns, 1)); } }
ตอนนี้เราสามารถสร้างรูปแบบการหมุนที่เราชอบได้:
.loading-spinner { แอนิเมชัน: kf-spin 1s เชิงเส้นไม่สิ้นสุด; /* ใช้ค่าเริ่มต้น: หมุนจาก 0deg ถึง 360deg */ }
.ตัวโหลดเร็ว { แอนิเมชั่น: kf-spin 1.2s ความสะดวกเข้า - ออกสลับไม่สิ้นสุด; --kf-หมุน-เปลี่ยน: 3; /* 3 รอบเต็มสำหรับแต่ละทิศทางต่อรอบ*/ }
. ก้าวถอยหลัง { ภาพเคลื่อนไหว: kf-spin 1.5s ขั้นตอน (8) อนันต์; --kf-หมุนไป: -360deg; /* ทวนเข็มนาฬิกา */ }
.subtle-กระดิก { แอนิเมชั่น: kf-spin 2s ความสะดวกเข้า - ออกสลับไม่สิ้นสุด; --kf-หมุนจาก: -16deg; --kf-หมุนไป: 32deg; /* ขยับ 36 องศา: ระหว่าง -18 องศา ถึง +18 องศา */ }
ดูโทเค็นคีย์เฟรมปากกา - การสาธิต 5 [แยก] โดย Amit Sheen ข้อดีของแนวทางนี้คือคีย์เฟรมเดียวกันนั้นใช้สำหรับการโหลดสปินเนอร์ ไอคอนที่หมุนได้ เอฟเฟกต์การกระดิก และแม้แต่แอนิเมชั่นแบบหลายเทิร์นที่ซับซ้อน ชีพจร Paradox แอนิเมชันแบบพัลส์มีความซับซ้อนกว่าเนื่องจากสามารถ "กระตุ้น" คุณสมบัติที่แตกต่างกันได้ บางตัวจะสั่นตามสเกล บางตัวจะสั่นตามความทึบ และคุณสมบัติสีเป็นจังหวะบางอย่าง เช่น ความสว่างหรือความอิ่มตัว แทนที่จะสร้างคีย์เฟรมแยกกันสำหรับแต่ละคุณสมบัติ เราสามารถสร้างคีย์เฟรมที่ทำงานร่วมกับคุณสมบัติ CSS ใดก็ได้ ต่อไปนี้คือตัวอย่างของพัลส์คีย์เฟรมที่มีตัวเลือกมาตราส่วนและความทึบ:
/* * Pulse - แอนิเมชั่นที่เต้นเป็นจังหวะ * ใช้ --kf-pulse-scale-from และ --kf-pulse-scale-to เพื่อควบคุมช่วงขนาด * ใช้ --kf-pulse-opacity-from และ --kf-pulse-opacity-to เพื่อควบคุมช่วงความทึบ * ค่าเริ่มต้น: ไม่มีพัลส์ (ค่าทั้งหมด 1) * การใช้งาน: * ภาพเคลื่อนไหว: kf-pulse 2s ความสะดวกเข้า - ออกสลับไม่สิ้นสุด; * --kf-ชีพจร-ขนาด-จาก: 0.95; --kf-ชีพจร-ขนาดถึง: 1.05; // สเกลชีพจร * --kf-ชีพจร-ทึบ-จาก: 0.7; --kf-ชีพจร-ความทึบถึง: 1; // ชีพจรทึบ */
@keyframes kf-ชีพจร { จาก { สเกล: var(--kf-pulse-scale-from, 1); ความทึบ: var(--kf-pulse-opacity-from, 1); } ถึง { ขนาด: var (--kf-pulse-scale-to, 1); ความทึบ: var(--kf-pulse-opacity-to, 1); } }
สิ่งนี้จะสร้างพัลส์ที่ยืดหยุ่นซึ่งสามารถทำให้คุณสมบัติหลายอย่างเคลื่อนไหวได้: .คำกระตุ้นการตัดสินใจ { ภาพเคลื่อนไหว: kf-pulse 0.6s สลับไม่สิ้นสุด; --kf-ชีพจร-ทึบ-จาก: 0.5; /* ชีพจรทึบ */ }
.notification-dot { แอนิเมชัน: kf-pulse 0.6s การค่อยๆ เข้า-ออก สลับกันอย่างไม่มีที่สิ้นสุด; --kf-ชีพจร-ขนาด-จาก: 0.9; --kf-ชีพจรขนาดถึง: 1.1; /* สเกลพัลส์ */ }
.text-เน้น { แอนิเมชัน: kf-pulse 1.5s คลายออกอย่างไม่มีที่สิ้นสุด; --kf-ชีพจร-ขนาด-จาก: 0.8; --kf-ชีพจร-ทึบ-จาก: 0.2; /* สเกลและความทึบของพัลส์ */ }
ดูโทเค็นคีย์เฟรมปากกา - การสาธิต 6 [แยก] โดย Amit Sheen คีย์เฟรม kf-pulse เดี่ยวนี้สามารถจัดการทุกอย่างตั้งแต่การดึงความสนใจเล็กน้อยไปจนถึงไฮไลท์ที่น่าทึ่ง ทั้งหมดนี้ปรับแต่งได้ง่าย การค่อยๆ เปลี่ยนขั้นสูง สิ่งที่ยอดเยี่ยมอย่างหนึ่งเกี่ยวกับการใช้โทเค็นคีย์เฟรมคือความง่ายในการขยายไลบรารีแอนิเมชั่นของเราและให้เอฟเฟกต์ที่นักพัฒนาส่วนใหญ่ไม่ต้องการเขียนตั้งแต่ต้น เช่น แบบยืดหยุ่นหรือการเด้ง ต่อไปนี้คือตัวอย่างของโทเค็นคีย์เฟรม "bounce" แบบง่ายๆ ที่ใช้ --kf-bounce-from คุณสมบัติที่กำหนดเอง เพื่อควบคุมความสูงของการกระโดด /* * Bounce - แอนิเมชั่นทางเข้าเด้ง * ใช้ --kf-bounce-from เพื่อควบคุมความสูงของการกระโดด * ค่าเริ่มต้น: กระโดดจาก 100vh (ปิดหน้าจอ) * การใช้งาน: * แอนิเมชั่น: kf-bounce 3s ง่ายต่อการใช้งาน; * --kf-เด้งจาก: 200px; // กระโดดจากความสูง 200px */
@keyframes kf-เด้ง { 0% { แปล: 0 calc(var(--kf-bounce-from, 100vh) * -1); }
34% { แปล: 0 calc(var(--kf-bounce-from, 100vh) * -0.4); }
55% { แปล: 0 calc(var(--kf-bounce-from, 100vh) * -0.2); }
72% { แปล: 0 calc(var(--kf-bounce-from, 100vh) * -0.1); }
85% { แปล: 0 calc(var(--kf-bounce-from, 100vh) * -0.05); }
94% { แปล: 0 calc(var(--kf-bounce-from, 100vh) * -0.025); }
99% { แปล: 0 calc(var(--kf-bounce-from, 100vh) * -0.0125); }
22%, 45%, 64%, 79%, 90%, 97%, 100% { แปล: 0 0; ฟังก์ชั่นจับเวลาภาพเคลื่อนไหว: คลายออก; } }
แอนิเมชั่นอย่าง “ยืดหยุ่น” นั้นยุ่งยากกว่าเล็กน้อยเนื่องจากมีการคำนวณภายในคีย์เฟรม เราจำเป็นต้องกำหนด --kf-elastic-from-X และ --kf-elastic-from-Y แยกกัน (ทั้งสองเป็นทางเลือก) และทั้งสองอย่างนี้ช่วยให้เราสร้างทางเข้าแบบยืดหยุ่นได้จากจุดใดก็ได้บนหน้าจอ
/* * Elastic In - แอนิเมชั่นทางเข้าแบบยืดหยุ่น * ใช้ --kf-elastic-from-X และ --kf-elastic-from-Y เพื่อควบคุมตำแหน่งเริ่มต้น * ค่าเริ่มต้น: เข้าสู่จากศูนย์กลางด้านบน (0, -100vh) * การใช้งาน: * แอนิเมชั่น: kf-elastic-in 2s ง่ายต่อการเข้า - ออกทั้งคู่; * --kf-elastic-from-X: -50px; * --kf-elastic-from-Y: -200px; // ป้อนจาก (-50px, -200px) */
@keyframes kf-elastic-in { 0% { แปล: calc(var(--kf-elastic-from-X, -50vw) * 1) calc(var(--kf-elastic-from-Y, 0px) * 1); }
16% { แปล: calc(var(--kf-elastic-from-X, -50vw) * -0.3227) calc(var(--kf-elastic-from-Y, 0px) * -0.3227); }
28% { แปล: calc (var (--kf-elastic-from-X, -50vw) * 0.1312)คำนวณ(var(--kf-elastic-from-Y, 0px) * 0.1312); }
44% { แปล: calc(var(--kf-elastic-from-X, -50vw) * -0.0463) calc(var(--kf-elastic-from-Y, 0px) * -0.0463); }
59% { แปล: calc(var(--kf-elastic-from-X, -50vw) * 0.0164) calc(var(--kf-elastic-from-Y, 0px) * 0.0164); }
73% { แปล: calc(var(--kf-elastic-from-X, -50vw) * -0.0058) calc(var(--kf-elastic-from-Y, 0px) * -0.0058); }
88% { แปล: calc(var(--kf-elastic-from-X, -50vw) * 0.0020) calc(var(--kf-elastic-from-Y, 0px) * 0.0020); }
100% { แปล: 0 0; } }
แนวทางนี้ทำให้ง่ายต่อการใช้ซ้ำและปรับแต่งคีย์เฟรมขั้นสูงทั่วทั้งโปรเจ็กต์ของเรา เพียงแค่เปลี่ยนคุณสมบัติที่กำหนดเองรายการเดียว
. ตีกลับและซูม { แอนิเมชั่น: kf-bounce 3s ง่ายต่อการใช้งาน kf-zoom 3s เชิงเส้น; --kf-ซูมจาก: 0; }
. ตีกลับและสไลด์ { องค์ประกอบแอนิเมชั่น: เพิ่ม; /* ภาพเคลื่อนไหวทั้งสองใช้การแปล */ แอนิเมชั่น: kf-bounce 3s ง่ายต่อการใช้งาน kf-slide-in 3s คลายออก; --kf-สไลด์จาก: -200px; }
.elastic-in { แอนิเมชัน: kf-elastic-in 2s ง่ายต่อการเข้า - ออกทั้งสอง; }
ดูโทเค็นคีย์เฟรมปากกา - การสาธิต 7 [แยก] โดย Amit Sheen เมื่อถึงจุดนี้ เราได้เห็นว่าเราสามารถรวมคีย์เฟรมเข้าด้วยกันอย่างชาญฉลาดและมีประสิทธิภาพได้อย่างไร แน่นอนว่า คุณอาจต้องการปรับแต่งสิ่งต่างๆ ให้เหมาะกับความต้องการของโปรเจ็กต์ของคุณมากขึ้น แต่เราได้กล่าวถึงตัวอย่างแอนิเมชันทั่วไปและกรณีการใช้งานในชีวิตประจำวันหลายรายการแล้ว และด้วยโทเค็นคีย์เฟรมเหล่านี้ ตอนนี้เราจึงมีบล็อคการสร้างอันทรงพลังสำหรับการสร้างแอนิเมชั่นที่สม่ำเสมอและบำรุงรักษาได้ทั่วทั้งโปรเจ็กต์ ไม่มีคีย์เฟรมที่ซ้ำกันอีกต่อไป ไม่มีความขัดแย้งในขอบเขตทั่วโลกอีกต่อไป เป็นวิธีที่สะอาดและสะดวกสบายในการจัดการกับความต้องการด้านแอนิเมชั่นทั้งหมดของเรา แต่คำถามที่แท้จริงคือ เราจะประกอบชิ้นส่วนสำเร็จรูปเหล่านี้เข้าด้วยกันได้อย่างไร รวบรวมมันทั้งหมดเข้าด้วยกัน เราพบว่าการรวมโทเค็นคีย์เฟรมพื้นฐานนั้นเป็นเรื่องง่าย เราไม่ต้องการอะไรพิเศษนอกจากการกำหนดภาพเคลื่อนไหวแรก กำหนดภาพเคลื่อนไหวที่สอง ตั้งค่าตัวแปรตามต้องการ แค่นี้เอง /* จางลง + เลื่อนเข้า */ .ขนมปังปิ้ง { แอนิเมชั่น: kf-เฟดใน 0.4 วินาที, kf-slide-in 0.4s ลูกบาศก์เบซิเยร์ (0.34, 1.56, 0.64, 1); --kf-สไลด์จาก: 0 40px; }
/* ซูมเข้า + จางเข้า */ .กิริยา { แอนิเมชั่น: kf-เฟดใน 0.3 วินาที, kf-zoom 0.3 วินาทีลูกบาศก์เบซิเยร์ (0.34, 1.56, 0.64, 1); --kf-ซูมจาก: 0.7; --kf-ซูมเพื่อ: 1; }
/* เลื่อนเข้า + ชีพจร */ .การแจ้งเตือน { แอนิเมชั่น: kf-สไลด์เข้า 0.5 วินาที kf-pulse 1.2s ความสะดวกเข้า-ออก ทางเลือกที่ไม่มีที่สิ้นสุด; --kf-สไลด์จาก: -100px 0; --kf-ชีพจร-ขนาด-จาก: 0.95; --kf-ชีพจร-ขนาดถึง: 1.05; }
การผสมผสานเหล่านี้ทำงานอย่างสวยงามเพราะแต่ละแอนิเมชันกำหนดเป้าหมายคุณสมบัติที่แตกต่างกัน เช่น ความทึบ การแปลง (การแปล/มาตราส่วน) ฯลฯ แต่บางครั้งก็มีข้อขัดแย้งกัน และเราจำเป็นต้องรู้ว่าเหตุใดและจะจัดการกับสิ่งเหล่านี้อย่างไร เมื่อภาพเคลื่อนไหวสองตัวพยายามทำให้คุณสมบัติเดียวกันเคลื่อนไหว เช่น ทั้งขนาดการเคลื่อนไหวหรือทั้งสองความทึบของภาพเคลื่อนไหว ผลลัพธ์จะไม่เป็นอย่างที่คุณคาดหวัง ตามค่าเริ่มต้น จะมีการใช้ภาพเคลื่อนไหวเพียงรายการเดียวกับคุณสมบัตินั้น ซึ่งเป็นรายการสุดท้ายในรายการภาพเคลื่อนไหว นี่เป็นข้อจำกัดของวิธีที่ CSS จัดการกับภาพเคลื่อนไหวหลายรายการในคุณสมบัติเดียวกัน ตัวอย่างเช่น สิ่งนี้จะไม่ทำงานตามที่ตั้งใจไว้ เนื่องจากจะใช้เฉพาะภาพเคลื่อนไหว kf-pulse เท่านั้น .bad-คำสั่งผสม { แอนิเมชั่น: kf-zoom 0.5 วินาทีไปข้างหน้า kf-pulse 1.2s สลับอนันต์; --kf-ซูมจาก: 0.5; --kf-ซูมเพื่อ: 1.2; --kf-ชีพจร-ขนาด-จาก: 0.8; --kf-ชีพจรขนาดถึง: 1.1; }
นอกจากนี้แอนิเมชั่น วิธีที่ง่ายและตรงที่สุดในการจัดการภาพเคลื่อนไหวหลายรายการที่ส่งผลต่อคุณสมบัติเดียวกันคือการใช้คุณสมบัติanimation-composition ในตัวอย่างสุดท้ายด้านบน แอนิเมชัน kf-pulse จะแทนที่แอนิเมชัน kf-zoom ดังนั้น เราจะไม่เห็นการซูมเริ่มต้น และจะไม่ได้ขนาดที่คาดหวังไว้ที่ 1.2 ด้วยการตั้งค่าองค์ประกอบภาพเคลื่อนไหวที่จะเพิ่ม เราจะบอกให้เบราว์เซอร์รวมภาพเคลื่อนไหวทั้งสองเข้าด้วยกัน สิ่งนี้ทำให้เราได้ผลลัพธ์ที่เราต้องการ .component-สอง { องค์ประกอบแอนิเมชั่น: เพิ่ม; }
ดูโทเค็นคีย์เฟรมปากกา - การสาธิต 8 [แยก] โดย Amit Sheen วิธีการนี้ใช้ได้ผลดีกับกรณีส่วนใหญ่ที่เราต้องการรวมเอฟเฟกต์กับคุณสมบัติเดียวกัน นอกจากนี้ยังมีประโยชน์เมื่อเราต้องการรวมภาพเคลื่อนไหวเข้ากับค่าคุณสมบัติคงที่ ตัวอย่างเช่น หากเรามีองค์ประกอบที่ใช้คุณสมบัติการแปลเพื่อวางตำแหน่งในตำแหน่งที่เราต้องการ และจากนั้นเราต้องการทำให้องค์ประกอบนั้นเคลื่อนไหวด้วยคีย์เฟรม kf-slide-in เราจะเห็นการกระโดดที่มองเห็นได้อย่างน่ารังเกียจโดยไม่ต้องมีองค์ประกอบภาพเคลื่อนไหว ดูโทเค็นคีย์เฟรมปากกา - การสาธิต 9 [แยก] โดย Amit Sheen ด้วยการตั้งค่าองค์ประกอบแอนิเมชั่นที่จะเพิ่ม แอนิเมชั่นจะรวมเข้ากับแอนิเมชันที่มีอยู่ได้อย่างราบรื่นเปลี่ยนรูป เพื่อให้องค์ประกอบคงอยู่กับที่และเคลื่อนไหวตามที่คาดไว้ แอนิเมชั่นซวนเซ อีกวิธีในการจัดการภาพเคลื่อนไหวหลายรายการคือการ "เดินโซเซ" ภาพเคลื่อนไหวเหล่านั้น กล่าวคือ เริ่มภาพเคลื่อนไหวที่สองหลังจากภาพเคลื่อนไหวแรกเสร็จสิ้นเล็กน้อย ไม่ใช่วิธีแก้ปัญหาที่เหมาะกับทุกกรณี แต่จะมีประโยชน์เมื่อเรามีแอนิเมชั่นทางเข้าตามด้วยแอนิเมชั่นต่อเนื่อง /* จางลง + ชีพจรทึบ */ .การแจ้งเตือน { แอนิเมชั่น: kf-fade-in 2s คลายออก kf-pulse 0.5s 2s ความสะดวกเข้า - ออกสลับไม่สิ้นสุด; --kf-ชีพจร-ความทึบถึง: 0.5; }
ดูโทเค็นคีย์เฟรมปากกา - การสาธิต 10 [แยก] โดย Amit Sheen เรื่องการสั่งซื้อ แอนิเมชันส่วนใหญ่ที่เราทำงานด้วยใช้คุณสมบัติการแปลง ในกรณีส่วนใหญ่ วิธีนี้จะสะดวกกว่า นอกจากนี้ยังมีข้อได้เปรียบด้านประสิทธิภาพเนื่องจากแอนิเมชั่นการแปลงสามารถเร่งด้วย GPU ได้ แต่ถ้าเราใช้การแปลงรูป เราต้องยอมรับว่าลำดับที่เราดำเนินการแปลงมีความสำคัญ มาก. ในคีย์เฟรมของเราจนถึงตอนนี้ เราได้ใช้การแปลงแบบเดี่ยวๆ ตามข้อกำหนด สิ่งเหล่านี้จะถูกนำไปใช้ในลำดับคงที่เสมอ โดยขั้นแรก องค์ประกอบจะได้รับการแปล จากนั้นจึงหมุน จากนั้นจึงปรับขนาด สิ่งนี้สมเหตุสมผลและเป็นสิ่งที่เราส่วนใหญ่คาดหวัง อย่างไรก็ตาม หากเราใช้คุณสมบัติการแปลง ลำดับในการเขียนฟังก์ชันจะเป็นลำดับที่ฟังก์ชันเหล่านั้นถูกนำไปใช้ ในกรณีนี้ ถ้าเราย้ายบางสิ่งบางอย่าง 100 พิกเซลบนแกน X แล้วหมุนไป 45 องศา จะไม่เหมือนกับการหมุนครั้งแรก 45 องศาแล้วเลื่อนไป 100 พิกเซล /* สี่เหลี่ยมสีชมพู: แปลก่อนแล้วจึงหมุน */ .ตัวอย่างหนึ่ง { แปลงร่าง: แปลX(100px) หมุน(45deg); }
/* สี่เหลี่ยมสีเขียว: หมุนก่อนแล้วจึงแปล */ .ตัวอย่าง-สอง { แปลงร่าง: หมุน (45deg) แปล X (100px); }
ดูโทเค็นคีย์เฟรมปากกา - การสาธิต 11 [แยก] โดย Amit Sheen แต่ตามลำดับการแปลง การแปลงแต่ละรายการ — ทุกสิ่งที่เราใช้สำหรับโทเค็นคีย์เฟรม — จะเกิดขึ้นก่อนฟังก์ชันการแปลง นั่นหมายความว่าทุกสิ่งที่คุณตั้งค่าในคุณสมบัติการแปลงจะเกิดขึ้นหลังจากภาพเคลื่อนไหว แต่หากคุณตั้งค่า เช่น แปลร่วมกับคีย์เฟรม kf-spin การแปลจะเกิดขึ้นก่อนภาพเคลื่อนไหว งงกันยัง?! สิ่งนี้นำไปสู่สถานการณ์ที่ค่าคงที่อาจทำให้เกิดผลลัพธ์ที่แตกต่างกันสำหรับภาพเคลื่อนไหวเดียวกัน เช่นในกรณีต่อไปนี้:
/* แอนิเมชั่นทั่วไปสำหรับนักปั่นทั้งสองคน */ .สปินเนอร์ { แอนิเมชัน: kf-spin 1s เชิงเส้นไม่สิ้นสุด; }
/* สปินเนอร์สีชมพู: แปลก่อนหมุน (การแปลงเดี่ยว) */ .spinner สีชมพู { แปล: 100% 50%; }
/* สปินเนอร์สีเขียว: หมุนแล้วแปล (ลำดับฟังก์ชัน) */ .สปินเนอร์สีเขียว { แปลงร่าง: แปล (100%, 50%); }
ดูโทเค็นคีย์เฟรมปากกา - การสาธิต 12 [แยก] โดย Amit Sheen คุณจะเห็นว่าสปินเนอร์ตัวแรก (สีชมพู) ได้รับการแปลที่เกิดขึ้นก่อนการหมุนของ kf-spin ดังนั้นมันจึงเคลื่อนที่ไปที่ตำแหน่งนั้นก่อนแล้วจึงหมุน สปินเนอร์ตัวที่สอง (สีเขียว) ได้รับฟังก์ชัน Translate() ที่เกิดขึ้นหลังจากการแปลงแต่ละครั้ง ดังนั้นองค์ประกอบจะหมุนก่อน จากนั้นจึงเคลื่อนที่โดยสัมพันธ์กับมุมปัจจุบัน และเราจะได้เอฟเฟกต์วงโคจรกว้างนั้น ไม่ นี่ไม่ใช่จุดบกพร่อง นี่เป็นเพียงหนึ่งในสิ่งที่เราจำเป็นต้องรู้เกี่ยวกับ CSS และโปรดคำนึงถึงเมื่อทำงานกับภาพเคลื่อนไหวหลายรายการหรือการแปลงหลายรายการ หากจำเป็น คุณสามารถสร้างชุดคีย์เฟรม kf-spin-alt เพิ่มเติมที่หมุนองค์ประกอบโดยใช้ฟังก์ชันหมุน () ได้ ลดการเคลื่อนไหว และในขณะที่เรากำลังพูดถึงคีย์เฟรมทางเลือก เราไม่สามารถเพิกเฉยต่อตัวเลือก "ไม่มีภาพเคลื่อนไหว" ได้ ข้อดีที่ใหญ่ที่สุดประการหนึ่งของการใช้โทเค็นคีย์เฟรมคือความสามารถในการเข้าถึงสามารถนำเข้ามาได้ และจริงๆ แล้วมันค่อนข้างง่ายที่จะทำ ด้วยการออกแบบคีย์เฟรมโดยคำนึงถึงความสามารถในการเข้าถึง เราจึงมั่นใจได้ว่าผู้ใช้ที่ต้องการการเคลื่อนไหวที่น้อยลงจะได้รับประสบการณ์ที่ราบรื่นขึ้น และรบกวนสมาธิน้อยลง โดยไม่ต้องทำงานเพิ่มเติมหรือทำซ้ำโค้ด ความหมายที่แท้จริงของ “Reduced Motion” สามารถเปลี่ยนได้เล็กน้อยจากแอนิเมชันหนึ่งไปอีกแอนิเมชัน และจากโปรเจ็กต์หนึ่งไปอีกโปรเจ็กต์ แต่นี่คือประเด็นสำคัญบางประการที่ควรคำนึงถึง: การปิดเสียงคีย์เฟรม แม้ว่าภาพเคลื่อนไหวบางรายการสามารถลดความเร็วลงได้ แต่ก็มีบางภาพเคลื่อนไหวที่ควรหายไปโดยสิ้นเชิงเมื่อมีการร้องขอให้ลดการเคลื่อนไหวลง ภาพเคลื่อนไหวแบบพัลส์เป็นตัวอย่างที่ดี เพื่อให้แน่ใจว่าภาพเคลื่อนไหวเหล่านี้จะไม่ทำงานในโหมดลดการเคลื่อนไหว เราสามารถรวมภาพเคลื่อนไหวเหล่านี้ไว้ในคิวรีสื่อที่เหมาะสมได้
@media (ชอบลดการเคลื่อนไหว: ไม่มีการตั้งค่า) { @keyfrmaes kf-ชีพจร { จาก { สเกล: var(--kf-pulse-scale-from, 1); ความทึบ: var(--kf-pulse-opacity-from, 1); } ถึง { ขนาด: var (--kf-pulse-scale-to, 1); ความทึบ:var(--kf-ชีพจร-ทึบ-to, 1); } } }
เพื่อให้แน่ใจว่าผู้ใช้ที่ตั้งค่าการลดการเคลื่อนไหวที่ต้องการเพื่อลดจะไม่เห็นภาพเคลื่อนไหวและจะได้รับประสบการณ์ที่ตรงกับความต้องการของตน เข้าทันที มีคีย์เฟรมบางส่วนที่เราไม่สามารถลบออกได้ง่ายๆ เช่น ภาพเคลื่อนไหวทางเข้า ค่าจะต้องเปลี่ยนแปลง ต้องเคลื่อนไหว มิฉะนั้นองค์ประกอบจะไม่มีค่าที่ถูกต้อง แต่ในการเคลื่อนไหวที่ลดลง การเปลี่ยนจากค่าเริ่มต้นควรเกิดขึ้นทันที เพื่อให้บรรลุเป้าหมายนี้ เราจะกำหนดชุดคีย์เฟรมเพิ่มเติมโดยที่ค่าจะข้ามไปยังสถานะสิ้นสุดทันที สิ่งเหล่านี้กลายเป็นคีย์เฟรมเริ่มต้นของเรา จากนั้น เราจะเพิ่มคีย์เฟรมปกติภายในคิวรี่สื่อสำหรับการตั้งค่าการตั้งค่าแบบลดการเคลื่อนไหวให้เป็นแบบไม่มีการตั้งค่า เช่นเดียวกับในตัวอย่างก่อนหน้านี้ /* เด้งเข้ามาทันทีเพื่อลดการเคลื่อนไหว */ @keyframes kf-zoom { จาก, ถึง { สเกล: var(--kf-zoom-to, 1); } }
@media (ชอบลดการเคลื่อนไหว: ไม่มีการตั้งค่า) { /* คีย์เฟรมการซูมดั้งเดิม */ @keyframes kf-zoom { จาก { สเกล: var(--kf-zoom-from, 0.8); } ถึง { สเกล: var(--kf-zoom-to, 1); } } }
ด้วยวิธีนี้ ผู้ใช้ที่ต้องการลดการเคลื่อนไหวจะเห็นองค์ประกอบปรากฏขึ้นทันทีในสถานะสุดท้าย ในขณะที่คนอื่นๆ จะได้รับการเปลี่ยนภาพเคลื่อนไหว แนวทางที่นุ่มนวล มีหลายกรณีที่เราต้องการคงการเคลื่อนไหวไว้ แต่นุ่มนวลและสงบกว่าแอนิเมชั่นต้นฉบับมาก ตัวอย่างเช่น เราสามารถแทนที่ทางเข้าที่เด้งกลับด้วยการค่อยๆ จางลงได้
@keyframes kf-เด้ง { /* เฟดเข้าอย่างนุ่มนวลเพื่อลดการเคลื่อนไหว */ }
@media (ชอบลดการเคลื่อนไหว: ไม่มีการตั้งค่า) { @keyframes kf-เด้ง { /* คีย์เฟรมการตีกลับดั้งเดิม */ } }
ขณะนี้ ผู้ใช้ที่เปิดใช้งานการลดการเคลื่อนไหวจะยังคงสัมผัสได้ถึงรูปลักษณ์ภายนอก แต่ไม่มีการเคลื่อนไหวที่รุนแรงของการตีกลับหรือแอนิเมชั่นแบบยืดหยุ่น เมื่อมีแบบเอกสารสำเร็จรูปแล้ว คำถามต่อไปคือจะทำให้เป็นส่วนหนึ่งของเวิร์กโฟลว์จริงได้อย่างไร การเขียนคีย์เฟรมที่ยืดหยุ่นก็เรื่องหนึ่ง แต่การทำให้คีย์เฟรมเหล่านี้เชื่อถือได้ในโปรเจ็กต์ขนาดใหญ่นั้นต้องใช้กลยุทธ์บางอย่างที่ฉันต้องเรียนรู้อย่างหนัก กลยุทธ์การดำเนินงานและแนวทางปฏิบัติที่ดีที่สุด เมื่อเรามีคลังโทเค็นคีย์เฟรมที่มั่นคงแล้ว ความท้าทายที่แท้จริงก็คือการนำโทเค็นเหล่านั้นมาสู่การทำงานในแต่ละวัน
สิ่งล่อใจคือการทิ้งคีย์เฟรมทั้งหมดพร้อมกันและประกาศว่าปัญหาได้รับการแก้ไขแล้ว แต่ในทางปฏิบัติ ฉันพบว่าผลลัพธ์ที่ดีที่สุดมาจากการนำไปใช้อย่างค่อยเป็นค่อยไป เริ่มต้นด้วยภาพเคลื่อนไหวที่พบบ่อยที่สุด เช่น การจางหายหรือสไลด์ นี่เป็นชัยชนะง่ายๆ ที่แสดงมูลค่าทันทีโดยไม่ต้องเขียนซ้ำจำนวนมาก การตั้งชื่อเป็นอีกจุดที่สมควรได้รับความสนใจ คำนำหน้าหรือเนมสเปซที่สอดคล้องกันทำให้ชัดเจนว่าแอนิเมชันใดเป็นโทเค็นและอันใดเป็นแบบที่เกิดขึ้นครั้งเดียวในเครื่อง นอกจากนี้ยังป้องกันการชนกันโดยไม่ได้ตั้งใจและช่วยให้สมาชิกในทีมใหม่จดจำระบบที่ใช้ร่วมกันได้อย่างรวดเร็ว เอกสารประกอบมีความสำคัญพอๆ กับโค้ดเอง แม้แต่ความคิดเห็นสั้นๆ เหนือโทเค็นคีย์เฟรมแต่ละรายการก็สามารถช่วยประหยัดเวลาในการคาดเดาในภายหลังได้ นักพัฒนาควรสามารถเปิดไฟล์โทเค็น สแกนหาเอฟเฟกต์ที่ต้องการ และคัดลอกรูปแบบการใช้งานลงในส่วนประกอบของตนได้โดยตรง ความยืดหยุ่นคือสิ่งที่ทำให้แนวทางนี้คุ้มค่ากับความพยายาม ด้วยการเปิดเผยคุณสมบัติแบบกำหนดเองที่สมเหตุสมผล เราให้พื้นที่ทีมในการปรับแอนิเมชั่นโดยไม่ทำลายระบบ ในขณะเดียวกัน พยายามอย่าทำให้ซับซ้อนเกินไป จัดเตรียมปุ่มที่สำคัญและเก็บความคิดเห็นที่เหลือไว้ สุดท้ายนี้ จำการเข้าถึงได้ ไม่ใช่ทุกแอนิเมชั่นที่ต้องการทางเลือกในการลดการเคลื่อนไหว แต่หลายแอนิเมชั่นต้องการ การอบการปรับเปลี่ยนเหล่านี้แต่เนิ่นๆ หมายความว่าเราไม่ต้องดัดแปลงใหม่ในภายหลัง และแสดงให้เห็นระดับความเอาใจใส่ที่ผู้ใช้ของเราจะสังเกตเห็นแม้ว่าพวกเขาจะไม่เคยพูดถึงก็ตาม
จากประสบการณ์ของผม การใช้โทเค็นคีย์เฟรมเป็นส่วนหนึ่งของเวิร์กโฟลว์โทเค็นการออกแบบของเราคือสิ่งที่ทำให้โทเค็นติดอยู่ เมื่อเข้าที่แล้ว พวกเขาจะหยุดรู้สึกเหมือนเป็นเอฟเฟกต์พิเศษและกลายเป็นส่วนหนึ่งของภาษาการออกแบบ ซึ่งเป็นส่วนขยายตามธรรมชาติของการเคลื่อนไหวและการตอบสนองของผลิตภัณฑ์ ห่อขึ้น แอนิเมชั่นอาจเป็นหนึ่งในส่วนที่สนุกสนานที่สุดของการสร้างอินเทอร์เฟซ แต่หากไม่มีโครงสร้าง แอนิเมชันก็สามารถกลายเป็นหนึ่งในสาเหตุหลักของความหงุดหงิดได้ ด้วยการปฏิบัติต่อคีย์เฟรมเสมือนเป็นโทเค็น คุณจะนำสิ่งที่มักจะยุ่งเหยิงและยากต่อการจัดการมาเปลี่ยนให้กลายเป็นระบบที่ชัดเจนและคาดเดาได้ มูลค่าที่แท้จริงไม่ได้อยู่ที่การบันทึกโค้ดเพียงไม่กี่บรรทัดเท่านั้น ด้วยความมั่นใจว่าเมื่อคุณใช้การเฟด สไลด์ ซูม หรือหมุน คุณจะรู้ได้อย่างชัดเจนว่ามันจะทำงานอย่างไรทั่วทั้งโปรเจ็กต์ อยู่ในความยืดหยุ่นที่มาจากคุณสมบัติที่กำหนดเองโดยไม่มีความสับสนวุ่นวายของรูปแบบที่ไม่มีที่สิ้นสุด และมันอยู่ในความสามารถในการเข้าถึงที่สร้างไว้ในรากฐานแทนที่จะเพิ่มเป็นภายหลัง ฉันได้เห็นแนวคิดเหล่านี้ทำงานในทีมและโค้ดเบสที่แตกต่างกัน และรูปแบบก็เหมือนกันเสมอ เมื่อโทเค็นเข้าที่แล้ว คีย์เฟรมจะหยุดเป็นคอลเลกชั่นลูกเล่นที่กระจัดกระจายและกลายเป็นส่วนหนึ่งของภาษาการออกแบบ ทำให้ผลิตภัณฑ์มีความตั้งใจมากขึ้น มีความสม่ำเสมอมากขึ้น และมีชีวิตชีวามากขึ้น หากคุณนำสิ่งหนึ่งจากบทความนี้ ปล่อยให้เป็นดังนี้: แอนิเมชั่นสมควรได้รับการดูแลและโครงสร้างแบบเดียวกับที่เรามอบให้กับสี การพิมพ์ และการเว้นวรรค การลงทุนเพียงเล็กน้อยในโทเค็นคีย์เฟรมจะให้ผลตอบแทนทุกครั้งที่อินเทอร์เฟซของคุณเคลื่อนไหว