Hallo zusammen, im heutigen Eintrag möchte ich erneut auf das schlanke Zepto.js Framework eingehen und ein kleines Tutorial vorstellen!

Ziel des Tutorials ist es, mit Hilfe von CSS3 und zepto.js Elemente auf unserer Webseite mit einem 3D „Umdreh-Effekt“ auszustatten! Idealerweise verbinden wir diese Effekte mit den Gesten, die uns ein mobiles Gerät zur Verfügung stellt (z.B. Elemente durch „wischen“ umdrehen) – Für Desktop Rechner bauen wir einen Fallback (Klick auf das Element) ein.

Zunächst aber ein paar wichtige Punkte:

  • Zepto.js animiert mit Hilfe von CSS (-Transitions) und wird damit nur auf aktuellen Browsern (Chrome 5+, Safari 5+, FF 4+) funktionieren.
  • Die 3D Effekte funktionieren bisher nur in wenigen Browsern ohne Probleme
  • Zepto.js ist aktuell noch in der Beta-Phase! (Ich meine aber gelesen zu haben das in den kommenden Tagen ein neues Release ansteht!)

3D Effekte mit Hilfe von CSS!

Zuerst laden wir uns die aktuellste Version von Zepto.js von der offiziellen Webseite und legen diese lokal in unserem Entwicklungs-Ordner ab. Anschließend erstellen wir uns eine kleine HTML Seite… Hier ein kleiner Auszug für einen „Schnellstart“:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Tutorial: 3D Effekte mit zepto.js</title>
</head>
<body>

    <div class="container">
        <div class="front">Vorderseite</div>
        <div class="back">Rückseite</div>
    </div>

    <div class="container">
        <div class="front">Vorderseite</div>
        <div class="back">Rückseite</div>
    </div>

    <script src="js/zepto.js"></script>
    <script>
        $(document).ready(function(){
            ;
        });
    </script>
</body>
</html>

Damit hätten wir also ein kleines HTML Grundgerüst, mit dem wir arbeiten können!

3d tutorial abbildung Als nächstes müssen wir etwas CSS hinzufügen, damit aus den „front“ und „back“ DIVs Vorder- und Rückseiten werden (Siehe Abbildung links). Außerdem möchten wir die Rückseite umgedreht darstellen damit sie sich „realistisch“ umdrehen lässt!
Stellt euch einfach ein Blatt Papier vor – Wenn es vor euch auf dem Tisch liegt, seht ihr die Vorderseite. Um die Rückseite zu sehen müsst ihr es umdrehen 😉

Da wir die beiden DIVs absolut positionieren müssen, sollten wir zunächst das CSS des umgebenden „container“-DIV vorbereiten. Das sieht dann etwa so aus:

.container {
    width: 320px;
    height: 240px;
    position: relative;
    
    perspective: 800px;
    -moz-perspective: 800px;
    -webkit-perspective: 800px;
}

Das „perspektive“ Attribut wird für den 3D Effekt benötigt – Das Attribut sagt dem Browser wie „tief“ die Animation in den Raum hineinzeigt… Am besten ihr probiert später selbst aus wie sich der Effekt verändert wenn ihr die Werte ändert (kleinere Werte sorgen für einen stärkeren Effekt).

Weiter gehts – Um unsere Rückseiten tatsächlich umzudrehen benutzen wir das CSS3 Feature transform. Außerdem benutzen wir noch die Attribute transform-style und backface-visibility! Das sieht dann etwa so aus:

.front, .back {
    position: absolute;
    background: #eee;
    width: 320px;
    height: 240px;
    z-index:10;
    
    transform-style: preserve-3d;
    -webkit-transform-style: preserve-3d;
    
    backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}

.back {
    z-index:9;
    
    transform: rotateY(180deg);
    -moz-transform: rotateY(180deg);
    -webkit-transform: rotateY(180deg);
}

