CSS Oneindige 3D-schuifregelaars PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

CSS Oneindige 3D-schuifregelaars

In deze serie, hebben we schuifregelaars voor afbeeldingen gemaakt met niets anders dan HTML en CSS. Het idee is dat we dezelfde opmaak maar verschillende CSS kunnen gebruiken om enorm verschillende resultaten te krijgen, ongeacht het aantal afbeeldingen dat we erin gooien. We zijn begonnen met een cirkelvormige schuifregelaar die oneindig ronddraait, een beetje zoals een fidget-spinner die afbeeldingen vasthoudt. Daarna hebben we er een gemaakt die door een stapel foto's bladert.

Deze keer duiken we in de derde dimensie. In het begin zal het er moeilijk uitzien, maar veel van de code waar we naar kijken is precies wat we gebruikten in de eerste twee artikelen in deze serie, met enkele aanpassingen. Dus als je nu net met de serie begint, raad ik je aan de andere te bekijken voor context over de concepten die we hier gebruiken.

CSS Sliders-serie

Dit is waar we naar streven:

Op het eerste gezicht lijkt het alsof we een draaiende kubus hebben met vier afbeeldingen. Maar in werkelijkheid hebben we in totaal te maken met zes afbeeldingen. Hier is de slider vanuit een andere hoek:

Nu we een goed beeld hebben van hoe de afbeeldingen zijn gerangschikt, gaan we de code ontleden om te zien hoe we daar komen.

De basisopstelling

Dezelfde HTML als de rest van de schuifregelaars die we voor de andere schuifregelaars hebben gebruikt:

En nogmaals, we gebruiken CSS Grid om de afbeeldingen in een stapel op elkaar te plaatsen:

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

De animatie

De logica voor deze schuifregelaar lijkt erg op de ronde slider uit het eerste artikel. Als je de video hierboven nog eens bekijkt, kun je zelfs zien dat de afbeeldingen zo zijn geplaatst dat er een polygoon ontstaat. Na een volledige rotatie keert het terug naar het eerste beeld.

We vertrouwden op de CSS transform-origin en animation-delay eigenschappen voor die eerste schuifregelaar. Dezelfde animatie wordt toegepast op alle afbeeldingselementen, die rond hetzelfde punt roteren. Vervolgens plaatsen we, door verschillende vertragingen te gebruiken, alle afbeeldingen correct rond een grote cirkel.

De implementatie zal een beetje anders zijn voor onze 3D-slider. Gebruik makend van transform-origin werkt hier niet omdat we in 3D werken, dus we zullen gebruiken transform plaats in plaats daarvan alle afbeeldingen correct en draai vervolgens de container.

We reiken weer naar Sass, zodat we het aantal afbeeldingen kunnen doorlopen en onze transformaties kunnen toepassen:

@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 */
  }
}

Je vraagt โ€‹โ€‹je misschien af โ€‹โ€‹waarom we meteen naar Sass springen. We zijn begonnen met een vast aantal afbeeldingen met behulp van vanilla CSS in de andere artikelen voordat we de code veralgemenen met Sass om rekening te houden met een willekeurig aantal (N) van afbeeldingen. Welnu, ik denk dat je het idee nu begrijpt en dat we al dat ontdekkingswerk kunnen schrappen om tot de echte implementatie te komen.

De transform eigenschap neemt drie waarden aan, die ik hier heb geรฏllustreerd:

CSS Oneindige 3D-schuifregelaars

We roteren eerst alle afbeeldingen boven elkaar. De rotatiehoek is afhankelijk van het aantal afbeeldingen. Voor N afbeeldingen, we hebben een toename gelijk aan 360deg/N. Dan gaan we translate alle afbeeldingen met dezelfde hoeveelheid op een manier dat hun middelpunten aan de zijkanten samenkomen.

De stapel afbeeldingen wordt plat in een cirkel gerangschikt met een rode lijn die door het middelpunt van de afbeeldingen loopt.
CSS Oneindige 3D-schuifregelaars

