Der Effekt ist unten dargestellt:
Demo ansehen Quellcode herunterladen
HTML-Struktur
Apple TV ist ein hochauflösendes TV-Set-Top-Box-Produkt, das Apple nach Airport Express auf den Markt gebracht hat. Wenn Sie es jemals verwendet haben, werden Sie sicherlich von den coolen visuellen Filmplakateffekten angezogen sein.
Die HTML-Struktur dieses visuellen Differenzeffekts verwendet ein
<div class="poster"> <div class="shine"></div> <div class="layer-1"></div> <div class="layer-2"></div> <div class="layer-3"></div> <div class="layer-4"></div> <div class="layer-5"></div> </div> <div.shine>是用于制作流光效果的图层。
CSS-Stil
Damit das umhüllte Element .poster einen 3D-Rotationseffekt erzeugt, muss sein übergeordnetes Element die Perspektive und den Transformationsstil festlegen.
body { background: linear-gradient(to bottom, #f6f7fc 0%,#d5e1e8 40%); transform-style: preserve-3d; transform: perspective(800px); }
Die Postergröße ist hier auf feste 320 x 500 Pixel eingestellt, zentriert relativ zur Seite, was einen abgerundeten Eckeneffekt und einige Schatteneffekte ergibt.
.poster { width: 320px; height: 500px; position: absolute; top: 50%; left: 50%; margin: -250px 0 0 -160px; border-radius: 5px; box-shadow: 0 45px 100px rgba(0, 0, 0, 0.4); overflow:hidden; }
Das Poster wird mit der absoluten Positionierungsmethode zentriert: links und oben sind jeweils 50 % und dann werden margin-left und margin-top auf negative Breiten- und Höhenwerte gesetzt.
Alle „Ebenen“ im Poster können über den div[class*="layer-"]-Selektor ausgewählt werden. Alle Ebenen sind auf absolute Positionierung eingestellt, das Hintergrundbild wird nicht wiederholt, die Hintergrundposition ist auf die obere linke Ecke eingestellt und die Größe des Hintergrunds ist auf 100 % Breite und automatische Höhe eingestellt.
div[class*="layer-"] { position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; background-size: 100% auto; background-repeat: no-repeat; background-position: 0 0; transition:0.1s; }
Beachten Sie, dass die Werte der oberen, linken, rechten und unteren Attribute im obigen Code alle -10 Pixel betragen. Sie werden verwendet, um die Abmessungen der Ebene um 20 Pixel größer zu machen als die Abmessungen des Posters. Der Grund hierfür besteht darin, die Kanten der Ebene auszublenden und so einen visuellen Unterschiedseffekt zu erzielen.
Legen Sie schließlich für jede Ebene ein Hintergrundbild fest.
.layer-1 { background-image: url('images/1.png'); } .layer-2 { background-image: url('images/2.png'); } .layer-3 { top: 0; bottom: 0; left: 0; right: 0; background-image: url('images/3.png'); } .layer-4 { background-image: url('images/4.png'); } .layer-5 { background-image: url('images/5.png'); }
JavaScript
Das Prinzip dieses visuellen Differenzeffekts besteht darin, dass sich jedes Mal, wenn der Benutzer die Maus bewegt, die Eigenschaften „TranslateY“, „Rotate“ und „RotateY“ von .poster entsprechend der Position der Maus ändern. Je weiter die Maus von der oberen linken Ecke entfernt ist, desto größer ist der Bereich, in dem die Animation sichtbar ist.
Die Berechnungsformel ähnelt offsetX = 0,5 – Mausposition / Breite des Fensters.
Um jeder Ebene unterschiedliche Animationsgeschwindigkeiten zu verleihen, muss diese mit einem benutzerdefinierten Animationsgeschwindigkeitswert multipliziert werden. Dieser Wert wird durch data-offset="number" im HTML-Tag bereitgestellt.
<div data-offset="-2" class="layer-1"></div> <div class="layer-2"></div> <div data-offset="1" class="layer-3"></div> <div data-offset="3" class="layer-4"></div> <div data-offset="10" class="layer-5"></div>
Je größer der Wert des Datenversatzes ist, desto größer ist der sichtbare Animationsbereich.
Der JS-Code für den gesamten visuellen Differenzeffekt lautet wie folgt:
var $poster = $('.poster'), $shine = $('.shine'), $layer = $('div[class*="layer-"]'); $(window).on('mousemove', function(e) { var w = $(window).width(), //窗口宽度 h = $(window).height(), /窗口高度 offsetX = 0.5 - e.pageX / w, //鼠标X坐标 offsetY = 0.5 - e.pageY / h, //鼠标Y坐标 dy = e.pageY - h / 2, //@h/2 = 海报容器中心 dx = e.pageX - w / 2, //@w/2 = 海报容器中心 theta = Math.atan2(dy, dx), //鼠标和海报中心的RAD角度 angle = theta * 180 / Math.PI - 90, //转换 rad 为 degrees offsetPoster = $poster.data('offset'), transformPoster = 'translateY(' + -offsetX * offsetPoster + 'px) rotateX(' + (-offsetY * offsetPoster) + 'deg) rotateY(' + (offsetX * (offsetPoster * 2)) + 'deg)'; //get angle between 0-360 if (angle < 0) { angle = angle + 360; } //gradient angle and opacity $shine.css('background', 'linear-gradient(' + angle + 'deg, rgba(255,255,255,' + e.pageY / h * .5 + ') 0%,rgba(255,255,255,0) 80%)'); //poster transform $poster.css('transform', transformPoster); //parallax foreach layer $layer.each(function() { var $this = $(this), offsetLayer = $this.data('offset') || 0, transformLayer = 'translateX(' + offsetX * offsetLayer + 'px) translateY(' + offsetY * offsetLayer + 'px)'; $this.css('transform', transformLayer); });