Ich möchte noch kurz erklären was wir hier genau gemacht haben:

  • position:absolute
    Sorgt dafür, das die beiden DIVs übereinander dargestellt werden.
  • z-index
    Sagt dem Browser dass das „front“ DIV auf Ebene 10 und das „back“ DIV auf Ebene 8 liegt – Dadurch wird die Vorderseite „über“ der Rückseite dargestellt (im Javascript wird dies nach der animation umgekehrt).
  • transform-style:preserve-3d
    Definiert, das die „transform“ Angaben in 3D dargestellt werden (in Abhängigkeit der Perspektive) – Dies funktioniert allerdings derzeit nur in Webkit Browsern (Chrome, Safari, …).
  • backface-visibility:hidden
    Gibt an, das „umgedrehte“ Objekte nicht dargestellt werden. Soll heißen die „Rückseite“ eines Elements wird nicht dargestellt.
  • transform:rotateY(180deg);
    Sorgt dafür, das unsere „back“ Elemente um 180° auf der Y-Achse gedreht werden

Javascript mit zepto.js

Nachdem wir nun unser CSS haben, kommen wir zum interessanten Teil – Dem Javascript!

/*
 * Bei Zepto müssen wir auf ein paar kleinere Features, 
 * die wir von jQuery gewohnt sind, verzichten:
 * Beispielsweise das wir CSS Attribute mit Werten wie "+=10px" animieren können.
 *
 * Aus diesem Grund benutze ich die "data" Methode zum speichern der aktuellen Grad-Zahl.
 * In den nächsten beiden Zeilen setze ich die Ausgangswerte für sämtliche "front" und "back" DIVs.
 */
$('.container .front').data('deg', 0);
$('.container .back').data('deg', 180);

// Anschließend definiere ich meine "rotate" Funktion.
function rotate(container, dir) {
    // Ich deklariere Variablen für die DIVs und ihre Grad-Zahl.
    var front = $('.front', container),
        front_to = front.data('deg'),
        back = $('.back', container),
        back_to = back.data('deg');
    
    // Haben wir keine Richtung angegeben, drehen wir links rum.
    if (typeof dir == 'undefined' || dir == 'left') {
        front_to = front.data('deg') - 180;
        back_to = back.data('deg') - 180;
    } else {
        // Ich benutze "parseInt", damit hier nicht 180 als String angehangen wird.
        front_to = parseInt(front.data('deg')) + 180;
        back_to = parseInt(back.data('deg')) + 180;
    }
    
    /*
     * Hier passiert die Magie: Wir drehen unsere DIVs!
     * Zusätzlich setze ich den z-index, damit das DIV mit einer Grad-Zahl die 
     * durch 0 oder 360 (0, 360, 720, ...) teilbar ist, "vorne" ist.
     */
    front.animate({rotateY: front_to + 'deg', zIndex:(front_to%360?9:10)}, 750, 'ease-in-out');
    back.animate({rotateY: back_to + 'deg', zIndex:(front_to%360?10:9)}, 750, 'ease-in-out');
    
    // Zu guter letzt speichern wir die neuen Grad-Zahlen ab.
    front.data('deg', front_to);
    back.data('deg', back_to);
};

Es fehlt nur noch eins: Der Event-Handler!

// Wir setzen unsere observer auf die "front" und "back" DIVs.
$('.front,.back', '.container').on('click', function() {
    rotate($(this).parent());
}).swipeLeft(function() {
    rotate($(this).parent(), 'left');
}).swipeRight(function() {
    rotate($(this).parent(), 'right');
});

Wir nutzen hier die „on“ Methode um einen Mausklick-Event abzufangen – Als callback übergeben wir eine Methode in der wir unsere „rotate“ Funktion aufrufen. Der Funktion übergeben wir das „container“ Element, damit wir beide untergeordneten „front“ und „back“ DIVs direkt ansteuern können. Als zweiten Parameter können wir (optional) eine Richtung übergeben – Also ob links- oder rechtsrum gedreht werden soll.

