Heim >Web-Frontend >CSS-Tutorial >So machen Sie ein reines CSS -3D -Paket umschalten

So machen Sie ein reines CSS -3D -Paket umschalten

尊渡假赌尊渡假赌尊渡假赌
尊渡假赌尊渡假赌尊渡假赌Original
2025-03-15 09:35:09378Durchsuche

So machen Sie ein reines CSS -3D -Paket umschalten

Kennen Sie diese völlig flachen Wellkisten? Sie können sie falten und kleben, um eine praktische Box zu erstellen. Wenn ein Recycling benötigt wird, schneiden Sie sie auf und flachen Sie sie ab. Vor kurzem wurde mir eine 3D -Animationsversion dieses Konzepts konsultiert und ich dachte, es wäre ein interessantes Tutorial, es mit reinem CSS zu implementieren, also haben wir angefangen!

Wie würde diese Art von Animation aussehen? Wie erstellen wir eine Timeline für Verpackungen? Kann die Größe flexibel eingestellt werden? Erstellen wir einen reinen CSS -Paket -Toggle -Effekt.

Der endgültige Effekt ist wie folgt: Klicken Sie auf das Packen und Auspacken des Kartons.

Wo fängt man an?

Wo fängt man an? Es ist am besten, im Voraus Pläne zu machen. Wir wissen, dass wir eine Verpackungsvorlage brauchen und sie im dreidimensionalen Raum falten müssen. Wenn Sie mit CSS 3D nicht vertraut sind, schlage ich vor, dass Sie diesen Artikel lesen, um loszulegen.

Wenn Sie mit 3D -CSS vertraut sind, können Sie dazu neigen, einen Quader zu bauen und dann zu beginnen. Dies bringt jedoch einige Probleme. Wir müssen überlegen, wie das Paket von 2D auf 3D konvertiert wird.

Beginnen wir zunächst eine Vorlage. Wir müssen die Markierungen im Voraus planen und darüber nachdenken, wie die Verpackungsanimation funktioniert. Beginnen wir mit einiger HTML.

<div>
  <div>
    <div>
      <div>
        <div></div>
        <div></div>
        <div>
          <div></div>
          <div></div>
        </div>
        <div>
          <div></div>
          <div></div>
          <div>
            <div></div>
            <div></div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Mixin ist eine gute Idee

Hier gibt es viele Inhalte. Es gibt viele Divs. Ich benutze oft gerne Mops, um Tags zu generieren, damit der Inhalt in wiederverwendbare Stücke unterteilt werden kann. Zum Beispiel hat jede Seite zwei Abdeckungen. Wir können ein Mops -Mixin für die Seite erstellen und den Namen der Modifikatorklasse mithilfe von Eigenschaften anwenden, um all diese Tags zu schreiben.

 Mixinklappen ()
  .package__Flap.package__Flap- top
  .package__Flap.package__flap-Boden

Mixin -Seite (Klasse)
  .package__side (class = `package__side-$ {class || 'Seite'}`)
     Klappen ()
    Block

.Szene
  .package__Wrapper
    .Paket
       Seite ('Main')
         Seite ('extra')
         Seite ('geflippt')
           Seite ('Tabbed')

Wir haben zwei Mixins verwendet. Man schafft eine Abdeckung für jede Seite der Box. Ein anderer erstellt die Seite der Box. Beachten Sie, dass wir im Seitenmischung Block verwenden. Die Kinderelemente der Mixin -Verwendung werden hier vorgestellt, was besonders nützlich ist, da wir einige Seiten später nisten müssen, um unsere Arbeit zu vereinfachen.

Erzeugte Tags:

