3D Button Parallax

Avatar of Alexander Futekov
Alexander Futekov am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Der folgende Text ist ein Gastbeitrag von Alexander Futekov. Kürzlich haben wir einen Artikel von Joshua Bader veröffentlicht, in dem ein 3D-Inset-Look beim Scrollen der Seite angepasst wurde, um eine realistischere Interaktion zu erzielen. Dies ist ähnlich, nur dass Alexander einen extrudierten Look auf Buttons verwendet und eine völlig andere Technik einsetzt.

Die Einführung von CSS3 führte zu einer Explosion schöner und interessanter Buttons, die mit Verläufen, Schatten und Rändern gestaltet wurden – oft, um einen 3D-Effekt zu erzielen. Das Problem bei solchen 3D-Buttons ist eine statische Perspektive. Die 3D-Wirkung ist nicht immer sehr überzeugend, wenn man nur die Vorderseite und vielleicht ein oder zwei Kanten sieht – selbst wenn sich die Seite bewegt und sich die Position des Buttons auf der Seite verschiebt.

Glücklicherweise können wir mit Hilfe von 3D-Transformationen einen realistischen Perspektiveneffekt erzielen, um die Seiten der Buttons anzupassen. Dies können wir tun, ohne das vorhandene HTML zu ändern, indem wir Pseudo-Elemente für die Seiten verwenden. Dann bringen wir den Button selbst mit translateZ nach vorne.

Bevor wir beginnen, müssen wir zunächst ein Problem lösen. Der Perspektivenursprung ist normalerweise in der vertikalen und horizontalen Mitte des Elements eingestellt. Das bedeutet, wenn wir ihn basierend auf dem Body einstellen, erhalten wir etwas wie das hier:

Indem wir die Höhe des Bodys auf 100% setzen, können wir den Perspektivenursprung wie folgt auf die Mitte des Viewports setzen:

html {
  height: 100%;
  overflow: hidden;
}

body {
  height: 100%;
  overflow-y: scroll;
}

Für einen einfachen <button> sieht das CSS so aus:

button {
  position: relative;
  display: inline-block;
  padding: 4px 16px;
  border: 0;
  background-color: blue;
  background-image: radial-gradient(ellipse at top, rgba(255, 255, 255, 0.15) 50%, transparent);
  color: #222;
  transform-style: preserve-3d;
  transform: translateZ(20px);
}

button::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  transform-origin: 0% 0%;
  transform: rotateX(-90deg);
}

button::after {
  content: "";
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  transform-origin: 0% 0%;
  transform: rotateY(90deg);
}

Aber wie bekommen wir 4 Seiten für jeden Button mit nur 2 Pseudo-Elementen? JavaScript! Wenn wir das Hinzufügen zusätzlicher Wrapper zu jedem Button vermeiden wollen (was wir tun), benötigen wir Skripte, um die obere Seite nach unten und die linke Seite nach rechts zu verschieben, je nachdem, wo sich der Button relativ zum Viewport des Benutzers befindet. Das Skript zum Wechseln der oberen mit der unteren Seite des Buttons ist ziemlich geradlinig – das Ändern von oben/unten oder rechts/links Seiten tritt nur beim Laden und beim Ändern der Größe auf, und oben/unten nur beim Scrollen auf.

$(window).on("load resize", function() {
  topHalf();
  leftHalf();
});

$("body").scroll(function() {
  topHalf();
});

function topHalf() {
  $("button").each(function() {
    var self = $(this),
        offTop = self.offset().top,
        scrTop = $(window).scrollTop(),
        halfWindowHeight = ($(window).height())/2;

    self.toggleClass("top-half", (offTop - scrTop) < halfWindowHeight);
  });
}

function leftHalf() {
  $("button").each(function() {
    var self = $(this),
        offLeft = self.offset().left,
        halfWindowWidth = ($(window).width())/2;

    self.toggleClass("left-half", offLeft < halfWindowWidth);
  });
}

Hinweis des Herausgebers: Dies könnte sicherlich etwas umstrukturiert werden, um Struktur zu verleihen und Effizienz zu gewinnen. Fühlen Sie sich frei, den folgenden Pen zu forken und es zu versuchen!

Einige neue Klassen helfen bei der Positionierung der Seiten:

button.top-half::before {
  top: auto;
  bottom: 0;
  transform-origin: 100% 100%;
  transform: rotateX(90deg);
}

button.left-half::after {
  left: auto;
  right: 0;
  transform-origin: 100% 100%;
  transform: rotateY(-90deg);
}

Beachten Sie, dass Sie, wenn Sie Klassen zum Floaten der Buttons verwenden (z. B. .pull-left und .pull-right wie in Twitter Bootstrap), wissen, wo jeder Button horizontal positioniert ist und somit die Hälfte des JavaScript-Codes überspringen können.

Hier ist eine stilisierte Demo zum Ausprobieren. Sie hat einen animierten Push-Down-Effekt für die Buttons und enthält einige andere 3D-Elemente, die kein JavaScript erfordern.

Check out this Pen!

Eine ähnliche Technik kann auch verwendet werden, um den 3D Inset Parallax-Effekt auf eine sehr grobe Weise zu replizieren. Es ist etwas komplexer, erfordert aber kein JavaScript.

Check out this Pen!