CSS Infinite 3D Sliders PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

CSS Infinite 3D Sliders

בסדרה זו, יצרנו מחווני תמונה ללא שום דבר מלבד HTML ו-CSS. הרעיון הוא שנוכל להשתמש באותו סימון אבל ב-CSS שונה כדי לקבל תוצאות שונות מאוד, לא משנה כמה תמונות נזרוק פנימה. התחלנו עם סליידר עגול שמסתובב בלי סוף, בערך כמו ספינר שמכיל תמונות. אחר כך הכנו אחד שעובר על ערימת תמונות.

הפעם, אנחנו צוללים לתוך המימד השלישי. זה הולך להיראות קשה בהתחלה, אבל הרבה מהקוד שאנחנו מסתכלים עליו הוא בדיוק מה שהשתמשנו בשני המאמרים הראשונים בסדרה הזו, עם כמה שינויים. אז, אם אתה רק עכשיו נכנס לסדרה, הייתי מציע לבדוק את האחרים כדי לקבל הקשר לגבי המושגים שבהם אנו משתמשים כאן.

סדרת Sliders 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 מאפיינים עבור המחוון הראשון. אותה אנימציה מוחלת על כל רכיבי התמונה, המסתובבים סביב אותה נקודה. לאחר מכן, על ידי שימוש בהשהיות שונות, אנו ממקמים נכון את כל התמונות סביב עיגול גדול.

היישום יהיה קצת שונה עבור המחוון התלת מימד שלנו. באמצעות transform-origin לא יעבוד כאן כי אנחנו עובדים בתלת מימד, אז נשתמש 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 */
  }
}

אתה אולי תוהה למה אנחנו קופצים ישר לתוך סאס. התחלנו עם מספר קבוע של תמונות באמצעות וניל CSS במאמרים האחרים לפני שהכללנו את הקוד עם Sass כדי לקחת בחשבון כל מספר (N) של תמונות. ובכן, אני חושב שהבנתם את הרעיון עכשיו ונוכל להפסיק את כל עבודת הגילוי כדי להגיע ליישום האמיתי.

השמיים transform נכס לוקח שלושה ערכים, שהמחשתי כאן:

CSS Infinite 3D Sliders

ראשית, אנו מסובבים את כל התמונות זו מעל זו. זווית הסיבוב תלויה במספר התמונות. ל N תמונות, יש לנו תוספת שווה ל 360deg/N. אז אנחנו translate כל התמונות באותה כמות באופן שגורם לנקודות המרכז שלהן להיפגש בצדדים.

מראה את ערימת התמונות המסודרת שטוחה במעגל עם קו אדום העובר דרך נקודת המרכז של התמונות.
CSS Infinite 3D Sliders

יש איזו גיאומטריה משעממת שעוזרת להסביר איך כל זה עובד, אבל המרחק שווה ל 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); }
}

מסגרות המפתח כמעט זהות. יש לנו אותם ערכי אחוזים, אותה לולאה, ואותו סיבוב.

למה שניהם זהים? כי ההיגיון שלהם זהה. בשני המקרים, התמונות מסודרות סביב צורה עגולה ועלינו לסובב את כל העניין כדי להציג כל תמונה. כך הצלחתי להעתיק את ה-keyframes מהמחוון העגול ולהשתמש באותו קוד עבור המחוון התלת-ממדי שלנו. ההבדל היחיד הוא שאנחנו צריכים לסובב את המיכל על ידי -90deg לאורך ציר ה-x כדי לראות את התמונות מכיוון שכבר סובבנו אותן על ידי 90deg על אותו ציר. ואז נוסיף נגיעה של perspective כדי לקבל את אפקט התלת מימד.

זהו זה! הסליידר שלנו נעשה. הנה שוב ההדגמה המלאה. כל מה שאתה צריך לעשות הוא להוסיף כמה תמונות שאתה רוצה ולעדכן משתנה אחד כדי להפעיל אותו.

מחוון תלת מימד אנכי

מכיוון שאנו משחקים במרחב התלת-ממדי, מדוע לא ליצור גרסה אנכית של המחוון הקודם? האחרון מסתובב לאורך ציר z, אבל אנחנו יכולים גם לנוע לאורך ציר x אם נרצה.

אם אתה משווה את הקוד עבור שתי הגרסאות של המחוון הזה, ייתכן שלא תזהה מיד את ההבדל כי זה רק תו אחד! החלפתי rotate() עם rotateX() בתוך ה-keyframes והתמונה transform. זהו זה!

זה יצוין כי rotate() שווה rotateZ(), כך על ידי שינוי הציר מ Z ל X אנו הופכים את המחוון מהגרסה האופקית לגרסה האנכית.

מחוון קוביות

אנחנו לא יכולים לדבר על תלת מימד ב-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 מאפיין מותאם אישית לא חוקי או חסר, ה 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 כדי למצוא את הערכים שמרגישים לי "נכונים". אל תנסה למצוא קשר בין ה-keyframes כי פשוט אין אחד. אני מגדיר טרנספורמציות נפרדות ואז צופה בתוצאה ה"אקראית". ודא שהתמונה הראשונה היא הפריימים הראשונים והאחרונים, בהתאמה, והצג תמונה שונה על כל אחת מהפריימים האחרים.

אינך מחויב להשתמש בא rotate3d() להפוך כפי שעשיתי. אתה יכול גם לשרשר סיבובים שונים כמו שעשינו בדוגמה הקודמת. שחק ותראה מה אתה יכול להמציא! אני אחכה שתשתף אותי בגרסה שלך בקטע התגובות!

גלישה את

אני מקווה שנהניתם מהסדרה הקטנה הזו. בנינו כמה סליידרים מהנים (ומצחיקים) תוך כדי למידה רבה על כל מיני מושגי CSS לאורך הדרך - ממיקום רשת וסדר ערימה, ועד עיכובים והפיכות של אנימציה. אפילו יצא לנו לשחק עם קורטוב של Sass כדי לעבור דרך מערך אלמנטים.

ועשינו הכל עם אותו HTML בדיוק עבור כל סליידר ומחוון שיצרנו. כמה מגניב זה? CSS הוא חזק מאוד ומסוגל להשיג כל כך הרבה ללא עזרת JavaScript.

בול זמן:

עוד מ טריקים של CSS