<div class="scene">
  <div class="package__wrapper">
    <div class="package">
      <div class="package__side package__side--main">
        <div class="package__flap package__flap--top"></div>
        <div class="package__flap package__flap--bottom"></div>
        <div class="package__side package__side--extra">
          <div class="package__flap package__flap--top"></div>
          <div class="package__flap package__flap--bottom"></div>
        </div>
      </div>
      <div class="package__side package__side--flipped">
        <div class="package__flap package__flap--top"></div>
        <div class="package__flap package__flap--bottom"></div>
        <div class="package__side package__side--tabbed">
          <div class="package__flap package__flap--top"></div>
          <div class="package__flap package__flap--bottom"></div>
        </div>
      </div>
    </div>
  </div>
</div>

Verschachtelte Seite

Verschachtelte Seiten erleichtern die Klappverpackung. Genauso wie es zwei Cover auf jeder Seite gibt. Die Nebenkinderelemente können die Seitenumwandlung erben und dann ihre eigene Transformation anwenden. Wenn wir mit einem Quader beginnen, ist es schwierig, dies zu nutzen.

Schauen Sie sich diese Demo an, die zwischen verschachtelten und nicht Nestnestnern Elementen wechselt, um den tatsächlichen Effekt zu erkennen.

Jedes Box verfügt über einen Transformationsorientier, der mit einem Wert von 100% 100% in die untere rechte Ecke eingestellt ist. Durch die Auswahl des "Transformation" -Wechsels wird jedes Feld um 90 Grad gedreht. Beachten Sie jedoch, dass das Verhalten dieser Transformation, wenn wir Elemente nisten, ändert.

Wir haben die Tags für beide Versionen gewechselt, aber nichts anderes wurde geändert.

Nist:

<div>
  <div>
    <div>
      <div>
        <div></div>
      </div>
    </div>
  </div>
</div>

Nicht neu:

<div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

Alles verwandeln

Nachdem wir einige Stile auf unsere HTML angewendet haben, haben wir unsere Paketvorlage.

Der Stil spezifiziert verschiedene Farben und findet die Seiten zum Paket. Jede Seite ist relativ zur "Haupt" -Seite positioniert. (Sie werden bald verstehen, warum das Nisten so nützlich ist.)

Einige Dinge müssen beachtet werden. Genau wie die Verwendung eines Quaders verwenden wir --height , --width und --depth , um die Größe zu bestimmen. Dies erleichtert es uns, die Paketgröße später zu ändern.

 .Paket {
  Höhe: Calc (var (-Höhe, 20) * 1Vmin);
  Breite: Calc (var (-Breite, 20) * 1VMIN);
}

Warum die Größe auf diese Weise definieren? Wir haben eine einheitlose Standardgröße von 20 verwendet, eine Idee, die ich aus Lea Verous CSS Confasia Talk (ab 52:44) bekam. Verwenden Sie benutzerdefinierte Eigenschaften als "Daten" anstelle von "Wert". Wir können sie verwenden, da wir gerne calc() verwenden. Außerdem muss sich JavaScript nicht um die Werteinheit kümmern, wir können sie in Pixel, Prozentsätze usw. ändern, ohne sie an anderer Stelle zu ändern. Sie können es in Koeffizienten in --root neu ausführen, aber dies kann schnell zu komplex werden.

Die Abdeckplatten auf jeder Seite müssen ebenfalls etwas kleiner sein als die Seiten, zu denen sie gehören. Auf diese Weise gibt es, wenn wir sie falten, keinen Z-Index-Konflikt.

 .package__flap {
  Breite: 99,5%;
  Höhe: 49,5%;
  Hintergrund: var (-flap-bg, var (-face-4));
  Position: absolut;
  Links: 50%;
  Transformation: Translate (-50%, 0);
}
.package__Flap--Top {
  Transform-Origin: 50% 100%;
  unten: 100%;
}
.package__Flap-bottom {
  Oben: 100%;
  Transform-Origin: 50% 0%;
}
.package__side-extra> .package__flap --botom,
.package__side-tabbed> .package__flap-bottom {
  Top: 99%;
}
.package__side-extra> .package__Flap- top,
.package__side-tabbed> .package__Flap--top {
  unten: 99%;
}