Die nächsten Observer („swipeLeft“ und „swipeRight“) gehören zu einer Spezialität von Zepto. Mit diesen beiden Methoden sind wir in der Lage Gesten auf mobilen Geräten (Smartphones und Tablet PCs) mit Touchscreen zu reagieren. Wir können übrigens auch Methoden wie „swipeUp“ und „swipeDown“ nutzen und die Elemente dann mit Hilfe von transform: rotateX(180deg); animieren, doch da wir diese Geste üblicherweise dazu benutzen um auf einer Seite zu scrollen habe ich davon abgesehen.

Und um das heutige Tutorial abzuschließen möchte ich hier noch kurz den kompletten lauffähigen Quellcode zur Verfügung stellen:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Tutorial: 3D Effekte mit zepto.js</title>
    <style>
    .container {
        width: 320px;
        height: 240px;
        position: relative;
        
        perspective: 800px;
        -moz-perspective: 800px;
        -webkit-perspective: 800px;
    }
    
    .front, .back {
        position: absolute;
    	background: #eee;
        width: 320px;
        height: 240px;
        z-index:10;
        
        transform-style: preserve-3d;
        -moz-transform-style: preserve-3d;
        -webkit-transform-style: preserve-3d;
        
        backface-visibility: hidden;
        -moz-backface-visibility: hidden;
        -webkit-backface-visibility: hidden;
    }
    	
    .back {
        z-index:9;
        
        transform: rotateY(180deg);
        -moz-transform: rotateY(180deg);
        -webkit-transform: rotateY(180deg);
    }
    </style>
</head>
<body>

    <div class="container">
        <div class="front">Vorderseite</div>
        <div class="back">Rückseite</div>
    </div>

    <div class="container">
        <div class="front">Vorderseite</div>
        <div class="back">Rückseite</div>
    </div>

    <script src="js/zepto.js"></script>
    <script>
        $(document).ready(function(){
            $('.container .front').data('deg', 0);
            $('.container .back').data('deg', 180);
            
            
            function rotate(container, dir) {
                var front = $('.front', container),
                    front_to = front.data('deg'),
                    back = $('.back', container),
                    back_to = back.data('deg');
                
                if (typeof dir == 'undefined' || dir == 'left') {
                    front_to = front.data('deg') - 180;
                    back_to = back.data('deg') - 180;
                } else {
                    front_to = parseInt(front.data('deg')) + 180;
                    back_to = parseInt(back.data('deg')) + 180;
                }
                
                front.animate({ rotateY: front_to + 'deg', zIndex: (front_to%360?9:10) }, 750, 'ease-in-out');
                back.animate({ rotateY: back_to + 'deg', zIndex: (front_to%360?10:9) }, 750, 'ease-in-out');
                
                front.data('deg', front_to);
                back.data('deg', back_to);
            };
            
            $('.front,.back').on('click', function() {
                rotate($(this).parent());
            }).swipeLeft(function() {
                rotate($(this).parent(), 'left');
            }).swipeRight(function() {
                rotate($(this).parent(), 'right');
            });
        });
    </script>
</body>
</html>

Und das wars eigentlich auch schon.

Sehr viel mehr als diese paar Zeilen braucht man nicht um ein paar schicke Effekte zu zaubern 🙂 Allerdings könnten wir noch einen Fallback für Browser einbauen, die weder die swipe-Gesten, noch CSS-Transforms o.Ä. kennen, oder? Dieses i-Tüpfelchen möchte ich euch allerdings selbst überlassen – Sozusagen als kleine Übung!

Ich hoffe euch gefällt das Tutorial! Es ist zwar leider noch nicht Praxistauglich (da verhältnismäßig wenige Browser damit umgehen können) doch das ist nur eine Frage der Zeit – Besser ihr wisst schon früh was HTML5 und CSS3 für Features und Möglichkeiten mit sich bringen!
Sobald Zepto in der Version 1.0 erscheint werde ich es wohl für mein nächstes kleines Projekt einsetzen – Vor allem, wenn es eine mobile Ansicht gibt 😉

Mit diesen Worten möchte ich euch eine angenehme Woche wünschen…
Happy Coding!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.