Er is een saaie geometrie die helpt verklaren hoe dit allemaal werkt, maar de afstand is gelijk aan 50%/tan(180deg/N). We hebben met een vergelijkbare vergelijking te maken gehad bij het maken van de ronde schuifregelaar ( transform-origin: 50% 50%/sin(180deg/N) ).

Ten slotte roteren we de afbeeldingen rond de x-as door 90deg om de regeling te krijgen die we willen. Hier is een video die illustreert wat de laatste rotatie doet:

Nu hoeven we alleen nog maar de hele container te draaien om onze oneindige schuifregelaar te maken.

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

Die code is misschien moeilijk te begrijpen, dus laten we even een stapje terug doen en de animatie bekijken die we voor de cirkelvormige schuifregelaar hebben gemaakt. Dit is wat we in dat eerste artikel schreven:

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

De keyframes zijn bijna identiek. We hebben dezelfde procentuele waarden, dezelfde lus en dezelfde rotatie.

Waarom zijn beide hetzelfde? Omdat hun logica hetzelfde is. In beide gevallen zijn de afbeeldingen gerangschikt rond een cirkelvorm en moeten we het geheel draaien om elke afbeelding weer te geven. Zo kon ik de keyframes van de ronde schuifregelaar kopiรซren en diezelfde code gebruiken voor onze 3D-schuifregelaar. Het enige verschil is dat we de container moeten draaien -90deg langs de x-as om de afbeeldingen te zien, aangezien we ze al hebben geroteerd 90deg op dezelfde as. Dan voegen we een vleugje toe perspective om het 3D-effect te krijgen.

Dat is het! Onze schuifregelaar is klaar. Hier is de volledige demo nog een keer. Het enige wat u hoeft te doen is zoveel afbeeldingen toe te voegen als u wilt en รฉรฉn variabele bij te werken om het op gang te krijgen.

Verticale 3D-schuifregelaar

Aangezien we in de 3D-ruimte spelen, waarom zou je dan geen verticale versie van de vorige schuifregelaar maken? De laatste roteert langs de z-as, maar we kunnen ook langs de x-as bewegen als we willen.

Als je de code voor beide versies van deze schuifregelaar vergelijkt, zie je misschien niet meteen het verschil omdat het maar รฉรฉn teken is! ik heb vervangen rotate() Met rotateX() binnen de keyframes en de afbeelding transform. Dat is het!

Opgemerkt dat rotate() is gelijk aan rotateZ(), dus door de as te veranderen van Z naar X we transformeren de schuifregelaar van de horizontale versie naar de verticale.

Kubus schuifregelaar

We kunnen niet zonder 3D in CSS praten over kubussen gesproken. En ja, dat betekent dat we nog een versie van de slider gaan maken.

Het idee achter deze versie van de schuifregelaar is om een โ€‹โ€‹echte kubusvorm te creรซren met de afbeeldingen en het volledige ding rond de andere as te draaien. Omdat het een kubus is, hebben we te maken met zes gezichten. We gebruiken zes afbeeldingen, รฉรฉn voor elk vlak van de kubus. Dus geen Sass maar terug naar vanilla CSS.

Die animatie is een beetje overweldigend, toch? Waar begin je eigenlijk?

We hebben zes gezichten, dus we moeten minstens zes rotaties uitvoeren zodat elk beeld een draai krijgt. Nou, eigenlijk hebben we vijf rotaties nodig - de laatste brengt ons terug naar het eerste beeldgezicht. Als je een Rubik's Cube - of een ander kubusvormig object zoals dobbelstenen - pakt en met je hand ronddraait, heb je een goed idee van wat we aan het doen zijn.

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

De transform eigenschap begint met nul rotaties en bij elke toestand voegen we een nieuwe rotatie toe op een specifieke as totdat we zes rotaties bereiken. Dan zijn we terug bij het eerste beeld.

Laten we de plaatsing van onze afbeeldingen niet vergeten. Elk wordt toegepast op een vlak van de kubus met behulp van 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); }

Je denkt waarschijnlijk dat er rare complexe logica zit achter de waarden die ik daar gebruik, toch? Welnee. Het enige wat ik deed was DevTools openen en met verschillende rotatiewaarden voor elke afbeelding spelen totdat ik het goed had. Het klinkt misschien stom, maar hey, het werkt - vooral omdat we een vast aantal afbeeldingen hebben en we niet op zoek zijn naar iets dat N afbeeldingen.

Vergeet in feite de waarden die ik gebruik en probeer de plaatsing alleen te doen als oefening. Begin met alle afbeeldingen op elkaar gestapeld, open de DevTools en ga! Je zult waarschijnlijk eindigen met andere code en dat is helemaal goed. Er kunnen verschillende manieren zijn om de afbeeldingen te positioneren.

Wat is de truc met de komma in de var()? Is het een typefout?

Het is geen typefout, dus niet verwijderen! Als u het toch verwijdert, zult u merken dat dit invloed heeft op de plaatsing van de eerste afbeelding. Je kunt dat zien in mijn code die ik heb gedefinieerd --_t voor alle afbeeldingen behalve de eerste omdat ik er alleen een vertaling voor nodig heb. Die komma zorgt ervoor dat de variabele terugvalt naar een nulwaarde. Zonder de komma hebben we geen fallback en is de hele waarde ongeldig.

Van de specificatie:

Opmerking: dat wil zeggen, var(--a,) is een geldige functie, specificeert dat als de --a aangepaste eigenschap ongeldig is of ontbreekt, de var()'moet worden vervangen door niets.

Willekeurige kubusschuifregelaar

Een beetje willekeur kan een leuke verbetering zijn voor dit soort animaties. Dus in plaats van de kubus in volgorde te draaien, kunnen we de dobbelsteen als het ware werpen en de kubus laten rollen zoals hij wil.

Cool toch? Ik weet niet hoe het met jou zit, maar ik vind deze versie beter! Het is interessanter en de overgangen zijn bevredigend om naar te kijken. En raad eens? Je kunt met de waarden spelen om je eigen willekeurige kubusschuifregelaar te maken!

De logica is eigenlijk helemaal niet willekeurig - het lijkt gewoon zo. U definieert een transform op elk keyframe waarmee u รฉรฉn gezicht kunt laten zien en ... nou, dat is het echt! U kunt elke gewenste bestelling kiezen.

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

ik gebruik rotate3d() deze keer, maar ik vertrouw nog steeds op DevTools om de waarden te vinden die voor mij "goed" aanvoelen. Probeer geen relatie tussen de keyframes te vinden, want die is er simpelweg niet. Ik definieer afzonderlijke transformaties en bekijk vervolgens het "willekeurige" resultaat. Zorg ervoor dat de eerste afbeelding respectievelijk het eerste en laatste frame is, en laat op elk van de andere frames een andere afbeelding zien.

U bent niet verplicht om a rotate3d() transformeren zoals ik deed. Je kunt ook verschillende rotaties koppelen, zoals in het vorige voorbeeld. Speel rond en kijk wat je kunt bedenken! Ik wacht op je om je versie met mij te delen in het opmerkingengedeelte!

Afsluiten

Ik hoop dat je genoten hebt van deze kleine serie. We hebben een aantal leuke (en grappige) schuifregelaars gebouwd terwijl we onderweg veel leerden over allerlei CSS-concepten โ€” van rasterplaatsing en stapelvolgorde tot animatievertragingen en transformaties. We mochten zelfs spelen met een scheutje Sass om door een reeks elementen te lopen.

En we deden het allemaal met exact dezelfde HTML voor elke slider die we maakten. Hoe cool is dat? CSS is ontzettend krachtig en kan zoveel bereiken zonder de hulp van JavaScript.

Tijdstempel:

Meer van CSS-trucs