Wir begannen auch, für jede Komponente transform-origin zu berücksichtigen. Die obere Abdeckung dreht sich von der unteren Kante und die untere Abdeckung dreht sich von der Oberkante.

Wir können Pseudoelemente verwenden, um das Etikett rechts zu erstellen. Wir verwenden clip-path , um die gewünschte Form zu erhalten.

 .package__side-tabben: nach {
  Inhalt: '';
  Position: absolut;
  Links: 99,5%;
  Höhe: 100%;
  Breite: 10%;
  Hintergrund: var (-face-3);
  -Webkit-Clip-Pfad: Polygon (0 0%, 100%20%, 100%80%, 0 100%);
  Clip-Pfad: Polygon (0 0%, 100%20%, 100%80%, 0 100%);
  Transform-Origin: 0% 50%;
}

Beginnen wir mit unseren Vorlagen in einer 3D -Ebene. Wir können zuerst die X-Achse und die Y-Achse .scene .

 .scene {
  Transformation: rotatex (-24deg) rotatey (-32deg) rotatex (90 °);
}

falten

Wir sind bereit, unsere Vorlagen zu falten! Unsere Vorlagen werden nach benutzerdefinierten Eigenschaften zusammengebrochen --packaged . Wenn der Wert 1 ist, kann die Vorlage zusammengebrochen werden. Lassen Sie uns beispielsweise einige Seiten- und Pseudo-Elemente-Etiketten zusammenbrechen.

 .package__side-getabbiert,
.package__side-tabben: nach {
  Transformation: rotatey (calc (var (-verpackt, 0) * -90de));
}
.package__side-extra {
  Transformation: rotatey (calc (var (-verpackt, 0) * 90 Grad));
}

Alternativ können wir eine Regel für alle Seiten schreiben, die nicht die "Haupt" -Seite sind.

 .package__side: nicht (.package__side-Main),
