CSS Infinite 3D Sliders PlatoBlockchain ข้อมูลอัจฉริยะ ค้นหาแนวตั้ง AI.

ตัวเลื่อน 3D CSS Infinite

ในชุดนี้เราทำแถบเลื่อนรูปภาพโดยไม่มีอะไรนอกจาก HTML และ CSS แนวคิดคือเราสามารถใช้มาร์กอัปเดียวกันแต่ใช้ CSS ต่างกันเพื่อให้ได้ผลลัพธ์ที่แตกต่างกันอย่างมาก ไม่ว่าเราจะใส่รูปภาพกี่รูปก็ตาม เราเริ่มด้วยแถบเลื่อนวงกลมที่หมุนได้ไม่รู้จบ คล้ายกับตัวหมุนที่อยู่ไม่สุขที่เก็บรูปภาพ จากนั้นเราก็สร้างภาพที่พลิกดูกองภาพถ่าย

คราวนี้เรากำลังดำดิ่งสู่มิติที่สาม ในตอนแรกจะดูยาก แต่โค้ดจำนวนมากที่เรากำลังดูนั้นตรงกับสิ่งที่เราใช้ในสองบทความแรกในซีรีส์นี้ โดยมีการปรับเปลี่ยนบางอย่าง ดังนั้น หากคุณเพิ่งเข้าสู่ซีรีส์นี้ ฉันขอแนะนำให้ตรวจสอบเนื้อหาอื่นๆ เกี่ยวกับแนวคิดที่เราใช้ที่นี่

ชุดตัวเลื่อน CSS

นี่คือสิ่งที่เราตั้งเป้าไว้:

เมื่อมองแวบแรก ดูเหมือนว่าเรามีลูกบาศก์หมุนที่มีสี่ภาพ แต่ในความเป็นจริง เรากำลังจัดการกับภาพทั้งหมดหกภาพ นี่คือแถบเลื่อนจากมุมอื่น:

ตอนนี้เรามีภาพที่ดีสำหรับการจัดเรียงภาพแล้ว เรามาแยกรหัสเพื่อดูว่าเราไปถึงที่นั่นได้อย่างไร

การตั้งค่าพื้นฐาน

HTML เดียวกันกับแถบเลื่อนที่เหลือที่เราใช้กับแถบเลื่อนอื่นๆ:

และอีกครั้ง เรากำลังใช้ CSS Grid เพื่อวางภาพในสแต็ก โดยวางซ้อนกัน:

.gallery {
  display: grid;
}
.gallery > img {
  grid-area: 1 / 1;
  width: 160px;
  aspect-ratio: 1;
  object-fit: cover;
}

แอนิเมชั่น

ตรรกะสำหรับแถบเลื่อนนี้คล้ายกับ แถบเลื่อนวงกลมจากบทความแรก. ในความเป็นจริง หากคุณตรวจสอบวิดีโอด้านบนอีกครั้ง คุณจะเห็นว่าภาพถูกวางในลักษณะที่สร้างรูปหลายเหลี่ยม หลังจากหมุนครบแล้ว จะกลับไปที่ภาพแรก

เราพึ่งพา CSS transform-origin และ animation-delay คุณสมบัติสำหรับแถบเลื่อนแรกนั้น ภาพเคลื่อนไหวเดียวกันนี้ใช้กับองค์ประกอบภาพทั้งหมด ซึ่งหมุนรอบจุดเดียวกัน จากนั้น ด้วยการใช้การหน่วงเวลาที่ต่างกัน เราจะวางภาพทั้งหมดรอบวงกลมขนาดใหญ่ได้อย่างถูกต้อง

การใช้งานจะแตกต่างกันเล็กน้อยสำหรับแถบเลื่อน 3 มิติของเรา โดยใช้ transform-origin จะไม่ทำงานที่นี่เพราะเรากำลังทำงานใน 3D ดังนั้นเราจะใช้ transform แทนที่จะวางภาพทั้งหมดให้ถูกต้อง จากนั้นหมุนคอนเทนเนอร์

เรากำลังติดต่อ Sass อีกครั้งเพื่อให้เราสามารถวนซ้ำจำนวนภาพและใช้การแปลงของเรา:

@for $i from 1 to ($n + 1) {
  .gallery > img:nth-child(#{$i}) {
     transform: 
       rotate(#{360*($i - 1) / $n}deg) /* 1 */
       translateY(50% / math.tan(180deg / $n)) /* 2 */ 
       rotateX(90deg); /* 3 */
  }
}

คุณอาจสงสัยว่าทำไมเราถึงกระโดดเข้าหา Sass โดยตรง เราเริ่มต้นด้วยจำนวนรูปภาพที่แน่นอนโดยใช้วานิลลา CSS ในบทความอื่นๆ ก่อนที่จะสรุปรหัสด้วย Sass เพื่อพิจารณาจำนวนใดๆ (N) ของรูปภาพ ฉันคิดว่าคุณคงเข้าใจความคิดแล้ว และเราสามารถตัดงานการค้นพบทั้งหมดนั้นออกเพื่อนำไปใช้งานจริงได้

พื้นที่ transform คุณสมบัติมีค่าสามค่าซึ่งฉันได้แสดงไว้ที่นี่:

ตัวเลื่อน 3D CSS Infinite

ก่อนอื่นเราหมุนภาพทั้งหมดที่อยู่ด้านบนกัน มุมของการหมุนขึ้นอยู่กับจำนวนภาพ สำหรับ N ภาพเราเพิ่มขึ้นเท่ากับ 360deg/N. ถ้าอย่างนั้นเรา translate ภาพทั้งหมดด้วยจำนวนที่เท่ากันในลักษณะที่ทำให้จุดกึ่งกลางบรรจบกันที่ด้านข้าง

แสดงภาพซ้อนเรียงกันเป็นวงกลมโดยมีเส้นสีแดงพาดผ่านจุดกึ่งกลางภาพ
ตัวเลื่อน 3D CSS Infinite

มีรูปทรงเรขาคณิตที่น่าเบื่อบางอย่างที่ช่วยอธิบายวิธีการทำงานทั้งหมดนี้ แต่ระยะทางเท่ากับ 50%/tan(180deg/N). เราจัดการกับสมการที่คล้ายกันเมื่อสร้างแถบเลื่อนวงกลม ( transform-origin: 50% 50%/sin(180deg/N) ).

สุดท้าย เราหมุนภาพรอบแกน x โดย 90deg เพื่อให้ได้การจัดที่เราต้องการ นี่คือวิดีโอที่แสดงให้เห็นว่าการหมุนเวียนครั้งล่าสุดเป็นอย่างไร:

ตอนนี้สิ่งที่เราต้องทำคือหมุนคอนเทนเนอร์ทั้งหมดเพื่อสร้างแถบเลื่อนที่ไม่มีที่สิ้นสุดของเรา

.gallery {
  transform-style: preserve-3d;
  --_t: perspective(280px) rotateX(-90deg);
  animation: r 12s cubic-bezier(.5, -0.2, .5, 1.2) infinite;
}
@keyframes r {
  0%, 3% {transform: var(--_t) rotate(0deg); }
  @for $i from 1 to $n {
    #{($i/$n)*100 - 2}%, 
    #{($i/$n)*100 + 3}% {
      transform: var(--_t) rotate(#{($i / $n) * -360}deg);
    }  
  }
  98%, 100% { transform: var(--_t) rotate(-360deg); }
}

โค้ดนั้นอาจเข้าใจยาก ดังนั้นเรามาย้อนกลับไปดูแอนิเมชันที่เราสร้างสำหรับแถบเลื่อนวงกลมกันอีกครั้ง นี่คือสิ่งที่เราเขียนไว้ในบทความแรก:

.gallery {
  animation: m 12s cubic-bezier(.5, -0.2, .5, 1.2) infinite;
}
@keyframes m {
  0%, 3% { transform: rotate(0); }
  @for $i from 1 to $n {
    #{($i / $n) * 100 - 2}%,
    #{($i / $n) * 100 + 3}% { 
      transform: rotate(#{($i / $n) * -360}deg);
    }  
  }
  98%, 100% { transform: rotate(-360deg); }
}

คีย์เฟรมเกือบจะเหมือนกัน เรามีค่าเปอร์เซ็นต์เท่ากัน วงเดียวกัน และการหมุนรอบเดียวกัน

ทำไมเหมือนกันทั้งคู่ เพราะตรรกะของพวกเขาเหมือนกัน ในทั้งสองกรณี รูปภาพถูกจัดเรียงเป็นรูปวงกลม และเราจำเป็นต้องหมุนทั้งหมดเพื่อแสดงแต่ละภาพ นั่นเป็นวิธีที่ฉันสามารถคัดลอกคีย์เฟรมจากแถบเลื่อนวงกลมและใช้รหัสเดียวกันนั้นสำหรับแถบเลื่อน 3 มิติของเรา ข้อแตกต่างเพียงอย่างเดียวคือเราต้องหมุนภาชนะตาม -90deg ตามแนวแกน x เพื่อดูภาพ เนื่องจากเราหมุนไปแล้ว 90deg บนแกนเดียวกัน จากนั้นเราเพิ่มสัมผัสของ perspective เพื่อให้ได้เอฟเฟ็กต์ 3 มิติ

แค่นั้นแหละ! สไลเดอร์ของเราเสร็จแล้ว นี่คือการสาธิตแบบเต็มอีกครั้ง สิ่งที่คุณต้องทำคือเพิ่มรูปภาพได้มากเท่าที่คุณต้องการและอัปเดตตัวแปรหนึ่งตัวเพื่อดำเนินการต่อ

แถบเลื่อน 3 มิติแนวตั้ง

เนื่องจากเรากำลังเล่นในพื้นที่ 3 มิติ ทำไมไม่ลองสร้างแถบเลื่อนรุ่นก่อนหน้าในแนวตั้งดูล่ะ อันสุดท้ายหมุนไปตามแกน z แต่เราสามารถเลื่อนไปตามแกน x ได้หากต้องการ

หากคุณเปรียบเทียบโค้ดของแถบเลื่อนนี้ทั้งสองเวอร์ชัน คุณอาจไม่เห็นความแตกต่างในทันทีเพราะเป็นอักขระเพียงตัวเดียว! ฉันแทนที่ rotate() กับ rotateX() ภายในคีย์เฟรมและรูปภาพ transform. แค่นั้นแหละ!

ควรสังเกตว่า rotate() เทียบเท่ากับ rotateZ()ดังนั้น โดยการเปลี่ยนแกนจาก Z ไปยัง X เราเปลี่ยนแถบเลื่อนจากแนวนอนเป็นแนวตั้ง

ตัวเลื่อนลูกบาศก์

เราไม่สามารถพูดถึง 3D ใน CSS ได้หากไม่มี พูดถึงลูกบาศก์. และใช่ นั่นหมายความว่าเรากำลังจะสร้างแถบเลื่อนอีกเวอร์ชันหนึ่ง

แนวคิดเบื้องหลังแถบเลื่อนเวอร์ชันนี้คือการสร้างรูปทรงลูกบาศก์จริงพร้อมรูปภาพและหมุนสิ่งที่เต็มไปรอบๆ แกนต่างๆ เนื่องจากมันเป็นลูกบาศก์ เราจึงต้องเผชิญกับหกหน้า เราจะใช้ภาพหกภาพ หนึ่งภาพสำหรับแต่ละหน้าของลูกบาศก์ ดังนั้นไม่ใช่ Sass แต่กลับไปที่วานิลลา CSS

อนิเมชั่นนั้นค่อนข้างล้นหลามใช่ไหม คุณจะเริ่มต้นที่ไหน

เรามีหกหน้า ดังนั้นเราต้องทำการหมุนอย่างน้อยหกครั้งเพื่อให้แต่ละภาพได้รับการหมุน อันที่จริง เราต้องการการหมุนห้ารอบ — อันสุดท้ายจะนำเรากลับไปที่ใบหน้ารูปแรก ถ้าคุณไปคว้าลูกบาศก์รูบิค — หรือวัตถุรูปทรงลูกบาศก์อื่น ๆ เช่น ลูกเต๋า — แล้วหมุนมันด้วยมือของคุณ คุณจะมีความคิดที่ดีว่าเรากำลังทำอะไรอยู่

.gallery {
  --s: 250px; /* the size */

  transform-style: preserve-3d;
  --_p: perspective(calc(2.5*var(--s)));
  animation: r 9s infinite cubic-bezier(.5, -0.5, .5, 1.5);
}

@keyframes r {
  0%, 3%   { transform: var(--_p); }
  14%, 19% { transform: var(--_p) rotateX(90deg); }
  31%, 36% { transform: var(--_p) rotateX(90deg) rotateZ(90deg); }
  47%, 52% { transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg); }
  64%, 69% { transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg) rotateX(90deg); }
  81%, 86% { transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg) rotateX(90deg) rotateZ(90deg); }
  97%, 100%{ transform: var(--_p) rotateX(90deg) rotateZ(90deg) rotateY(-90deg) rotateX(90deg) rotateZ(90deg) rotateY(-90deg); }
}

