欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

入门 CSS3 3D 动画:基础知识详解

最编程 2024-08-06 21:30:05
...

基础概念

坐标

image.pngimage (1).png

旋转

  • x左边是负的,右边是正的
  • y 上面是负的, 下面是正的
  • z 里面是负的, 外面是正的
  • 与2d相比,3D多了z轴,z方向就是对着自己的方向

旋转

image (2).png

  • x轴:冲着自己转,为负角度
  • y轴:冲着自己转,为负角度
  • z轴:逆时针旋转,为负角度

开启3D视图

  • 设置一个元素的transform-style:preserve-3d;只影响这个元素的子元素
  • 所有子元素都可以相对与父元素的平面进行3d变形操作
  • 注意:如果孙子元素也有3d效果,那么还必须给子元素设置preserve-3d

透视/景深效果

perspective(length)为一个元素设置三维透视的距离。仅作用于元素的后代,而不是其元素本身。假如当我们看一个房子的时候,比如房子有200米长,在房里里面与在房子外面,看到的角度都是不一样的: 说白了就是眼睛与物体的距离

当设置perspective<200的时候,就是我们在房里看,

当设置perspective>200或者更多的时候,就相当在外面看,而且越远看房子的角度大小也就不一样

当元素没有设置perspective(length)时,所有后代元素被压缩在同一个二维平面上,不存在景深的效果。

如果设置perspective(length)后,将会看到三维的效果。默认的透视视角中心在容器

75c0bf91-1cdf-4390-9f15-f25001c46724.png31d86233-5524-482d-ac50-15a2e21e9a45.png

<div class="container">
   <div class="card"></div>
</div>

.container {
  width: 200px;
  height: 200px;
  position: relative;
  top: 20px;
  -webkit-perspective: 700px;
  -webkit-transform-style: preserve-3d;
}

.card {
  width: 100%;
  height: 100%;
  background-color: green;
  position: absolute;
  -webkit-transform: rotateY(60deg);
}

perspective-origin

49fbe083-97d8-4102-a649-1c57d1332ec3.png

  • perspective-origin: 50% 50%,第一个数值是 3D 元素所基于的 X 轴,第二个定义在 y 轴上的位置

总结

呈现3d效果需要设置3部分

1.父元素或者当前运动元素上设置透视角perspective,perspective属性的值决定了3D效果的强度

2.3D视图,设置在父元素上,子元素都可以相对父元素的平面进行3d变形操作

3.3D变形函数,translate3d、scale3d、rotateX、rotateY、rotateZ等

4.开启GPU加速

{
  will-change: transform;
  transform: translateZ(0);
}

小例子

3D 菜单效果

voaoq-syda0.gif

<div id="nav">
  <ul class="nav-menu clearfix unstyled">
    <li>
      <a href="#" class="three-d">
        Services
        <span class="three-d-box">
            <span class="front">Services</span>
            <span class="back">Services</span>
        </span>
      </a>
    </li>
  </ul>
</div>

/* basic menu styles */
.nav-menu {
  display: block;
    background: #74adaa;
    width:950px;
    margin: 50px auto 150px;
}
.nav-menu > li {
  display: inline;
  float:left;
    border-right:1px solid #94c0be;
}
.nav-menu > li:last-child {
  border-right: none;
}
.nav-menu li a {
    color: #fff;
    display: block;
    text-decoration: none;
    font-family: 'sansationregular';
    -webkit-font-smoothing: antialiased;
    text-transform: capitalize;
    overflow: visible;
    line-height: 20px;
    font-size: 20px;
    padding: 15px 30px 15px 31px;
}

/* animation domination */
.three-d {
  perspective: 200px;
  transition: all .07s linear;
  position: relative;
}

.three-d:not(.active):hover .three-d-box,
.three-d:not(.active):focus .three-d-box {
  transform: translateZ(-25px) rotateX(90deg);
}

