纯CSS3 的transform 3D变换实现翻牌效果
2017-04-13 22:40

CSS3的transform 3D实现翻牌效果

翻牌效果最近似乎也成了前端热衷的一种页面特效,这得益于CSS3 transform 3D变换的普及。不过虽然浏览器都支持transform 3D了,可是还有很多前端对transform 3D变换掌握的不太好,本文就通过实现翻牌效果来讲一下transform 3D的使用。

transform 3D有rotateX,rotateY,rotateZ,translateX,translateY,translateZ等css函数。我们的翻牌效果用到的就是rotateY。

如果你还不知道什么是翻牌效果,那么先睹为快:CSS3翻牌效果。记住在支持transform的浏览器中体验。

翻牌效果截图如下:

blob.png

翻牌效果的实现原理

blob.png

这是一张扑克牌,当鼠标放上去的时候翻转为正面

blob.png

这个翻转是对于Y轴进行的transform3D变换,所以要使用rotateY来实现。

使用transform3D,我们要先建立一个舞台。

<div class="fc_wrapper">
</div>

舞台上要设置perspective属性,perspective属性代表我们距离舞台的距离。

.fc_wrapper{
    width:150px;
    height:235px;
    box-sizing:border-box;
    border:1px solid #e67e22;
    perspective:1000px;
}

有了舞台,我们要添加进行3D变换的容器。

<div class="fc_wrapper">
    <div class="fc_inner">
    </div>
</div>

容器中要设置transform-style:preserve-3d和backface-visibility:hidden属性。

.fc_inner{
    position:relative;
    width:100%;
    height:100%;
    transform-style: preserve-3d;
    backface-visibility: hidden;
    transform-origin: center center;
    transition:transform 0.8s;
}

这里transform-style属性有两个值,一个是flat,表示平面变换,一个preserve-3d表示3D变换,backface-visibility:hidden属性表示在3D空间中,后面的元素会被前面的元素挡住看不到。注意这两个值要写在会有transform变换的元素上,不然的话,会有一些不符合现实3D效果的结果呈现。比如在rotateY(-180deg)时,本来应该后面的JK出现,如果把backfac-visibility:hidden写在舞台元素上,在chrome下正常,但是在FF下,看不到JK,只能看到背景图案。

然后布局两张图片,为absolute定位,一张在上面,一张在下面,在下面的图片通过rotateY(180deg)翻转。

<div class="fc_wrapper">
    <div class="fc_inner">
        <div class="fc_front"><img src="images/jkbg.jpg"/></div>
        <div class="fc_back"><img src="images/jkforce.jpg"/></div>
    </div>
</div>
.fc_front{
    position:absolute;
    z-index: 4;
    left:0;
    top:0;
    width:100%;
    height:100%;
}
.fc_back{
    position:absolute;
    z-index: 2;
    left:0;
    top:0;
    width:100%;
    height:100%;
    transform-origin: center center;
    transform: rotateY(180deg);
}
.fc_front img,.fc_back img{
    width:100%;
    height:100%;
}

最后,我们给舞台添加一个::hover伪类,让容器通过rotateY翻转-180deg。

.fc_wrapper:hover .fc_inner{
    transform: rotateY(-180deg) translateZ(0);
}

这样,在鼠标悬停时,扑克牌会翻转到正面,在鼠标移开时,扑克牌会翻转到背面。

完整的代码如下:

<style>
    .fc_cont{
        margin:15px;
        padding:15px;
        background:#f7f7f7;
        border:1px solid #bababa;
    }
    .fc_cont ul{margin:0;padding:0;list-style:none;}
    .fc_cont ul li{
        display:inline-block;
    }
    .fc_cont ul li + li{
        margin-top:12px;
        margin-left:12px;
    }
    .fc_wrapper{
        width:150px;
        height:235px;
        box-sizing:border-box;
        border:1px solid #e67e22;
        perspective:1000px;
    }
    .fc_wrapper:hover .fc_inner{
        transform: rotateY(-180deg) translateZ(0);
    }
    .fc_inner{
        position:relative;
        width:100%;
        height:100%;
        transform-style: preserve-3d;
        backface-visibility: hidden;
        transform-origin: center center;
        transition:transform 0.8s;
    }
    .fc_front{
        position:absolute;
        z-index: 4;
        left:0;
        top:0;
        width:100%;
        height:100%;
    }
    .fc_back{
        position:absolute;
        z-index: 2;
        left:0;
        top:0;
        width:100%;
        height:100%;
        transform-origin: center center;
        transform: rotateY(180deg);
    }
    .fc_front img,.fc_back img{
        width:100%;
        height:100%;
    }
</style>

<div class="fc_cont">
<ul>
    <li>
        <div class="fc_wrapper">
            <div class="fc_inner">
                <div class="fc_front"><img src="images/jkbg.jpg"/></div>
                <div class="fc_back"><img src="images/jkforce.jpg"/></div>
            </div>
        </div>
    </li>
</ul>
</div>

这两张图片,通过absolute定位重叠到一起,通过z-Index属性一张在上面,一张在下面,在下面的通过rotateY(180deg)沿着Y轴翻转180deg,这样在容器".fc_inner"翻转rotateY(-180deg)或者rotateY(180deg)时,它才能以正面占展现。这两张图片的zIndex,前面的高,后面的低,使用transform-style:preserve-3d和backface-visibility:hidden的属性作用是在容器翻转180deg时,后面zIndex低的图片能够在3D环境中跑到前面现实,如果没有这两个属性,那么背景图片的层会一直高于正面图片的层,也就看不到正面图片了。

补充:

经过测试发现,在360浏览器上,这个翻牌效果看不见正面的K,处理方法是,给fc_front和fc_back也添加上“backface-visibility:hidden”属性。

所以修改后这两个类的样式变为:

.fc_front{
    position:absolute;
    z-index: 4;
    left:0;
    top:0;
    width:100%;
    height:100%;
    backface-visibility: hidden;
}
.fc_back{
   position:absolute;
    z-index: 2;
    left:0;
    top:0;
    width:100%;
    height:100%;
    transform-origin: center center;
    transform: rotateY(180deg);
    backface-visibility: hidden;
}

另外,即使这样,在360浏览器中还有一个问题,就是多次hover触发,鼠标离开时,没有transition的动画过渡,直接硬切换到牌的背面了。这个应该是360浏览器的一个bug,也许以后会改正。目前没有找到解决的办法。

总结

这个翻牌效果使用了css3的transform3D来实现。并且其他的有关transform3D的效果实现都应该按照这种顺序:

@1:设置舞台,舞台添加persepective属性。

@2:设置发生变换的容器,添加transform-style:preserve-3d和backface-visibility:hidden两个属性,你如果想要透视效果,那可以把backface-visibility属性去掉。

@3:对容器中的元素进行3D空间的布局,如本例中对下面图片的rotateY的设置。

@4:对容器使用transform3D变化,如rotateX,rotateY,translateZ等。


原创文章,转载请注明来自:妹纸前端-www.webfront-js.com.
阅读(6120)
辛苦了,打赏喝个咖啡
微信
支付宝
妹纸前端
妹纸前端工作室 | 文章不断更新中
京ICP备16005385号-1