พื้นที่ transform คุณสมบัติเริ่มต้นด้วยการหมุนเป็นศูนย์ และในแต่ละสถานะ เราจะเพิ่มการหมุนใหม่บนแกนใดแกนหนึ่งจนกระทั่งเราหมุนครบหกรอบ จากนั้นเราจะกลับไปที่ภาพแรก

อย่าลืมตำแหน่งของภาพของเรา แต่ละอันถูกนำไปใช้กับใบหน้าของลูกบาศก์โดยใช้ transform:

.gallery img {
  grid-area: 1 / 1;
  width: var(--s);
  aspect-ratio: 1;
  object-fit: cover;
  transform: var(--_t,) translateZ(calc(var(--s) / 2));
}
.gallery img:nth-child(2) { --_t: rotateX(-90deg); }
.gallery img:nth-child(3) { --_t: rotateY( 90deg) rotate(-90deg); }
.gallery img:nth-child(4) { --_t: rotateX(180deg) rotate( 90deg); }
.gallery img:nth-child(5) { --_t: rotateX( 90deg) rotate( 90deg); }
.gallery img:nth-child(6) { --_t: rotateY(-90deg); }

คุณอาจคิดว่ามีตรรกะที่ซับซ้อนแปลกๆ อยู่เบื้องหลังค่าที่ฉันใช้อยู่ใช่ไหม ก็ไม่ ทั้งหมดที่ฉันทำคือเปิด DevTools และเล่นกับค่าการหมุนที่แตกต่างกันสำหรับแต่ละภาพจนกว่าฉันจะทำได้ถูกต้อง อาจฟังดูงี่เง่า แต่เดี๋ยวก่อน มันได้ผล — โดยเฉพาะอย่างยิ่งเมื่อเรามีจำนวนภาพที่แน่นอน และเราไม่ได้มองหาสิ่งที่รองรับ N ภาพ

