视差图得到视差
在之前的教程中,我向您展示了如何使用CSS 3D变换创建等轴测网格布局 。 这是非常具有挑战性的,因为诸如Firefox之类的一些浏览器在如何在三维平面上呈现元素方面具有略有不同的方法。
在本教程中,我们将通过受Apple TV界面的启发,构建3D视差翻转效果,从而继续探索3D变换。 我们仍将使用Envato Elements作为内容的灵感; 这是我们正在努力的方向:
将鼠标悬停在缩略图上,并在光标周围移动; 缩略图将根据光标位置和移动方向倾斜。
透视:入门
作为人类,我们的视野仅限于消失的地平线,而我们的双目视觉创造了我们所感知的视角 。 透视有助于我们将物体解释得更远,而不仅仅是变小。
上一教程中的等距网格未考虑“透视”。 实际上保留了网格的大小(高度和宽度)。 实际上,由于透视图,我们应该看到网格的最远端缩小。
在CSS中,我们可以通过perspective()函数将透视图添加到3D转换中。 值得注意的是,必须先添加perspective()才能使其生效,然后再使用其他转换函数,例如rotate()和translate() 。 它还需要一个值,该值定义相对于元素的视图距离。 是否应该从远处或附近观看元素。
#perspective {
transform: perspective(600px) rotateX(60deg) rotateY(0deg) rotateZ(-45deg);
}
这就是我们使用CSS渲染3D平面的方式。 现在,让我们看看如何应用它来创建视差效果 。 我们将从HTML开始:
HTML标记
如果您完全按照我们之前的教程进行操作,您会发现HTML标记非常相似。 在这里,我们有一个div ,其中的ItemCard类包装了名称,图像和指向Envato Elements上一个项目的链接。
<div class="ItemCard">
<a class="ItemCard__dest cover" href="https://elements.envato.com/items/type/fonts/campfire-stories-font-duo-DH6LQG" target="_blank"></a>
<figure class="ItemCard__thumb">
<img src="./images/001.jpg" height="340" width="510" alt="">
</figure>
<div class="ItemCard__layer cover"></div>
<div class="ItemCard__summary cover">
<span class="ItemCard__meta category">Fonts</span>
<h2 class="ItemCard__title">Herbert Lemuel</h2>
<address class="ItemCard__meta designer">August10</address>
</div>
</div>
从上至下添加上述HTML标记。
CSS
我们首先添加一些重置样式,在这种情况下,将元素的框大小设置为border-box ,除去figure元素的边距,并使图像流畅。
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
figure {
margin: 0;
}
img {
max-width: 100%;
height: auto;
}
完成后,我们向ItemCard添加了一些样式。 除了border-radius和box-shadow类的美学规则外,我们还定义了元素过渡和变换,包括perspective()函数。
.ItemCard {
position:relative;
display:flex;
overflow:hidden;
flex-direction:column;
cursor:pointer;
border-radius:6px;
box-shadow:0 2px 10px rgba( 0,0,0,.3 );
align-items:center;
max-width: 510px;
height: auto;
transition: transform .5s cubic-bezier(.215, .61, .355, 1),
box-shadow .5s cubic-bezier(.215, .61, .355, 1);
transform: perspective( 600px ) translate3d( 0, 0, 0 );
}
元样式
接下来,我们为ItemCard子元素添加样式; 项目名称,项目作者名称和项目类别。 同样,样式定义这些元素的可见性,位置,大小,过渡和转换。
.ItemCard .cover {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.ItemCard__dest {
z-index: 30;
display: block;
}
.ItemCard__thumb {
position: relative;
z-index: 3;
padding: 0;
transition: transform .2s;
}
.ItemCard__thumb img {
display: block;
transition: box-shadow 0.2s;
}
.ItemCard__layer {
z-index: 10;
transition: opacity 1s cubic-bezier(0.215, 0.61, 0.355, 1);
opacity: 0;
background: linear-gradient(120deg, #9d50bb 0%, #4096ee 100%);
}
.ItemCard__summary {
z-index: 20;
padding: 25px;
display: flex;
flex-direction: column;
transform: perspective(600px) translate3d(0, 100%, 0);
text-align: center;
color: #fff;
justify-content: center;
}
.ItemCard__title {
margin: 8px 0;
font-weight: 900;
transform: translate3d(0, 150px, 50px);
text-transform: uppercase;
color: #fff;
font-size: 19px;
line-height: 1.48;
}
3D渲染
添加以下样式,以使ItemCard和.ItemCard__summary的子元素与三维渲染兼容。
/**
* Preserve 3D elements for the descendants
*/
.ItemCard,
.ItemCard__summary {
transform-style: preserve-3d;
backface-visibility: hidden;
}
徘徊
ItemCard悬停状态样式定义box-shadow以及某些子元素的Z轴:
/**
* Hover States
*/
.ItemCard:hover {
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
}
.ItemCard:hover .ItemCard__layer {
opacity: .9;
}
.ItemCard:hover .ItemCard__title {
transform: translate3d(0, 0, 50px);
}
.ItemCard:hover .ItemCard__meta.category {
transform: translate3d(0, 0, 40px);
}
.ItemCard:hover .ItemCard__meta.designer {
transition-delay: .05s;
transform: translate3d(0, 0, 20px);
}
此时,您将获得类似于以下内容的内容:
jQuery的视差效果
我们将在此处利用一些jQuery,因此请确保您要在文档中的某个位置链接到jQuery。 在CodePen中,添加https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js作为外部JavaScript路径。
通过两个jQuery Events mousemove和mouseout应用视差效果。 当光标移到目标元素上时,将触发mousemove事件。 在这种情况下, .ItemCard 。 当鼠标光标已经在目标元素外部时,将触发mouseout 。
$( document )
.on( "mousemove", ".ItemCard", function( event ) {
} )
.on( "mouseout", ".ItemCard", function() {
} );
在mousemove事件期间,我们检索鼠标光标的坐标,确定ItemCard旋转,并通过添加内联样式来应用这些数字。 在mouseout事件期间,我们将删除内联样式,以便ItemCard返回其初始位置。
$( document )
.on( "mousemove", ".ItemCard", function( event ) {
/**
* Half of the `ItemCard` width
* @type {integer}
*/
var halfW = ( this.clientWidth / 2 );
/**
* Half of the `ItemCard` height
* @type {integer}
*/
var halfH = ( this.clientHeight / 2 );
/**
* Mouse cursor X coordinate
* @type {integer}
*/
var coorX = ( halfW - ( event.pageX - this.offsetLeft ) );
/**
* Mouse cursor Y coordinate
* @type {integer}
*/
var coorY = ( halfH - ( event.pageY - this.offsetTop ) );
/**
* X Rotation degree of `ItemCard`
* @type {integer}
*/
var degX = ( ( coorY / halfH ) * 10 ) + 'deg'; // max. degree = 10
/**
* Y Rotation degree of `ItemCard`
* @type {integer}
*/
var degY = ( ( coorX / halfW ) * -10 ) + 'deg'; // max. degree = 10
/**
* Add the inline styles
*/
$( this ).css( 'transform', function() {
return 'perspective( 600px ) translate3d( 0, -2px, 0 ) scale(1.1) rotateX('+ degX +') rotateY('+ degY +')';
} )
.children( '.ItemCard__summary' )
.css( 'transform', function() {
return 'perspective( 600px ) translate3d( 0, 0, 0 ) rotateX('+ degX +') rotateY('+ degY +')';
} );
} )
.on( "mouseout", ".ItemCard", function() {
/**
* Remove the inline styles
*/
$( this ).removeAttr( 'style' )
.children( '.ItemCard__summary' )
.removeAttr( 'style' );
} );
这就是包装。
结语
在本教程中,我们学习了如何利用3D变换来构建受Apple TV启发的3D视差效果。
请记住,这种效果在启用触摸的设备上无法很好地发挥作用,因此您需要考虑某种后备方式,可能需要使用Touch Events复制视差效果–我将把它留在桌面上供您解决!
有用的资源
- DesandroCSS 3D透视简介
- 实例透视— Webkit
- 网络视差