Slider תמונה מסתובבת אינסופית ומעגלית של PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

מחוון תמונה מסתובב אינסופי ומעגלי של CSS

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

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

סדרת Sliders CSS

עבור המאמר הראשון הזה, נתחיל עם משהו שאני מכנה "מחוון תמונות מסתובב מעגלי":

מגניב נכון? בואו ננתח את הקוד!

סימון HTML

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

s ודברים אחרים.

אותו כלל חל כאן - הקוד שלנו אינו אלא רשימה של תמונות בקונטיינר.

נניח שאנו עובדים עם ארבע תמונות:

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

איך זה עובד?

הנה סרטון שבו אני מסיר overflow: hidden מה-CSS כדי שנוכל להבין טוב יותר איך התמונות זזות:

זה כאילו ארבע התמונות שלנו ממוקמות על עיגול גדול שמסתובב נגד כיוון השעון.

מחוון תמונה מסתובב אינסופי ומעגלי של CSS

לכל התמונות יש אותו גודל (מסומן ב S באיור). שימו לב למעגל הכחול שהוא המעגל שמצטלב עם מרכז כל התמונות ויש לו רדיוס (R). נצטרך את הערך הזה מאוחר יותר עבור האנימציה שלנו. R שווה ל 0.707 * S. (אני הולך לדלג על הגיאומטריה שנותנת לנו את המשוואה הזו.)

בוא נכתוב קצת CSS!

אנו נשתמש רשת CSS כדי למקם את כל התמונות באותו אזור זו מעל זו:

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

  display: grid;
  width: var(--s);
  aspect-ratio: 1;
  padding: calc(var(--s) / 20); /* we will see the utility of this later */
  border-radius: 50%;
}
.gallery > img {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
}

שום דבר מורכב מדי עד כה. החלק המסובך הוא האנימציה.

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

.gallery > img {
  /* same as before */
  animation: m 8s infinite linear;
  transform-origin: 50% 120.7%;
}

@keyframes m {
  100% { transform: rotate(-360deg); }
}

הטריק העיקרי מסתמך על הקו המודגש הזה. כברירת מחדל, ה-CSS transform-origin רכוש שווה ל- center (אוֹ 50% 50%) מה שגורם לתמונה להסתובב סביב מרכזה, אבל אנחנו לא צריכים אותה כדי לעשות זאת. אנחנו צריכים שהתמונה תסתובב סביב מרכז ה- מעגל גדול שמכיל את התמונות שלנו ומכאן הערך החדש עבור transform-origin.

מכיוון ש-R שווה ל 0.707 * S, אנחנו יכולים להגיד את זה R שווה ל 70.7% של גודל התמונה. הנה דמות שתמחיש איך קיבלנו את 120.7% ערך:

Slider תמונה מסתובבת אינסופית ומעגלית של PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.
מחוון תמונה מסתובב אינסופי ומעגלי של CSS

בוא נריץ את האנימציה ונראה מה קורה:

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

.gallery > img:nth-child(2) { animation-delay: -2s; } /* -1 * 8s / 4 */
.gallery > img:nth-child(3) { animation-delay: -4s; } /* -2 * 8s / 4 */
.gallery > img:nth-child(4) { animation-delay: -6s; } /* -3 * 8s / 4 */

המצב כבר משתפר!

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

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

@keyframes m {
  0%, 3% { transform: rotate(0); }
  22%, 27% { transform: rotate(-90deg); }
  47%, 52% { transform: rotate(-180deg); }
  72%, 77% { transform: rotate(-270deg); }
  98%, 100% { transform: rotate(-360deg); }
}

עבור כל 90deg (360deg/4, שם 4 הוא מספר התמונות) נוסיף הפסקה קטנה. כל תמונה תישאר גלויה עבור 5% של משך הזמן הכולל לפני שנגלוש לפרק הבא (27%-22%, 52%-47%, וכו.). אני הולך לעדכן את animation-timing-function באמצעות cubic-bezier() פונקציה כדי להפוך את האנימציה לקצת יותר מפוארת:

