CSS3 transform3D 圖片翻轉效果
經常能在展示案例logo的時候見到。logo原本是黑白色,滑鼠移入時logo翻轉成為彩色。
一、實現一張圖片的翻轉
一、HTML結構
<div class="stage">
<div class="flipBox">
<figure class="pic front">Front</figure>
<figure class="pic back">Back</figure>
</div>
</div>
上述HTML的結構是:
- div.stage規定了一個3D舞臺,基本上所有使用CSS3 3D變換的實現都會這麼做,規定perspective樣式從而達到透視效果
- div.flipBox是真正實現翻面的容器,稍後將對它進行3D變換
- figure代表兩張圖片,一張是正面,一張是背面
思路是:將figure.front和figure.back作為翻轉圖片的正反面。圖片翻轉後,figure.back將變成面對使用者的那一面,figure.front將背對使用者。
初始狀態下figure.back是水平翻轉過的(即transform: rotateY(180deg)),這樣圖片翻轉後背面的文字將正著顯示(否則翻轉過來以後背面的文字是倒著的——因為反轉之前是正著的嘛~)。
二、CSS結構
body,figure {
margin: 0;
padding : 0;
}
.stage {
width: 200px;
height: 100px;
margin: 40px;
perspective: 1000px;
}
.flipBox {
width: 200px;
height: 100px;
position: relative;
transform-style: preserve-3d;
transition: transform 1s;
}
.pic {
width: 200px;
height: 100px;
font-size: 24px;
color: #fff;
line-height : 100px;
text-align: center;
position: absolute;
top: 0;
left: 0;
backface-visibility: hidden;
}
.front {
background: #f00;
}
.back {
background: #090;
transform: rotateY(180deg);
}
現在分析每個元素的CSS:
body,figure {
margin: 0;
padding: 0;
}
沒什麼好說的,去掉內外邊距!
.stage {
width: 200px;
height: 100px;
margin: 40px;
perspective: 1000px;
}
為3D舞臺定義樣式。margin是為了距離瀏覽器左邊和上邊有一些距離,讓變換顯示的更完整。perspective規定了3D元素距攝像機(或人眼)的距離,值越小3D元素離人眼越近,值越大3D元素離人眼越遠。
.flipBox {
width: 200px;
height: 100px;
position: relative;
transform-style: preserve-3d;
transition: transform 1s;
}
為翻轉盒子定義樣式。這個元素是真正進行3D變換的元素。其position屬性是為其兩個子figure元素創造定位點,以便兩個子figure元素定位到div.flipBox的左上角實現兩張圖片的對齊。transform-style屬性是必須的,這規定了div.flipBox元素的後代元素是以哪種形式進行3D變換(preserve-3d表示後代元素任然以3d的模式進行變換;另一個值flat表示只對div.flipBox進行3D變換,後代元素則只是div.flipBox平面中的內容,不進行3D變換),這和After Effect中的偽3D十分相似。transition規定只變換transform屬性,時間為1s.
.pic {
width: 200px;
height: 100px;
font-size: 24px;
color: #fff;
line-height: 100px;
text-align: center;
position: absolute;
top: 0;
left: 0;
backface-visibility: hidden;
}
為兩張圖片(這裡的兩個figure)規定統一的樣式。使用絕對定位,定位到div.flipBox的左上角,而兩個figure的大小又是一樣的,所以完美重疊。backface-visibility是一個重要的屬性,它規定背對使用者的3D元素是否顯示,這裡應該規定為不顯示(hidden),否則不該顯示背面的時候背面會顯示出來。比如初始狀態,顯然不應該顯示figure.back,但又因為figure.back是後渲染的,所以會覆蓋在figure.front上,我們之前為figure.back規定了transform: rotateY(180deg),所以figure.front是背對使用者的,將不顯示。再比如翻轉過後,figure.front會擋在figure.back前面,不過此時figure.front將會背對使用者,所以被backface-visibility隱藏了,這正是我們想要的。
.front {
background: #f00;
}
規定了圖片正面為紅色。
.back {
background: #090;
transform: rotateY(180deg);
}
規定了圖片背面為綠色,同時,transform: rotateY(180deg)規定在初始狀態,figure.back是水平翻轉180°的。
三、開始旋轉圖片
.stage:hover .flipBox {
transform: rotateY(-180deg);
}
當滑鼠移入3D舞臺時,將div.flipBox旋轉-180°,實現圖片翻轉效果。這裡讓div.flipBox旋轉+180°也是可以的,只是旋轉的方向不同罷了。
二、案例
一、圖片準備
為減少HTTP請求,這裡使用精靈圖。
圖片大小為200*200,分上下兩部分,上方為翻轉圖片的正面(黑白),下方為翻轉圖片的背面(彩色)。上方和下方的logo都經過水平居中和垂直居中,以保證翻轉前後logo位置一致。
二、程式碼實現
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>JavaScript Study</title>
<style>
html,body,ul,li,a,figure,h4 {
padding: 0;
margin: 0;
}
ul {
list-style: none;
}
h4 {
display: none;
}
.Stage {
width: 604px;
height: 203px;
margin: 50px;
border-left: 1px solid #f5f5f5;
border-top: 1px solid #f5f5f5;
perspective: 10000px;
}
.trigger {
display: block;
float: left;
width: 200px;
height:100px;
border-right: 1px solid #f5f5f5;
border-bottom: 1px solid #f5f5f5;
position: relative;
}
.flipBox {
display: block;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 1.2s;
transition-delay: 0.03s;
}
.trigger:hover .flipBox {
transform: perspective(10000px) rotateY(-180deg); /*這裡的perspective為每個flipBox規定單獨的視點距離,解決Chrome中統一視點的問題*/
}
.plane {
width: 200px;
height: 100px;
position: absolute;
top: 0;
left: 0;
backface-visibility: hidden;
}
.back {
transform: rotateY(180deg);
}
.logo1 figure.front {
background: url("pic.png") center 0 no-repeat;
}
.logo2 figure.front {
background: url("pic_2.png") center 0 no-repeat;
}
.logo3 figure.front {
background: url("pic_3.png") center 0 no-repeat;
}
.logo4 figure.front {
background: url("pic_4.png") center 0 no-repeat;
}
.logo5 figure.front {
background: url("pic_5.png") center 0 no-repeat;
}
.logo6 figure.front {
background: url("pic_6.png") center 0 no-repeat;
}
.logo1 figure.back {
background: url("pic.png") center -100px no-repeat;
}
.logo2 figure.back {
background: url("pic_2.png") center -100px no-repeat;
}
.logo3 figure.back {
background: url("pic_3.png") center -100px no-repeat;
}
.logo4 figure.back {
background: url("pic_4.png") center -100px no-repeat;
}
.logo5 figure.back {
background: url("pic_5.png") center -100px no-repeat;
}
.logo6 figure.back {
background: url("pic_6.png") center -100px no-repeat;
}
</style>
</head>
<body>
<div class="Stage">
<ul class="logo_sets">
<li class="trigger">
<a class="flipBox logo1" href="#">
<h4>Fun Games</h4>
<figure class="plane front"></figure>
<figure class="plane back"></figure>
</a>
</li>
<li class="trigger">
<a class="flipBox logo2" href="#">
<h4>Man Style</h4>
<figure class="plane front"></figure>
<figure class="plane back"></figure>
</a>
</li>
<li class="trigger">
<a class="flipBox logo3" href="#">
<h4>Sims.</h4>
<figure class="plane front"></figure>
<figure class="plane back"></figure>
</a>
</li>
<li class="trigger">
<a class="flipBox logo4" href="#">
<h4>Googla</h4>
<figure class="plane front"></figure>
<figure class="plane back"></figure>
</a>
</li>
<li class="trigger">
<a class="flipBox logo5" href="#">
<h4>JavaScript</h4>
<figure class="plane front"></figure>
<figure class="plane back"></figure>
</a>
</li>
<li class="trigger">
<a class="flipBox logo6" href="#">
<h4>Felix</h4>
<figure class="plane front"></figure>
<figure class="plane back"></figure>
</a>
</li>
</ul>
</div>
</body>
</html>