CSS3乾貨15:旋轉摩天輪

今天做項目,無意看到個摩天輪效果,甚是有意思,決定自己來做做。原效果是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摩天輪效果,全是一個特效,一個模子。

今天開始,有第二個了~!!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章