事情是發生在Thibe高中的時候,當時放學時間緊迫,我急著回家打LOL,就在我加速騎著Ubike,頭上剛好飛過一台直升機,我心裡想:「要是能搭直升機就好了!」這時候,我腳下突然變成了腳踏直升機,飛也似地我就回到家了,快速地坐到電腦桌前打開電腦, 眼前突然一片光亮,夢醒了。そうか~這就是腳踏直升機的由來。
今天我們來實作Day #14
CodePen: https://codepen.io/stevetanus/pen/OJZjrjx
<div class="frame">
<div class="card">
<div class="flip">
<div class="front">
<img src="https://100dayscss.com/codepen/bycicle.svg">
<div class="street">
.stripe-$*9
</div>
</div>
<div class="back">
<img src="https://100dayscss.com/codepen/helicopter.svg">
<div class="sky">
.cloud-$*9
</div>
</div>
</div>
</div>
</div>
.frame
中間有一張卡片.card
,.flip
會加上翻轉的CSS屬性,裡面會有.front
和.back
,前方卡片會顯示腳踏車,.stripe-$*9
是九條道路線;後方卡片會顯示直升機,.cloud-$*9
是九片雲彩。
.card {
position: absolute;
width: 320px;
height: 180px;
top: 110px;
left: 40px;
perspective: 800px;
&:hover .flip {
transform: rotateX(180deg) translate3d(0, 0, 0);
box-shadow: 8px -10px 15px 0 rgba(0,0,0,.5);
}
.flip {
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: all 1s ease-in-out;
perspective: 1000px;
box-shadow: 8px 10px 15px 0 rgba(0,0,0,0.5);
}
}
perspective
(透視)值代表我們與物體的距離,距離讓我們看到translate3d
的效果,在內層要再加入transform-style: preserve-3d
讓它以3d顯現,這時候hover.card
就會看見中間的卡片隨著X軸旋轉180度來到後方,離開時就會返回前方,box-shadow
的y值則是相對的,在旋轉前後都為相同的陰影。而.front
跟.back
也要做些處理。
persective: https://www.casper.tw/css/2013/10/11/css-perspective/
rotateX, rotateY: https://ithelp.ithome.com.tw/articles/10135528
CSS 3d: https://www.casper.tw/css/2016/01/24/css-3d/
.front, .back {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
...
backface-visibility: hidden;
text-align: center;
}
.back {
transform: rotateX(180deg); }
backface-visibility: hidden
在3d旋轉的時候必須考慮進去,讓旋轉後的腳踏車、一開始的直升機背面隱藏起來。(我們要注意如果是在.flip
加上背影隱藏就不會有背面的效果了,所以在.flip
內要再創.front
跟.back
的class)
backface-visibility: https://developer.mozilla.org/en-US/docs/Web/CSS/backface-visibility\
.street{
position: absolute;
...
@for $i from 1 through 9 {
.stripe-#{$i} {
position: absolute;
right: -25px;
top: 0;
height: 3px;
width: (2+ $i *2)+px; //每條線的寬度會增加2px
background: #4B4841;
border-radius: 3px;
animation: street (0.8 + random(2) / 10) + s linear (random(10)/10)+ s infinite
// 動畫會在0.8s左右結束,每條線會有0~1s的延遲
}
}
}
// street動畫X軸會往左移-210px,縮小0.8倍
@keyframes street {
0% {
transform: translate3d(0, 0, 0) scaleX(1);
}
100% {
transform: translate3d(-210px,0,0) scaleX(.8);
}
}
@for $i from 1 through 9 {
.cloud-#{$i} {
position: absolute;
right: -25px;
// 雲朵每朵會往下14px
top: (20 + $i * 14) + px;
height: 3px;
// 寬度隨機為10~25px
width: (10 + random(150)/ 10)+ px;
background: #4B4841;
border-radius: 3px;
animation: cloud (0.6 + random(2)/ 10) + s linear (random(10)/ 10) + s infinite;
}
}
cloud動畫和street動畫相同,這邊沒有附上,都是往後210px,縮小0.8倍。
@keyframes bike {
0%, 100% {
transform: scaleY(1);
}
50% {
transform: scaleY(1.05);
}
}
@keyframes helicopter {
0%, 100% {
transform: translate3d(0,-5px,0);
}
50% {
transform: translate3d(0,5px,0);
}
}
可以看到腳踏車跟直升機動畫都是在0%、100%時相同位置,而50%時變大或是下降,配合道路和雲朵往後跑的動畫,形成前進的感覺。
HTML
目標 | 屬性 |
---|---|
翻面元素 | .card 外層卡片、.flip 內層旋轉元素、front 前面、.back 後面 |
CSS | |
目標 | 屬性 |
------------- | ------------- |
背景顏色黑黃配 | 黑色: background: #4B4841; 黃色: background: #FFCE4E; |
翻面效果 | 內外層:perspective ,內層transform-style: preserve-3d ,X軸翻面rotateX(180deg) |
3d元素的背面隱藏 | backface-visibility: hidden |
OK ~ 第15天!挑戰經過一半了,上班忙、回家寫文章真的挺硬的,只是寫文章還可以廢話幾句,還好又要週五了,假日來調整一波XD