効果は以下のとおりです:
HTML 構造
Apple TV は、Airport Express の後に Apple が発売した高解像度テレビのセットトップボックス製品です。使ったことがある人なら、きっとそのクールな映画ポスターの視覚効果に魅了されるでしょう。
この視覚的な差分エフェクトの HTML 構造は、
<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 スタイル
ラップされた要素 .poster で 3D 回転効果を作成するには、その親要素で遠近法と変換スタイルを設定する必要があります。
body { background: linear-gradient(to bottom, #f6f7fc 0%,#d5e1e8 40%); transform-style: preserve-3d; transform: perspective(800px); }
ここでのポスターのサイズは、ページに対して中央に固定された 320x500 ピクセルに設定されており、角が丸い効果といくつかの影の効果が与えられています。
.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; }
ポスターは絶対配置方法を使用して中央に配置されます。left と top はそれぞれ 50% で、margin-left と margin-top は負の幅と高さの値に設定されます。
ポスター内のすべての「レイヤー」は、div[class*="layer-"] セレクターを通じて選択できます。すべてのレイヤーは絶対位置に設定され、背景画像は繰り返されず、background-position は左上隅に設定され、背景のサイズは幅 100% と自動高さに設定されます。
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; }
上記のコードの top、left、right、bottom 属性の値はすべて -10 ピクセルであることに注意してください。これらは、レイヤーの寸法をポスターの寸法より 20 ピクセル大きくするために使用されます。この理由は、視覚的な差分エフェクトを作成するときにレイヤーのエッジを非表示にするためです。
最後に各レイヤーの背景画像を設定します。
.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
この視覚的な差異効果の原理は、ユーザーがマウスを動かすたびに、.poster のtranslateY、rotate、rotateY プロパティがマウスの位置に応じて変化することです。マウスが左上隅から離れるほど、アニメーションが表示される領域が広がります。
計算式は、offsetX = 0.5 – マウスの位置 / ウィンドウの幅に似ています。
各レイヤーに異なるアニメーション速度を与えるには、カスタム アニメーション速度値を掛ける必要があります。この値は HTML タグの data-offset="number" で指定されます。
<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>
data-offset の値が大きいほど、表示されるアニメーション領域が大きくなります。
視覚的な差分エフェクト全体の JS コードは次のとおりです:
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); });