.package__side: nicht (.package__side-Main): Nach {{
  Transformation: rotatey (calc ((var (-verpackt, 0) * var (-rotation, 90)) * 1deg));
}
.package__side-tabben {-ROTATION: -90;

Dies wird alle Seiten abdecken.

Erinnern Sie sich, als ich sagte, dass verschachtelte Seiten es uns ermöglichen, die Transformation des übergeordneten Elements zu erben? Wenn wir unsere Demo aktualisieren, damit wir den Wert von --packaged ändern können, können wir sehen, wie sich dieser Wert auf die Transformation auswirkt. Versuchen Sie, den Wert von --packaged zwischen 1 und 0, und Sie werden sehen, was ich meine.

Nachdem wir die Möglichkeit haben, den gefalteten Status der Vorlage zu wechseln, können wir mit etwas Bewegung umgehen. Unsere frühere Demonstration wechselt zwischen zwei Zuständen. Wir können dafür transition verwenden. Der schnellste Weg? Fügen Sie einen transition transform jedes untergeordneten Elements in .scene hinzu.

 .scene *,
.scene *:: nach {
  Übergang: Transformation Calc (var (-Geschwindigkeit, 0,2) * 1s);
}

Mehrstufiger Übergang!

Aber wir falten die gesamte Vorlage nicht gleichzeitig - im wirklichen Leben ist der Faltprozess nacheinander, wir werden eine Seite und seine Abdeckung zuerst falten und dann mit dem nächsten und so weiter übergehen. SCOPE -benutzerdefinierte Eigenschaften sind für diesen Zweck ideal.

 .scene *,
.scene *:: nach {
  Übergang: Transformation Calc (var (-Geschwindigkeit, 0,2) * 1s) Calc ((var (-Schritt, 1) * var (-Verzögerung, 0,2)) * 1s);
}

Hier sagen wir, dass für jede Transformation das transition-delay zum Multiplizieren von --step mit --delay . --delay Wert ändert sich nicht, aber jedes Element kann seine "Schritte" in der Sequenz definieren. Wir können dann die Reihenfolge, in der Dinge passieren, klar angeben.

 .package__side-extra {
  -STEP: 1;
}
.package__side-tabben {
  -STEP: 2;
}
.package__side-Flipped,
.package__side-tabbed :: nach {{
  -STEP: 3;
}

Schauen Sie sich die Demo unten an, um besser zu verstehen, wie sie funktioniert. Ändern Sie den Schieberegler, um die Reihenfolge zu aktualisieren, in der Dinge passieren. Können Sie das Auto ändern?

Die gleiche Technologie ist der Schlüssel zu dem, was wir als nächstes tun müssen. Wir konnten sogar ein --initial-delay einführen und für einen realistischeren Effekt eine leichte Pause für alles verleihen.

 .Race__light-animiert,
.Race__light-animiert: danach,
.Auto {
  Animation-Delay: Calc ((var (-Schritt, 0) * var (-Verzögerungsschritt, 0)) * 1s);
}

Wenn wir auf unser Paket zurückblicken, können wir noch einen Schritt weiter gehen und die "Schritte" auf alle Elemente anwenden, die konvertiert werden. Das ist ziemlich ausführlich, aber es funktioniert. Alternativ können Sie diese Werte in das Tag einbeziehen.

 .package__side-extra> .package__flap-bottom {
  -STEP: 4;
}
.package__side-tabbed> .package__flap-bottom {
  -STEP: 5;
}
.package__side-Main> .package__flap-Bottom {
  -STEP: 6;
}
.package__side-flipped> .package__flap-bottom {
  -STEP: 7;
}
.package__side-extra> .package__flap--top {
  -STEP: 8;
}
.package__side-tabbed> .package__Flap--top {
  -STEP: 9;
}
.package__side-Main> .package__Flap--Top {
  -STEP: 10;
}
.package__side-flipped> .package__flap--top {
  -STEP: 11;
}

Es fühlt sich jedoch unrealistisch an.

Vielleicht sollten wir die Box umdrehen

Wenn ich die Box im wirklichen Leben faltete, könnte ich die Box zuerst umdrehen und dann die obere Abdeckung falten. Wie können wir das tun? Nun, diejenigen mit scharfen Augen haben möglicherweise das .package__wrapper -Element bemerkt. Wir werden es verwenden, um das Paket zu schieben. Dann drehen wir die Wickel um die x-Achse. Dies vermittelt den Eindruck, das Paket zur Seite zu drehen.

 .Paket {
  Transform-Origin: 50% 100%;
  Transformation: rotatex (calc (var (-verpackt, 0) * -90de));
}
.package__wrapper {
  Transformation: Translate (0, Calc (var (-verpackt, 0) * -100%));
}

Passen Sie die --step -Deklaration entsprechend an und wir können einen ähnlichen Effekt erzielen.

Erweitern Sie die Box

Wenn Sie zwischen gefalteten und entfalteten Zuständen wechseln, werden Sie feststellen, dass die Erweiterung falsch aussieht. Die Expansionsreihenfolge sollte das vollständige Umkehr des Zusammenbruchs sein. Wir können nach --packaged und die Anzahl der Schritte --step . Unser letzter Schritt ist 15. Wir können unsere Konvertierung dazu aktualisieren:

 .scene *,
.scene *: nach {
  -No-of-Steps: 15;
  -STEP-DELAY: CALC (var (-Schritt, 1)-((1-var (-verpackt, 0)) * (var (-Schritt)-((var (-No-of-Steps) 1)-var (-Schritt))));
  Übergang: Transformation Calc (var (-Geschwindigkeit, 0,2) * 1s) Calc ((var (-Stiefverzögerung) * var (-Verzögerung, 0,2)) * 1s);
}

Dies sind in der Tat viele calc , um transition-delay umzukehren. Aber es funktioniert! Wir müssen uns daran erinnern, --no-of-steps auf dem neuesten Stand zu halten!

Wir haben eine andere Option. Wenn wir auf der "reinen CSS" -Soute fortfahren, werden wir schließlich den Kontrollkästchen Trick verwenden, um den gefalteten Status zu wechseln. Wir können zwei Sätze definierter "Schritte" haben, von denen eines aktiv ist, wenn unser Kontrollkästchen ausgewählt ist. Dies ist sicherlich eine ausführlichere Lösung. Es ermöglicht uns jedoch, körniger zu kontrollieren.

 /* Falten*/
: überprüft ~ .scene .package__side-extra {
  -STEP: 1;
}
/* Expandieren*/
.package__side-extra {
  -STEP: 15;
}

Größe und Mitte

Bevor wir Dat.gui in der Demo aufgeben, passen wir die Größe des Pakets an. Wir möchten prüfen, ob unser Paket beim Falten und Umdrehen zentriert bleibt. In dieser Demo hat der Wrap eine größere --height , während .scene eine gepunktete Grenze hat.

Wir können unsere Transformation genauso gut anpassen, um das Paket besser zu zentrieren:

 /* Betrachten Sie die Pakethöhe durch Übersetzung auf der Z-Achse*/
.scene {
  Transformation: rotatex (calc (var (-rotate-x, -24) * 1deg)) rotatey (calc (var (-rotate-y, -32) * 1deg)) rotatex (90de) Translat3d (0, 0, calc (var (-Höhe, 20) * -0,5vmin));
}
/* Berücksichtigen Sie die Wickeltiefe, indem Sie die Tiefe vor dem Umdrehen*/schieben*/
.package__wrapper {
  Transformation: Translate (0, Calc ((var (-verpackt, 0) * var (-Tiefe, 20)) * -1vmin));
}

Dies gibt uns einen zuverlässigen Zentrierungseffekt in der Szene. Aber alles hängt von persönlichen Vorlieben ab!

Tipps zum Hinzufügen von Kontrollkästchen

Lassen Sie uns nun Dat.gui loswerden und es "reines" CSS machen. Dazu müssen wir eine Reihe von Steuerungen in HTML einführen. Wir werden ein Kontrollkästchen verwenden, um unser Paket zu kollabieren und zu erweitern. Wir werden dann ein Optionsfeld verwenden, um die Paketgröße auszuwählen.

 <label for="one">S</label>

<label for="two">M</label>

<label for="three">L</label>

<label for="four">Xl</label>

<input type="checkbox" id="package">
<label for="package" class="open">Öffnen Sie das Paket</label>
<label for="package" class="close">Schließen Sie das Paket</label>

In der endgültigen Demo werden wir die Eingabe ausblenden und das Tag -Element verwenden. Aber jetzt lassen wir sie zuerst alle sichtbar. Der Trick besteht darin, den Geschwister -Kombinierer (~) zu verwenden, wenn einige Steuerelemente ausgewählt werden. Wir können dann den benutzerdefinierten Eigenschaftswert auf .scene festlegen.

 #package: up ~ .scene {
  -verpackt: 1;
}
#One: Checked ~ .scene {
  -Höhe: 10;
  -Breite: 20;
  -Depth: 20;
}
#TWO: Überprüft ~ .scene {
  -Höhe: 20;
  -Breite: 20;
  -Depth: 20;
}
#Three: Checked ~ .scene {
  -Höhe: 20;
  -Breite: 30;
  -Depth: 20;
}
#four: ~ .scene {
  -Höhe: 30;
  -Breite: 20;
  -Depth: 30;
}