.three-d-box {
  transition: all .3s ease-out;
  transform: translatez(-25px);
  transform-style: preserve-3d;
  pointer-events: none;
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.front {
  transform: rotatex(0deg) translatez(25px);
}

.back {
  color: #FFE7C4;
}

3D 翻纸牌效果

c2mrw-6st5e.gif

<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    /*3D效果容器*/
    .cardflip{
      width:600px;
      height:600px;
      position: relative;
      perspective: 800;
      -webkit-perspective: 800;
    }
    .cardflip .card{
      width:200px;
      height:260px;
      position:absolute;
      transform-style:preserve-3d;
      -webkit-transform-style:-webkit-preserve-3d;
      transition:all 1s;
      -webkit-transition:all 1s;
    }
    .cardflip .card>div{
      position:absolute;
      width:100%;
      height:100%;
      text-align: center;
      font-size: 120px;
      color: #000;
      line-height:2;
      backface-visibility: hidden;

    }
    .cardflip .card .front{
    }
    .cardflip .card .back{
      transform: rotateY(180deg);
      -webkit-transform: rotateY(180deg);
    }
    .cardflip .card.flipped{
      transform: rotateY(180deg);
      -webkit-transform: rotateY(180deg);
    }
  </style>
</head>
<body>
  <div class="cardflip">
    <div class="card" id="card">
      <div class="front">1</div>
      <div class="back">2</div>
    </div>
  </div>
  <script>
    function flip(){
      var that = card;
      var isfront = true;
      return function(){
        isfront ? that.classList.add('flipped') : that.classList.remove('flipped');
        isfront = !isfront;
      }
    } 
    var card = document.getElementById('card');
    var fp = flip();
    card.onclick = fp;
  </script>
</body>
</html>

3D 翻页效果

5zw5s-743qa.gif

<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
    .my3dspace {
      -webkit-perspective: 800;
      -webkit-perspective-origin: 50% 50%;
      overflow: hidden;
    }

    .page-group {
      width: 400px;
      height: 400px;
      margin: 0 auto;
      -webkit-transform-style: preserve-3d;
      position: relative;
    }

    .page {
      width: 360px;
      height: 360px;
      padding: 20px;
      background: black;
      color: #fff;
      font-size: 360px;
      font-weight: bold;
      line-height: 360px;
      text-align: center;
      position: absolute;
    }

    #page1 {
      -webkit-transform-origin: bottom;
      -webkit-transition: -webkit-transform 1s linear;
    }

    #page2,
    #page3,
    #page4,
    #page5,
    #page6,
    #page7,
    #page8,
    #page9 {
      -webkit-transform-origin: bottom;
      -webkit-transition: -webkit-transform 1s linear;
      -webkit-transform: rotateX(90deg);
    }

    .op {
      text-align: center;
      margin: 40px auto;
    }
  </style>
</head>

<body>
  <div class="my3dspace">
    <div class="page-group">
      <div class="page" id="page1">1</div>
      <div class="page" id="page2">2</div>
      <div class="page" id="page3">3</div>
      <div class="page" id="page4">4</div>
      <div class="page" id="page5">5</div>
      <div class="page" id="page6">6</div>
      <div class="page" id="page7">7</div>
      <div class="page" id="page8">8</div>
      <div class="page" id="page9">9</div>
    </div>
    <div class="op">
      <a href="javascript:next();">next</a>&nbsp;<a href="javascript:prev();">prev</a>
    </div>
  </div>
  <script>
    var cur_index = 1;
    function next() {
      if (cur_index == 9) return false;
      var cur = document.getElementById('page' + cur_index);
      cur.style.webkitTransform = 'rotateX(-270deg)';
      cur_next = document.getElementById('page' + (++cur_index));
      cur_next.style.webkitTransform = 'rotateX(0deg)';
    }
    function prev() {
      if (cur_index == 1) return false;
      var cur = document.getElementById('page' + cur_index);
      cur.style.webkitTransform = 'rotateX(90deg)';
      cur_perv = document.getElementById('page' + (--cur_index));
      cur_perv.style.webkitTransform = 'rotateX(0deg)';
    }
  </script>
</body>

</html>