עכשיו המחוון שלנו מושלם! ובכן, כמעט מושלם כי עדיין חסר לנו המגע הסופי: הגבול העגול והצבעוני שמסתובב סביב התמונות שלנו. אנחנו יכולים להשתמש באלמנט פסאודו ב- .gallery עטיפה להכנתו:

.gallery {
  padding: calc(var(--s) / 20); /* the padding is needed here */
  position: relative;
}
.gallery::after {
  content: "";
  position: absolute;
  inset: 0;
  padding: inherit; /* Inherits the same padding */
  border-radius: 50%;
  background: repeating-conic-gradient(#789048 0 30deg, #DFBA69 0 60deg);
  mask: 
    linear-gradient(#fff 0 0) content-box, 
    linear-gradient(#fff 0 0);
  mask-composite: exclude;
}
.gallery::after,
.gallery >img {
  animation: m 8s infinite cubic-bezier(.5, -0.2, .5, 1.2);
}

יצרתי מעגל עם א שיפוע חרוטי חוזר עבור הרקע בעת שימוש ב-a טריק מיסוך שמראה רק את האזור המרופד. ואז אני מחיל עליו את אותה אנימציה שהגדרנו לתמונות.

אנחנו גמרנו! יש לנו סליידר מעגלי מגניב:

בואו נוסיף עוד תמונות

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

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

נתחיל עם העיכובים:

.gallery > img:nth-child(2) { animation-delay: -2s; } /* -1 * 8s / 4 */
.gallery > img:nth-child(3) { animation-delay: -4s; } /* -2 * 8s / 4 */
.gallery > img:nth-child(4) { animation-delay: -6s; } /* -3 * 8s / 4 */

הנוסחה לעיכוב היא (1 - $i)*duration/$n, שנותן לנו את הלולאה הבאה של Sass:

@for $i from 2 to ($n + 1) {
  .gallery > img:nth-child(#{$i}) {
    animation-delay: calc(#{(1 - $i) / $n} * 8s);
  }
}

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

@keyframes m {
  0%, 3% { transform: rotate(0); }
  22%, 27% { transform: rotate(-90deg); }
  47%, 52% { transform: rotate(-180deg); }
  72%, 77% { transform: rotate(-270deg); }
  98%, 100% {transform: rotate(-360deg); }
}

בואו נפשט את זה כדי לקבל תצוגה טובה יותר של הדפוס:

@keyframes m {
  0% { transform: rotate(0); }
  25% { transform: rotate(-90deg); }
  50% { transform: rotate(-180deg); }
  75% { transform: rotate(-270deg); }
  100% { transform: rotate(-360deg); }
}

הצעד בין כל מדינה שווה ל 25% - שהוא 100%/4 - ואנחנו מוסיפים א -90deg זווית - כלומר -360deg/4. זה אומר שאנחנו יכולים לכתוב את הלולאה שלנו כך במקום זאת:

@keyframes m {
  0% { transform: rotate(0); }
  @for $i from 1 to $n {
    #{($i / $n) * 100}% { transform: rotate(#{($i / $n) * -360}deg); }  
  }
  100% { transform: rotate(-360deg); }
}

מאז כל תמונה לוקחת 5% של האנימציה, אנו משנים את זה:

#{($i / $n) * 100}%

…עם זה:

#{($i / $n) * 100 - 2}%, #{($i / $n) * 100 + 3}%

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

@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); }
}

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

Slider תמונה מסתובבת אינסופית ומעגלית של PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.
מחוון תמונה מסתובב אינסופי ומעגלי של CSS

אתה כנראה לא רוצה הסבר גיאומטריה משעמם אז הנה איך אנחנו מוצאים R:

R = S / (2 * sin(180deg / N))

אם נביע את זה באחוזים, זה נותן לנו:

R = 100% / (2 * sin(180deg / N)) = 50% / sin(180deg / N)

... שפירושו ה transform-origin הערך שווה ל:

transform-origin: 50% (50% / math.sin(180deg / $n) + 50%);

אנחנו סיימנו! יש לנו סליידר שעובד עם כל תמונות מספר!

בואו נזרוק שם תשע תמונות:

הוסף כמה תמונות שתרצה ועדכן את $n משתנה עם המספר הכולל של תמונות.

גלישה את

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

בול זמן:

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