Hier ist eine Demo mit dieser Funktion!

Endgültiger Politur

Jetzt können wir die Dinge "hübsch" aussehen lassen und zusätzliche Details hinzufügen. Lassen Sie uns zuerst alle Eingänge verbergen.

 Eingabe {
  Position: fest;
  Top: 0;
  links: 0;
  Breite: 1PX;
  Höhe: 1PX;
  Polsterung: 0;
  Rand: -1px;
  Überlauf: versteckt;
  Clip: Rect (0, 0, 0, 0);
  weißer Raum: Nowrap;
  Grenzbreit: 0;
}

Wir können die Größenoption auf die kreisförmige Taste einstellen:

 .Size-label {
  Position: fest;
  Oben: var (-ober);
  Rechts: 1Rem;
  Z-Index: 3;
  Schriftfamilie: Sans-Serif;
  Schriftgewicht: fett;
  Farbe: #262626;
  Höhe: 44px;
  Breite: 44px;
  Anzeige: Grid;
  Orts-Element: Zentrum;
  Hintergrund: #fcfcfc;
  Grenzradius: 50%;
  Cursor: Zeiger;
  Grenze: 4px Solid #8bb1b1;
  Transformation: Translate (0, Calc (var (-y, 0) * 1%)) Skala (var (-Skala, 1));
  Übergang: Transformation 0,1s;
}
.Size-Label: Hover {
  - -y: -5;
}
.Size-Label: Active {
  --y: 2;
  -Scale: 0,9;
}

