css绘制3D炫动ikun

时间:2023-02-09 19:52:15

今天做一个3D版的ikun。

先准备图片一张

css绘制3D炫动ikun

代码浅析

页面整体div.contrainer,舞台div.stage,控制盒子div.control,图片盒子div.imgWrap,js载入div.img列表。

<div class="contrainer">
  <div class="stage">
    <div class="control">
      <div class="imgWrap"></div>
    </div>
  </div>
</div>

先设置页面背景色以及div.contrainer固定高度,导入图片。

body {
  background: #000;
}
.contrainer {
  position: relative;
  height: 100vh;
}
.stage {
  position: relative;
  width: 100%;
  height: 100%;
  margin: 0 auto;
  perspective: 120px;
}
.stage .control {
  position: relative;
  width: 100%;
  height: 100%;
}
.stage .control .imgWrap {
  position: absolute;
  width: 100%;
  height: 100%;
  max-width: 400px;
  min-height: 400px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.stage .control .imgWrap .img {
  position: absolute;
  width: 100%;
  height: 100%;
  line-height: 6px;
  font-size: 12px;
  top: 0;
  left: 0;
  background: var(--ikun);
  background-position: -150px 0;
  background-repeat: no-repeat;
  background-size: auto;
  overflow: hidden;
  color: transparent;
  word-break: break-word;
}

我完成了第一步效果

css绘制3D炫动ikun

接下来我们需要加一点效果,给图片div.img加一个滤镜效果filter

.stage .control .imgWrap .img{
  ...
  filter: grayscale(1) invert(1) brightness(0.5);
}

grayscale(黑白效果),值在0-1之间,0为原图,1为完全变灰(0%-100%)

invert(反转效果),值在0-1之间,0为原图,1为完全反转(0%-100%)

brightness(亮度效果),值不为负数,1为原图(百分比也可以,1=100%)
超过1,图会更明亮,0-1相当于遮罩效果
使用 filter: brightness(0.5); 就无须额外制作遮罩

接下来给div.img设置一个味蕾before,同时,也和div.img一样设置背景,并且使用背景混合模式

.stage .control .imgWrap .img::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  background: var(--ikun), red;
  background-blend-mode: lighten;
  margin-left: 10px;
  mix-blend-mode: darken;
  background-repeat: no-repeat;
  background-size: auto;
}

mix-blend-mode是CSS3新增的一个很有意思的属性,它描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合。我们将 PS 中图层的概念替换为 HTML 中的元素。

这样我们就得到一下效果

css绘制3D炫动ikun

接下来我们给div…stage,div.control,div.imgWrap,div.img这些盒子加上transform-style: preserve-3d;属性,preserve-3d将指示元素的子元素应位于 3D 空间中,该属性不能被子元素继承,属性的效果作用于子元素,不作用于自身,要结合transform使用,否则没效果。

继续,
我们给div.img加入文字或者符号…之类的,要用到background-clip: text;将文本绘制到背景区域,

效果如下
css绘制3D炫动ikun

整体效果出来了,接下来我们需要用到动画让整体动起来,CSS3中添加的新属性animation是用来为元素实现动画效果的,但是animation无法单独担当起实现动画的效果。承载动画的另一个属性——@keyframes。

@keyframes rotate {
  0% {
    transform: rotateY(0deg);
  }
  50% {
    transform: rotateY(-360deg);
  }
  100% {
    transform: rotateY(-720deg);
  }
}
@keyframes filterChange {
  100% {
    filter: grayscale(1) invert(1) brightness(3);
  }
}

效果如下

css绘制3D炫动ikun

这是一个div.img得到的效果,那么我们多加几个?我们使用js将div.img添加到div.imgWrap中,

 for(let i=0;i<8;i++){

      let div = document.createElement("div")
      div.className = 'img'
      div.innerText = '..........................................'
      document.getElementsByClassName('imgWrap')[0].appendChild(div)
  }

用js添加了div.img,我们还需要给每个div.img设置transform: rotateY() translateZ();rotateY是Y轴的旋转角度,translateZ是往Z轴移动,

stage .control .imgWrap .img:nth-child(1) {
  transform: rotateY(80deg) translateZ(482.84px);
  animation: filterChange 0.5s 500ms infinite linear; 
}
.stage .control .imgWrap .img:nth-child(2) {
  transform: rotateY(125deg) translateZ(482.84px);
  animation: filterChange 0.5s 500ms infinite linear;
}
.stage .control .imgWrap .img:nth-child(3) {
  transform: rotateY(170deg) translateZ(482.84px);
  animation: filterChange 0.5s 500ms infinite linear;
}
.stage .control .imgWrap .img:nth-child(4) {
  transform: rotateY(215deg) translateZ(482.84px);
  animation: filterChange 0.5s 500ms infinite linear;
}
.stage .control .imgWrap .img:nth-child(5) {
  transform: rotateY(260deg) translateZ(482.84px);
  animation: filterChange 0.5s 500ms infinite linear;
}
.stage .control .imgWrap .img:nth-child(6) {
  transform: rotateY(305deg) translateZ(482.84px);
  animation: filterChange 0.5s 500ms infinite linear;
}
.stage .control .imgWrap .img:nth-child(7) {
  transform: rotateY(350deg) translateZ(482.84px);
  animation: filterChange 0.5s 500ms infinite linear;
}
.stage .control .imgWrap .img:nth-child(8) {
  transform: rotateY(395deg) translateZ(482.84px);
  animation: filterChange 0.5s 500ms infinite linear;
}

css写太麻烦了,我们可以用less这样写方便快捷

.loop(@n,@i:1) when(@i<=@n){
    .img:nth-child(@{i}){
        transform: rotateY(35 + (@i * 45deg)) translateZ(482.84px) ;
        animation: filterChange .5s 500ms infinite linear;
    }
    .loop(@n,(@i)+1)
}
.loop(8)

最后就得到了我们开头看到的效果

css绘制3D炫动ikun

结尾

其实做这个我也看了很多知识,受益良多。

一起学习,一起努力,共同进步,

学无止境,学无止境,学无止境。

—— END ——