Web前端之路代码改变世界你不知道的技术

纯CSS3制作一个仿真眼球

2019-08-05  本文已影响90人  Jkanon

本想起一个哗众取宠的标题,但转念一想,还是求真务实一点,用内容说话。今天我们抛开JS,不用SVG,单纯使用CSS来一步一步地制作响应式的仿真眼球。

先睹为快

静态眼球模型 浮动的眼球

绘制眼球基础球体

<body>
  <div class="eye_container">
    <div class="eye">
    </div>
  </div>
</body>
body {
  background-image: radial-gradient(ellipse at 50% 0%, #eef 0, #888 100%);
  min-height: 100vh;
  display: flex;
  flex-wrap: nowrap;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}

.eye_container {
  width: 200px;
  height: 200px;
}

.eye {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-image: radial-gradient(circle at 45% 45%, #fff 41%, #ccc 83%);
}

描绘虹膜基础轮廓

<body>
  <div class="eye_container">
    <div class="eye">
      <div class="eye_iris">
      </div>
    </div>
  </div>
</body>
.eye_iris {
  position: absolute;
  top: 25%;
  left: 25%;
  width: 50%;
  height: 50%;
  border-radius: 50%;
  box-shadow: 0 0 5px 0 #000;
  background: radial-gradient(circle at center, #b86e29 32%, #94c7d4 42%, #1c0a24 112%);
}  

通过三种颜色构成的径向渐变构造出虹膜的基础轮廓,同时通过box-shadow制作虹膜边框的模糊特效。

制作四根睫状肌

<body>
  <div class="eye_container">
    <div class="eye">
      <div class="eye_iris">
        <ul class="eye_ciliary">
          <li class="eye_ciliary_item"><span></span></li>
        </ul>
      </div>
    </div>
  </div>
</body>
.eye_ciliary {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  transform: rotateZ(1deg);
}

.eye_ciliary_item {
  display: block;
  width: 100%;
  height: 100%;
  position: absolute;
  top: 50%;
  margin-top: -50%;
}

.eye_ciliary_item span {
    display: block;
    width: 100%;
    height: 100%;
    position: absolute;
}

.eye_ciliary_item:before, 
.eye_ciliary_item:after, 
.eye_ciliary_item span:before, 
.eye_ciliary_item span:after {
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    position: absolute;
    background-color: #000;
    opacity: 0.1;
}

.eye_ciliary_item:before {
  transform: scale(0.025, 0.7) rotate(45deg);
}

.eye_ciliary_item:after {
  transform: scale(0.7, 0.025) rotate(45deg);
}

.eye_ciliary_item span:before {
  transform: rotate(45deg) scale(0.025, 0.7) rotate(45deg);
}

.eye_ciliary_item span:after {
  transform: rotate(-45deg) scale(0.025, 0.7) rotate(45deg);
}

增加更多的睫状肌

<body>
  <div class="eye_container">
    <div class="eye">
      <div class="eye_iris">
        <ul class="eye_ciliary">
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
        </ul>
      </div>
     </div>
  </div>
</body>
.eye_ciliary_item:nth-child(2) {
  transform: rotateZ(5deg);
}
.eye_ciliary_item:nth-child(3) {
  transform: rotateZ(10deg);
}
.eye_ciliary_item:nth-child(4) {
  transform: rotateZ(15deg);
}
.eye_ciliary_item:nth-child(5) {
  transform: rotateZ(20deg);
}
.eye_ciliary_item:nth-child(6) {
  transform: rotateZ(25deg);
}
.eye_ciliary_item:nth-child(7) {
  transform: rotateZ(30deg);
}
.eye_ciliary_item:nth-child(8) {
  transform: rotateZ(35deg);
}
.eye_ciliary_item:nth-child(9) {
  transform: rotateZ(40deg);
}

我们假设两条睫状肌之间的角度偏差为5度,则一共需要360/5 = 72条睫状肌,而根据上个步骤,一个li可在四个象限产生总数为8条的睫状肌,因此我们此处构造了72/8 = 9li

绘制瞳孔

<body>
  <div class="eye_container">
    <div class="eye">
      <div class="eye_iris">
        <ul class="eye_ciliary">
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
        </ul>
        <ul class="eye_ciliary eye_ciliary_sub">
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
          <li class="eye_ciliary_item"><span></span></li>
        </ul>
      </div>
     </div>
  </div>
</body>
.eye_ciliary_sub {
    width: 60%;
    height: 60%;
    top: 20%;
    left: 20%;
}

.eye_ciliary_sub .eye_ciliary_item:before, 
.eye_ciliary_sub .eye_ciliary_item:after, 
.eye_ciliary_sub .eye_ciliary_item span:before, 
.eye_ciliary_sub .eye_ciliary_item span:after {
  opacity: 1;
}

与虹膜的睫状肌制作一样来制作瞳孔,只是通过缩小体积和调整透明度是的中间部分的颜色更加深暗。

瞳孔增加高光

<body>
<div class="eye_container">
  <div class="eye">
    <div class="eye_iris">
      <ul class="eye_ciliary">
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
      </ul>
      <ul class="eye_ciliary eye_ciliary_sub">
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
      </ul>
      <div class="eye_reflect"></div>
      <div class="eye_reflect eye_reflect_sec"></div>
      <div class="eye_reflect eye_reflect_sub"></div>
    </div>
  </div>
</div>
</body>
.eye_reflect {
  position: absolute;
  top: 30%;
  left: 30%;
  width: 20%;
  height: 15%;
  border-radius: 50%;
  transform: rotate(-35deg);
  background-image: radial-gradient(circle at center, #fff 0%, #fff 40%, rgba(255,255,255,0) 100%);
  z-index: 2;
  opacity: .9;
}

.eye_reflect_sec {
  top: 58%;
  left: 50%;
  width: 12%;
  height: 6%;
  background-image: radial-gradient(ellipse at center, #fff 0%, #fff 10%, rgba(255,255,255,0) 100%);
  transform: rotate(35deg);
}

.eye_reflect_sub {
  width: 80%;
  height: 80%;
  top: 0;
  left: 0;
  margin-left: -10%;
  margin-top: -10%;
  background-image: none;
  background-color: rgba(255,255,255, .1);
  z-index: 3;
}

通过两个小的椭圆渐变及一个大的透明的圆形径向渐变来表现出高光,同时通过调整旋转角度将其放置在合适的位置。

添加阴影

角膜阴影
.eye_iris {
  top: 15%;
  left: 15%;
  box-shadow: 0 0 5px 2px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.5) inset;
}

这边增加了角膜内阴影,然后通过改变虹膜的位置调节眼球的转向使之更靠近光源,让角膜阴影显得更加自然。

眼球阴影
<body>
<div class="eye_container">
  <div class="eye">
    <div class="eye_iris">
      <ul class="eye_ciliary">
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
      </ul>
      <ul class="eye_ciliary eye_ciliary_sub">
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
        <li class="eye_ciliary_item"><span></span></li>
      </ul>
      <div class="eye_reflect"></div>
      <div class="eye_reflect eye_reflect_sec"></div>
      <div class="eye_reflect eye_reflect_sub"></div>
    </div>
  </div>
  <div class="shade"></div>
</div>
</body>
.eye_iris {
  background-image: radial-gradient(circle at center, #b86e29 32%, #94c7d4 42%, #1c0a24 200%);
}  

.eye:before, .eye:after {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border-radius: 50%;
}
.eye:before {
  opacity: .75;
  mix-blend-mode: color-burn;
  background-image: radial-gradient(circle at 45% 45%, #ffe 30%, #222 67%, #558 80%);
  z-index: 10;
}

.eye:after {
  mix-blend-mode: overlay;
  background-image: radial-gradient(circle at 65% 65%, #000 20%, rgba(0,0,0,0) 40%);
  z-index: 4;
  opacity: 0.5;
}

.shade {
  position: relative;
  width: 130%;
  height: 10%;
  margin: 0 2em;
  border-radius: 80% 60%;
  background-image: radial-gradient(ellipse at center, #000 0%, rgba(0,0,0, 0.6) 30%, rgba(0,0,0, 0) 70%);
  z-index: 1;
}

增加浮动效果

.eye_iris {
  -webkit-animation: eye_iris_shade ease-in-out 1.5s infinite;
  animation: eye_iris_shade ease-in-out 1.5s infinite;
}  

.eye:after {
  -webkit-animation: eye_shade ease-in-out 1.5s infinite;
  animation: eye_shade ease-in-out 1.5s infinite;
}

.eye {
  -webkit-animation: float ease-in-out 1.5s infinite;
  animation: float ease-in-out 1.5s infinite;
}
.shade {
  -webkit-animation: shade ease-in-out 1.5s infinite;
  animation: shade ease-in-out 1.5s infinite;
}
@-webkit-keyframes float {
  0% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
  50% {
    -webkit-transform: translateY(1em);
    transform: translateY(1em);
  }
  100% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
}

@keyframes float {
  0% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
  50% {
    -webkit-transform: translateY(1em);
    transform: translateY(1em);
  }
  100% {
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
}

@-webkit-keyframes shade {
  0% {
    -webkit-transform: translateY(0) translateX(1em);
    transform: translateY(0) translateX(1em);
    opacity: .5;
  }
  50% {
    -webkit-transform: translateY(1em) translateX(-1em) scale(.9);
    transform: translateY(1em) translateX(-1em) scale(.9);
    opacity: 1;
  }
  100% {
    -webkit-transform: translateY(0) translateX(1em);
    transform: translateY(0) translateX(1em);
    opacity: .5;
  }
}

@keyframes shade {
  0% {
    -webkit-transform: translateY(0) translateX(1em);
    transform: translateY(0) translateX(1em);
    opacity: .5;
  }
  50% {
    -webkit-transform: translateY(1em) translateX(-1em) scale(.9);
    transform: translateY(1em) translateX(-1em) scale(.9);
    opacity: 1;
  }
  100% {
    -webkit-transform: translateY(0) translateX(1em);
    transform: translateY(0) translateX(1em);
    opacity: .5;
  }
}

@-webkit-keyframes eye_shade {
  0% {
    opacity: .2;
  }
  50% {
    opacity: .5;
  }
  100% {
    opacity: .2;
  }
}

@keyframes eye_shade {
  0% {
    opacity: .2;
  }
  50% {
    opacity: .5;
  }
  100% {
    opacity: .2;
  }
}

@-webkit-keyframes eye_iris_shade {
  0% {
    -webkit-box-shadow: 0 0 3px 1px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.2) inset;
    box-shadow: 0 0 3px 1px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.2) inset;
  }
  50% {
    -webkit-box-shadow: 0 0 3px 1px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.5) inset;
    box-shadow: 0 0 3px 1px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.5) inset;
  }
  100% {
    -webkit-box-shadow: 0 0 3px 1px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.2) inset;
    box-shadow: 0 0 3px 1px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.2) inset;
  }
}

@keyframes eye_iris_shade {
  0% {
    -webkit-box-shadow: 0 0 3px 1px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.2) inset;
    box-shadow: 0 0 3px 1px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.2) inset;
  }
  50% {
    -webkit-box-shadow: 0 0 3px 1px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.5) inset;
    box-shadow: 0 0 3px 1px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.5) inset;
  }
  100% {
    -webkit-box-shadow: 0 0 3px 1px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.2) inset;
    box-shadow: 0 0 3px 1px rgba(0,0,0,0.4), 5px 5px 5px 0 rgba(0,0,0,0.2) inset;
  }
}
上一篇 下一篇

猜你喜欢

热点阅读