Wir möchten in der Lage sein, überall zu klicken, um die Faltung und Erweiterung des Pakets zu wechseln. Daher belegen unsere .open und .close -Tags den gesamten Bildschirm. Möchten Sie wissen, warum wir zwei Etiketten haben? Das ist ein kleiner Trick. Wenn wir transition-delay verwenden und auf dem entsprechenden Tag zoomen, können wir zwei Tags ausblenden, wenn das Paket konvertiert wird. Auf diese Weise kämpfen wir gegen Spam -Klicks (obwohl es nicht hindert, die Leakenleiste auf der Tastatur zu drücken).

 .schließen,
.offen {
  Position: fest;
  Höhe: 100VH;
  Breite: 100VW;
  Z-Index: 2;
  Transformation: Skala (var (-Skala, 1)) Translate3D (0, 0, 50VMin);
  Übergang: Transformation 0s var (-Dendezone, Calc (((var (-No-of-Steps), 15) 1) * var (-Verzögerung, 0,2)) * 1s));
}

#package: überprüft ~ .CLOSE,
.offen {
  -Scale: 0;
  -Reveal-Delay: 0s;
}
#package: up ~ .open {
  -Scale: 1;
  -Reveal-Delay: Calc (((var (-ohne Schritt, 15) 1) * var (-Verzögerung, 0,2)) * 1s);
}

Schauen Sie sich diese Demo an, um zu sehen, wo wir background-color in .open und .close hinzugefügt haben. Während der Umwandlung ist kein Etikett sichtbar.

Wir haben bereits volle Funktionalität! Unser Paket ist im Moment jedoch etwas langweilig. Fügen wir zusätzliche Details hinzu, damit es eher wie ein "Box" wie ein Wickelband und Verpackungsbezeichnungen aussieht.

Details wie diese sind nur durch unsere Fantasie begrenzt! Wir können unsere --packaged benutzerdefinierte Eigenschaft verwenden, um alles zu beeinflussen. Zum Beispiel konvertiert .package__tape die scaleY Transformation:

 .package__Tape {
  Transformation: Translate3D (-50%, var (-offset-y), -2px) scalex (var (-verpackt, 0));
}

Es ist zu beachten, dass wir unsere Schritte aktualisieren müssen, wenn wir neue Funktionen hinzufügen, die sich auf die Sequenz auswirken. Nicht nur --step Wert, sondern auch --no-of-steps .

Das ist alles!

Auf diese Weise erstellen Sie eine reine CSS -3D -Paketschaltung. Würden Sie es auf Ihre Website setzen? Nicht wahrscheinlich! Es macht jedoch Spaß zu sehen, dass Sie diese Dinge mit CSS implementieren können. Benutzerdefinierte Eigenschaften sind sehr mächtig.

Warum nicht feiern und ein Geschenk für CSS geben!

Bleib gut! ʕ • ᴥ • ʔ

Das obige ist der detaillierte Inhalt vonSo machen Sie ein reines CSS -3D -Paket umschalten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn