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摩天轮效果,全是一个特效,一个模子。

今天开始,有第二个了~!!

发布了92 篇原创文章 · 获赞 247 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/weixin_42703239/article/details/105361755