今天做項目,無意看到個摩天輪效果,甚是有意思,決定自己來做做。原效果是JS 寫的,我懶得用JS,就用 CSS3 寫一個。那麼多美女圍繞着轉,開心的要死,所以放了個單純的小男孩在中間代表我的心情~
效果動圖如下:
旋轉的圖片想做都少都無所謂,我這裏做12個。
主要的原理就是利用了 CSS3 的 transform 的位移 和 旋轉變形,以及幀動畫。
HTML結構
12張圖,就用一個 ul 結合 12 個 li 來做。注意,這裏有 span 標籤,後面有用~!
<div class="box">
<ul>
<li><span><img src="../images/3d/1.jpg" alt=""></span></li>
<li><span><img src="../images/3d/2.jpg" alt=""></span></li>
<li><span><img src="../images/3d/3.jpg" alt=""></span></li>
<li><span><img src="../images/3d/4.jpg" alt=""></span></li>
<li><span><img src="../images/3d/5.jpg" alt=""></span></li>
<li><span><img src="../images/3d/6.jpg" alt=""></span></li>
<li><span><img src="../images/3d/7.jpg" alt=""></span></li>
<li><span><img src="../images/3d/8.jpg" alt=""></span></li>
<li><span><img src="../images/3d/9.jpg" alt=""></span></li>
<li><span><img src="../images/3d/10.jpg" alt=""></span></li>
<li><span><img src="../images/3d/11.jpg" alt=""></span></li>
<li><span><img src="../images/3d/12.jpg" alt=""></span></li>
</ul>
</div>
樣式分析
1、box 的大小任意,但是一定是一個正方形。
讓它相對定位,是因爲 li 的位置需要任意擺放,li 肯定是絕對定位的,那麼 box 就必須相對定位。
.box{
width: 400px;
height: 400px;
margin-left: auto;
margin-right: auto;
position: relative;
margin-top: 10px;
}
ul 是一個寬高略小於 box 圓形,且在 box 的中心位置。
ul{
border:1px #000 dashed;
margin:auto;
position: relative;
width: 340px;
height: 340px;
border-radius: 100%;
top: 30px;
}
2、爲了方便控制 li 的位置,先讓 li 擺放到 box 的中心去,再調整位置,到 12 點方位。以12點方位爲起點,調整每個 li 的位置。並且把li的旋轉中心,也就是 transform-origin 屬性,一定要圖片下方 200px 的位置。爲啥 200px?因爲 box 的寬高一半就是 200px 。
li{
width: 60px;
height: 60px;
overflow: hidden;
position: absolute;
border-radius: 100%;
left:50%;
margin-left: -30px;
margin-top: -30px;
top:50%;
transform-origin: center 200px; /* 調整旋轉中心,水平居中,垂直座標爲圖片下方200px */
}
這個時候,圖片還是在中心上,還沒放到各自的位置。
3、關鍵的來了,把 li 擺放到各自的位置上。li 要圍繞 box 的中心,擺在12個方位上。每個位置到中心點的距離一樣,只是旋轉的度數不同。例如,第一個 0 度的話,第二個就旋轉 30 度,第三個 60 度,依次類推。爲啥 30 ? 因爲 360 / 12 = 30 啊~!
這裏可以看出來,每個方位的旋轉度是 360 / 內容個數。
每個 li 添加樣式:
transform: translateY(-170px) rotateZ( 索引*30 + deg);
- translateY 是控制位移,往上放移動 170。爲啥 170? 因爲圖片還有 60px 寬度,不能超出 box 範圍,圖片中心距離 box 邊緣還有 30px。
- rotateZ 是圍繞 z 軸,就是垂直於屏幕的座標軸旋轉。 每個 li 旋轉 索引*30 度。控制每個 li 用 nth-child( 索引 )。注意,這裏的索引是從 1 開始的。
.box li:nth-child(1) {
transform: translateY(-170px) rotateZ(0deg);
}
.box li:nth-child(2) {
transform: translateY(-170px) rotateZ(30deg);
}
依次類推。
但是,圖片要始終是要擺正的。所以,圖片要反向旋轉對應的度數。
.box li:nth-child(1) img {
transform: rotateZ(0deg);
}
.box li:nth-child(2) img {
transform: rotateZ(-30deg);
}
按照這個思路寫 12 個。有點多~~
4、最後動起來。讓摩天輪旋轉~!
ul{
animation:MoTianLun 50s infinite linear;
}
@keyframes MoTianLun {
0%{
transform:rotateZ(0)
}
100%{
transform:rotateZ(360deg)
}
}
每個圖片也會跟着旋轉,會歪斜。要持續擺正,就做反向旋轉動畫。但是之前圖片已經寫了 transform 的旋轉了,所以反向旋轉的動畫就寫在 span 標籤上。
li>span{
animation:MoTianLun 50s infinite linear reverse;
}
考慮到每個 li 的位置寫起太麻煩,其實我是用 SCSS 寫的。完整 SCSS 代碼如下:
@charset "utf-8";
*{
margin: 0;
padding: 0;
}
ul,li,ol{
list-style: none;
}
img{
border:none;
}
.boy{
position: absolute;
width: 200px;
height: 200px;
left: 50%;
top:50%;
margin-left: -100px;
margin-top: -100px;
z-index: 1;
overflow: hidden;
img{
width: 200px;
height: 200px;
border-radius: 100%;
}
}
.box{
width: 400px;
height: 400px;
margin-left: auto;
margin-right: auto;
position: relative;
margin-top: 10px;
ul{
border:1px #000 dashed;
margin:auto;
position: relative;
width: 340px;
height: 340px;
border-radius: 100%;
top: 30px;
}
li img{
width: 60px;
height: 60px;
}
li{
width: 60px;
height: 60px;
overflow: hidden;
position: absolute;
border-radius: 100%;
left:50%;
margin-left: -30px;
margin-top: -30px;
top:50%;
transform-origin: center 200px;
span{
display: block;
width: 60px;
height: 60px;
overflow: hidden;
}
}
@for $i from 1 through 12{
$deg:$i*30-30;
li:nth-child(#{$i}){
transform: translateY(-170px) rotateZ($deg+deg);
img{
transform:rotateZ(-$deg+deg);
}
}
}
}
.box{
ul{
animation:MoTianLun 50s infinite linear;
}
li>span{
animation:MoTianLun 50s infinite linear reverse;
}
}
@keyframes MoTianLun {
0%{
transform:rotateZ(0)
}
100%{
transform:rotateZ(360deg)
}
}
沒有SCSS環境的朋友,也可以使用完整 CSS, 代碼如下:
* {
margin: 0;
padding: 0; }
ul, li, ol {
list-style: none; }
img {
border: none; }
.boy {
position: absolute;
width: 200px;
height: 200px;
left: 50%;
top: 50%;
margin-left: -100px;
margin-top: -100px;
z-index: 1;
overflow: hidden; }
.boy img {
width: 200px;
height: 200px;
border-radius: 100%; }
.box, .box ul {
width: 400px;
height: 400px;
margin-left: auto;
margin-right: auto;
position: relative;
margin-top: 10px; }
.box ul {
border: 1px #000 dashed;
margin: auto;
position: relative;
width: 340px;
height: 340px;
border-radius: 100%;
top: 30px; }
.box li img {
width: 60px;
height: 60px; }
.box li {
width: 60px;
height: 60px;
overflow: hidden;
position: absolute;
border-radius: 100%;
left: 50%;
margin-left: -30px;
margin-top: -30px;
top: 50%;
transform-origin: center 200px; }
.box li span {
display: block;
width: 60px;
height: 60px;
overflow: hidden; }
.box li:nth-child(1) {
transform: translateY(-170px) rotateZ(0deg); }
.box li:nth-child(1) img {
transform: rotateZ(0deg); }
.box li:nth-child(2) {
transform: translateY(-170px) rotateZ(30deg); }
.box li:nth-child(2) img {
transform: rotateZ(-30deg); }
.box li:nth-child(3) {
transform: translateY(-170px) rotateZ(60deg); }
.box li:nth-child(3) img {
transform: rotateZ(-60deg); }
.box li:nth-child(4) {
transform: translateY(-170px) rotateZ(90deg); }
.box li:nth-child(4) img {
transform: rotateZ(-90deg); }
.box li:nth-child(5) {
transform: translateY(-170px) rotateZ(120deg); }
.box li:nth-child(5) img {
transform: rotateZ(-120deg); }
.box li:nth-child(6) {
transform: translateY(-170px) rotateZ(150deg); }
.box li:nth-child(6) img {
transform: rotateZ(-150deg); }
.box li:nth-child(7) {
transform: translateY(-170px) rotateZ(180deg); }
.box li:nth-child(7) img {
transform: rotateZ(-180deg); }
.box li:nth-child(8) {
transform: translateY(-170px) rotateZ(210deg); }
.box li:nth-child(8) img {
transform: rotateZ(-210deg); }
.box li:nth-child(9) {
transform: translateY(-170px) rotateZ(240deg); }
.box li:nth-child(9) img {
transform: rotateZ(-240deg); }
.box li:nth-child(10) {
transform: translateY(-170px) rotateZ(270deg); }
.box li:nth-child(10) img {
transform: rotateZ(-270deg); }
.box li:nth-child(11) {
transform: translateY(-170px) rotateZ(300deg); }
.box li:nth-child(11) img {
transform: rotateZ(-300deg); }
.box li:nth-child(12) {
transform: translateY(-170px) rotateZ(330deg); }
.box li:nth-child(12) img {
transform: rotateZ(-330deg); }
.box ul {
animation: MoTianLun 50s infinite linear; }
.box li > span, .box ul li > span {
animation: MoTianLun 50s infinite linear reverse; }
@keyframes MoTianLun {
0% {
transform: rotateZ(0); }
100% {
transform: rotateZ(360deg); } }
網頁上的應用
如某個培訓機構的頁面某一板塊:
百度 CSS摩天輪效果,全是一個特效,一個模子。
今天開始,有第二個了~!!