อันที่จริง ลืมค่าต่างๆ ที่ฉันใช้อยู่และพยายามจัดตำแหน่งด้วยตัวคุณเองในแบบฝึกหัด เริ่มจากนำภาพทั้งหมดมาซ้อนกัน เปิด DevTools แล้วไปกันเลย! คุณอาจจะลงเอยด้วยรหัสอื่นซึ่งก็ไม่เป็นไร การวางตำแหน่งรูปภาพอาจมีหลายวิธี

เคล็ดลับกับเครื่องหมายจุลภาคใน var()? มันเป็นการพิมพ์ผิด?

มันไม่ใช่การพิมพ์ผิด ดังนั้นอย่าลบออก! หากคุณลบออก คุณจะสังเกตเห็นว่ามีผลกับตำแหน่งของภาพแรก คุณจะเห็นว่าในรหัสของฉันที่ฉันกำหนดไว้ --_t สำหรับภาพทั้งหมดยกเว้นภาพแรกเพราะฉันต้องการคำแปลเท่านั้น เครื่องหมายจุลภาคนั้นทำให้ตัวแปรถอยกลับไปเป็นค่าว่าง หากไม่มีเครื่องหมายจุลภาค เราจะไม่มีทางเลือกสำรองและค่าทั้งหมดจะไม่ถูกต้อง

จาก ข้อมูลจำเพาะ:

หมายเหตุ: นั่นคือ var(--a,) เป็นฟังก์ชันที่ถูกต้อง โดยระบุว่า ถ้า --a คุณสมบัติที่กำหนดเองไม่ถูกต้องหรือหายไป, the var()` ควรจะแทนที่ด้วยอะไร

ตัวเลื่อนลูกบาศก์แบบสุ่ม

การสุ่มเล็กน้อยอาจเป็นส่วนเสริมที่ดีสำหรับแอนิเมชันประเภทนี้ ดังนั้น แทนที่จะหมุนลูกบาศก์ตามลำดับ เราสามารถทอยลูกเต๋าได้ตามที่พูด และปล่อยให้ลูกบาศก์หมุนไปตามทิศทางของมัน

เย็นใช่มั้ย? ฉันไม่รู้เกี่ยวกับคุณ แต่ฉันชอบเวอร์ชั่นนี้มากกว่า! มันน่าสนใจกว่าและช่วงการเปลี่ยนภาพก็น่าพอใจที่จะดู และคาดเดาอะไร คุณสามารถเล่นกับค่าต่าง ๆ เพื่อสร้างตัวเลื่อนคิวบ์แบบสุ่มของคุณเอง!

ตรรกะนั้นไม่ได้เกิดขึ้นจริงโดยบังเอิญเลย — มันดูเหมือนเป็นอย่างนั้น คุณกำหนดก transform ในแต่ละคีย์เฟรมที่ให้คุณแสดงใบหน้าเดียว และ... ก็แค่นั้นจริงๆ! คุณสามารถเลือกคำสั่งใด ๆ ที่คุณต้องการ

@keyframes r {
  0%, 3%   { transform: var(--_p) rotate3d( 0, 0, 0,  0deg); }
  14%,19%  { transform: var(--_p) rotate3d(-1, 1, 0,180deg); }
  31%,36%  { transform: var(--_p) rotate3d( 0,-1, 0, 90deg); }
  47%,52%  { transform: var(--_p) rotate3d( 1, 0, 0, 90deg); }
  64%,69%  { transform: var(--_p) rotate3d( 1, 0, 0,-90deg); }
  81%,86%  { transform: var(--_p) rotate3d( 0, 1, 0, 90deg); }
  97%,100% { transform: var(--_p) rotate3d( 0, 0, 0,  0deg); }
}

ฉันใช้ rotate3d() ครั้งนี้ แต่ฉันยังคงพึ่งพา DevTools เพื่อค้นหาค่าที่รู้สึกว่า "ใช่" สำหรับฉัน อย่าพยายามค้นหาความสัมพันธ์ระหว่างคีย์เฟรมเพราะไม่มีเลย ฉันกำลังกำหนดการแปลงแยกกันแล้วดูผลลัพธ์ "สุ่ม" ตรวจสอบให้แน่ใจว่าภาพแรกคือเฟรมแรกและเฟรมสุดท้ายตามลำดับ และแสดงรูปภาพที่แตกต่างกันในแต่ละเฟรมอื่นๆ

คุณไม่จำเป็นต้องใช้ rotate3d() แปลงร่างเหมือนที่ฉันทำ คุณยังสามารถเชื่อมโยงการหมุนต่างๆ เข้าด้วยกันได้เหมือนกับที่เราทำในตัวอย่างที่แล้ว เล่นไปรอบ ๆ และดูว่าคุณสามารถทำอะไรได้บ้าง! ฉันจะรอให้คุณแบ่งปันเวอร์ชันของคุณกับฉันในส่วนความคิดเห็น!

ตัดขึ้น

ฉันหวังว่าคุณจะสนุกกับซีรีส์เล็ก ๆ นี้ เราสร้างแถบเลื่อนที่สนุก (และตลก) ในขณะที่เรียนรู้มากมายเกี่ยวกับแนวคิด CSS ทุกประเภทไปพร้อมกัน ตั้งแต่การวางตารางและลำดับการซ้อน ไปจนถึงการหน่วงเวลาและการแปลงภาพเคลื่อนไหว เรายังต้องเล่นกับ Sass เพื่อวนซ้ำองค์ประกอบต่างๆ

และเราทำทั้งหมดนี้ด้วย HTML เดียวกันทุกประการสำหรับแถบเลื่อนแต่ละตัวที่เราสร้างขึ้น มันเจ๋งแค่ไหน? CSS นั้นทรงพลังและสามารถทำได้หลายอย่างโดยไม่ต้องใช้ JavaScript ช่วย

ประทับเวลา:

เพิ่มเติมจาก เคล็ดลับ CSS