css3带你实现3D转换效果


Posted in HTML / CSS onFebruary 24, 2022

前言

在css3中允许使用3D转换来对元素进行格式化,在原本只是2D转化的平面中引入了Z轴。在这之前我们讲解了css3中的2D转换,也就是二维空间变换,本篇的3D转换就是基于原来的2D转换而来,与2D转换的功能相似。

三维坐标系

相信学过数学的效果版对这一概念多多少少是知道的,我们要想有一个3D空间效果,也就是立体空间感,比如:正方体、长方体.....再比如我们生活所居住的房间也是3D立体空间的,主要有X轴、Y轴Z轴共同组成

css3带你实现3D转换效果

x轴 : 水平向右,x右边是正值,左边是负值。

y轴 : 垂直向下,y下面是正值,上面是负值。

z轴 : 垂直屏幕,往外面是正值,往里面是负值。

转换属性

属性 描述
transform 使得元素向2D或3D转换
transform-origin 改变转换元素的位置
transform-style 规定被嵌套元素如何在 3D 空间中显示
perspective 规定 3D 元素的透视效果
perspective-origin 规定 3D 元素的底部位置
backface-visibility 定义元素在不面对屏幕时是否可见

这里transform属性和transform-origin属性在前一篇《css3中2D转换之有趣的transform形变效果》中已经讲解了,这里就不再细说。不同的是在3D转换中,transform-origin属性会接收第三个值,表示Z轴方向位置

(1)transform-style

transform-style设置元素的子元素是位于 3D 空间中还是平面中。

语法:

div{
    transform-style: flat|preserve-3d;
}

flat:设置元素的子元素位于该元素的平面中(子元素不设置3D空间)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box{
            position: relative;
            width: 200px;
            height: 200px;
            margin: 100px auto;
            transition: .5s;
            /* flat:子元素不存在3D空间 */
            transform-style: flat;
            background-color: #eee;
        }
        .box:hover{
            transform: rotateY(60deg);
        }
        .s{
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: pink;
        }
        .s2{
            background-color: orange;
            transform: rotateX(45deg);
        }
    </style>
</head>
<body>
    <div class="box">
        <div class="s s1"></div>
        <div class="s s2"></div>
    </div>
</body>
</html>

设置flat值,子元素就只位于平面中,效果如下:

css3带你实现3D转换效果

preserve-3d:设置元素的子元素应用于3D空间中

基于上述栗子,将transform-style属性值改为preserve-3d

.box{
  /* 让子元素保持3d立体空间环境 */
  transform-style: preserve-3d;
}

得到3D空间效果:

css3带你实现3D转换效果

3D视觉是不是感觉一下就来啦~

(2)perspective

perspective指定了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果。如果不指定透视,则Z轴空间中的所有点将平铺到同一个2D视平面中,并且变换结果中将不存在景深概念

z>0 的三维元素比正常大,而 z<0 时则比正常小,大小程度由该属性的值决定

“perspective”本身就具有透视的意思,就是设置用于户和元素3D空间Z平面之间的距离(视距),简单理解就是将电脑屏幕当做一个平面,用户眼睛到屏幕的垂直方向。值越大用户与屏幕距离越远,视觉效果很小,值越小3D效果就越明显。

css3带你实现3D转换效果

语法:

div{
   perspective:none | <length>
}
  • none:默认值,与 0 相同,不设置透视
  • length:元素距离视图的距离,以像素计

这里还是以上述栗子进行演示:

body{
    perspective: 900px;
}

或者

.box{
    perspective: 900px;
}

只要设置在父盒子上就可以,效果如下:

css3带你实现3D转换效果

从第一眼就可以看出与上面不同,没有设置景深是这样:

css3带你实现3D转换效果

设置了景深是这样的:

css3带你实现3D转换效果

注意:perspective属性只影响 3D 转换元素,并且同时使用perspective-origin属性,可以改变 3D 元素的底部位置

(3)perspective-orgin

perspective-origin 属性定义 3D 元素所基于的 X 轴和 Y 轴。该属性允许您改变 3D 元素的底部位置。

语法:

perspective-origin: x-axis y-axis;

x-position:指定消失点的横坐标,其值有以下形式:

<length-percentage>长度值或相对于元素宽度的百分比值,可为负值。

  • left, 关键字,0值的简记。
  • center, 关键字,50%的简记。
  • right, 关键字,100%的简记。

y-position:指定消失点的纵坐标,其值有以下形式:

  • <length-percentage>长度值或相对于元素高度的百分比值,可为负值。
  • top, 关键字,0值的简记。
  • center, 关键字,50%的简记。
  • bottom, 关键字,100%的简记

介绍完语法使用,我们知道了怎么取值,下面还是基于上述例子继续演示:

值为长度值:

.box{
    perspective-origin: 300px;
}

效果如下:

css3带你实现3D转换效果

值为关键字:

.box{
    perspective: 900px;
    perspective-origin: left;
}

效果如下:

css3带你实现3D转换效果

值为百分比:

.box{
    perspective: 900px;
    perspective-origin: 300%;
}

效果如下:

css3带你实现3D转换效果

两个值:

.box{
    perspective: 900px;
    perspective-origin: left top;
}

效果如下:

css3带你实现3D转换效果

(4)backface-visibility

backface-visibility指定当元素背面朝向观察者时是否可见

元素的背面是其正面的镜像,虽然在 2D 中不可见,但是当变换导致元素在 3D 空间中旋转时,背面可以变得可见。 (此属性对 2D 变换没有影响,它没有透视。)

语法:

backface-visibility: visible|hidden;
  • visible:默认值。 背面是可见的。
  • hidden:背面是不可见的

这里借鉴了MDN上面的例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .showbf div {
          backface-visibility: visible;
        }
        
        .hidebf div {
          backface-visibility: hidden;
        }
        .container {
          width: 150px;
          height: 150px;
          margin: 75px 0 0 75px;
          border: none;
        }
        
        .cube {
          width: 100%;
          height: 100%;
          perspective: 550px;
          perspective-origin: 150% 150%;
          transform-style: preserve-3d;
        }
        
        .face {
          display: block;
          position: absolute;
          width: 100px;
          height: 100px;
          border: none;
          line-height: 100px;
          font-family: sans-serif;
          font-size: 60px;
          color: white;
          text-align: center;
        }
        
        .front {
          background: rgba(0, 0, 0, 0.3);
          transform: translateZ(50px);
        }
        
        .back {
          background: rgba(0, 255, 0, 1);
          color: black;
          transform: rotateY(180deg) translateZ(50px);
        }
        
        .right {
          background: rgba(196, 0, 0, 0.7);
          transform: rotateY(90deg) translateZ(50px);
        }
        
        .left {
          background: rgba(0, 0, 196, 0.7);
          transform: rotateY(-90deg) translateZ(50px);
        }
        
        .top {
          background: rgba(196, 196, 0, 0.7);
          transform: rotateX(90deg) translateZ(50px);
        }
        
        .bottom {
          background: rgba(196, 0, 196, 0.7);
          transform: rotateX(-90deg) translateZ(50px);
        }
        
        th, p, td {
          background-color: #EEEEEE;
          margin: 0px;
          padding: 6px;
          font-family: sans-serif;
          text-align: left;
        }
    </style>
</head>
<body>
    <table>
      <tr>
        <th><code>backface-visibility: visible;</code></th>
        <th><code>backface-visibility: hidden;</code></th>
      </tr>
      <tr>
        <td>
          <div class="container">
            <div class="cube showbf">
              <div class="face front">1</div>
              <div class="face back">2</div>
              <div class="face right">3</div>
              <div class="face left">4</div>
              <div class="face top">5</div>
              <div class="face bottom">6</div>
            </div>
          </div>
          <p>
            Since all faces are partially transparent,
            the back faces (2, 4, 5) are visible
            through the front faces (1, 3, 6).
          </p>
        </td>
        <td>
          <div class="container">
            <div class="cube hidebf">
              <div class="face front">1</div>
              <div class="face back">2</div>
              <div class="face right">3</div>
              <div class="face left">4</div>
              <div class="face top">5</div>
              <div class="face bottom">6</div>
            </div>
          </div>
          <p>
            The three back faces (2, 4, 5) are
            hidden.
          </p>
        </td>
      </tr>
    </table>
</body>
</html>

3D转换

旋转单位:deg(角度)、rad(弧度)、grad(梯度)、turn(圈)

  1. 弧度 = 角度*π/180
  2. grad = 360度(一圈)

(1)3D位移

3D位移在2D基础上多加了一个可以z轴移动的方向

3D位移主要演示translateZtranslate3d两个属性:

translate3d()CSS 函数在3D空间内移动一个元素的位置,这个移动由一个三维向量来表达,分别表示他在三个方向上移动的距离

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>3D位移</title>
    <style>
body{
    perspective: 800px;
} 
.box{
    position: relative;
    width: 200px;
    height: 200px;
    margin: 100px auto;
    transition: .5s;
    background-color: pink;
    text-align: center;
    line-height: 200px;
}
.box:hover{
    /* transform: translateX(50px) translateY(100px) translateZ(200px); */
    /* 简写 */
    transform: translate3d(50px,100px,200px);
}
    </style>
</head>
<body>
    <div class="box">3D位移</div>
</body>
</html>

效果如下:

css3带你实现3D转换效果

注意:

  1. 首先要设置perspectiv属性在被观察元素的父盒子上,不然不会有Z轴效果。
  2. 如果只是单独设置Z轴视距,可以直接使用translateZ属性。
  3. Z轴设置的值越大,距离我们眼睛就越近,也就是简单理解元素被放大了
  4. Z轴设置的值越小,或者为负数,则会离我们眼睛越远,元素缩小

(2)3D旋转

  • rotateX:让元素围绕X轴转
  • rotateY:让元素围绕Y轴旋转
  • rotateZ:让元素围绕Z轴旋转
  • rotate3d:让元素围绕固定轴旋转不变形

旋转量由角度决定,角度为正则顺时针旋转,反之逆时针旋转

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>3D旋转</title>
    <style>
body{
    perspective: 800px;
} 
.box{
    position: relative;
    width: 200px;
    height: 200px;
    margin: 100px auto;
    transition: .5s;
    background-color: pink;
    text-align: center;
    line-height: 200px;
}
.box:hover{
    transform: rotateX(180deg); /* X轴旋转180° */
    transform: rotateY(180deg); /* Y轴旋转180° */
    transform: rotateZ(180deg); /* Z轴旋转180° */
}
    </style>
</head>
<body>
    <div class="box">3D旋转</div>
</body>
</html>

X轴旋转效果:

css3带你实现3D转换效果

Y轴旋转效果:

css3带你实现3D转换效果

Z轴旋转效果:

css3带你实现3D转换效果

这里单独将rotate3d函数拎出来讲

语法:

rotate3d(x, y, z, a)

取值分析:

  • x:可以是0到1之间的数值,表示旋转轴X坐标方向的矢量
  • y:可以是0到1之间的数值,表示旋转轴Y坐标方向的矢量
  • z:可以是0到1之间的数值,表示旋转轴Z坐标方向的矢量
  • a:表示旋转角度。正的角度值表示顺时针旋转,负值表示逆时针旋转

也就是说rotateX(a) === rotate3d(1,0,0,a)、rotateY(a) === rotate3d(0,1,0,a)、rotateZ(a) === rotate3d(0,0,1,a)

.box:hover{
    transform: rotate3d(1,1,0,50deg); /* 表示在X轴和Y轴旋转50° */
}

效果如下:

css3带你实现3D转换效果

.box:hover{
    transform: rotate3d(1,1,1,1turn); /* 围绕3轴旋转一圈 */
}

效果如下:

css3带你实现3D转换效果

综合案例

基于上述所学内容,我们来实操做一个3D盒子旋转:

html结构:

<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>3D盒子旋转</title>
        <link rel="stylesheet" href="css/index.css" />
    </head>
    <body>
        <section>
            <div><img src="images/1.jpg" alt="" /></div>
            <div><img src="images/2.jpg" alt="" /></div>
            <div><img src="images/3.jpg" alt="" /></div>
            <div><img src="images/4.jpg" alt="" /></div>
            <div><img src="images/5.jpg" alt="" /></div>
            <div><img src="images/6.jpg" alt="" /></div>
            <div><img src="images/1.jpg" alt="" /></div>
            <div><img src="images/2.jpg" alt="" /></div>
            <div><img src="images/3.jpg" alt="" /></div>
            <div><img src="images/4.jpg" alt="" /></div>
            <div><img src="images/5.jpg" alt="" /></div>
            <div><img src="images/6.jpg" alt="" /></div>
        </section>
    </body>
</html>

css部分:

* {
    /* 初始化 */
    padding: 0;
    margin: 0;
}
body {
    /* 弹性布局*/
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    /* 视距 */
    perspective: 1000px;
}
section {
    position: relative;
    width: 150px;
    height: 150px;
    /* 让子元素保留其3D位置 */
    transform-style: preserve-3d;
    /* 动画 名称 时长 linear 是匀速运动 infinite是无限次播放 */
    animation: rotate 5s linear infinite;
}
section div {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #fff;
    transition: all 1s;
}
section div img {
    width: 100%;
    height: 100%;
}
/* 这里使用的伪类选择器 */
section div:nth-child(1) { /* 选择第1个元素 */
    transform: translateZ(75px);
}
section:hover div:nth-child(1) {
    transform: translateZ(200px);
}
section div:nth-child(2) { /* 选择第2个元素 */
    transform: rotateX(-180deg) translateZ(75px);
}
section:hover div:nth-child(2) {
    transform: rotateX(-180deg) translateZ(200px);
}
section div:nth-child(3) { /* 选择第3个元素 */
    transform: rotateX(90deg) translateZ(75px);
}
section:hover div:nth-child(3) {
    transform: rotateX(90deg) translateZ(200px);
}
section div:nth-child(4) { /* 选择第4个元素 */
    transform: rotateX(-90deg) translateZ(75px);
}
section:hover div:nth-child(4) {
    transform: rotateX(-90deg) translateZ(200px);
}
section div:nth-child(5) { /* 选择第5个元素 */
    transform: rotateY(90deg) translateZ(75px);
}
section:hover div:nth-child(5) {
    transform: rotateY(90deg) translateZ(200px);
}
section div:nth-child(6) { /* 选择第6个元素 */
    transform: rotateY(-90deg) translateZ(75px);
}
section:hover div:nth-child(6) {
    transform: rotateY(-90deg) translateZ(200px);
}
section div:nth-child(7) { /* 选择第7个元素 */
    transform: translateZ(75px);
}
section div:nth-child(8) { /* 选择第8个元素 */
    transform: rotateX(-180deg) translateZ(75px);
}
section div:nth-child(9) { /* 选择第9个元素 */
    transform: rotateX(90deg) translateZ(75px);
}
section div:nth-child(10) { /* 选择第10个元素 */
    transform: rotateX(-90deg) translateZ(75px);
}
section div:nth-child(11) { /* 选择第11个元素 */
    transform: rotateY(90deg) translateZ(75px);
}
section div:nth-child(12) { /* 选择第12个元素 */
    transform: rotateY(-90deg) translateZ(75px);
}

/* 定义动画 */
@keyframes rotate {
    0% {
        transform: rotateY(0) rotateX(0);
    }
    100% {
        transform: rotateY(360deg) rotateX(360deg);
    }
}

效果如下

css3带你实现3D转换效果

到此这篇关于css3带你实现3D转换效果的文章就介绍到这了,更多相关css3 3D转换内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

HTML / CSS 相关文章推荐
检测用户浏览器是否支持CSS3的方法
Aug 29 HTML / CSS
移动Web—CSS为Retina屏幕替换更高质量的图片
Dec 24 HTML / CSS
五款漂亮的纯CSS3动画按钮的实例教程
Nov 21 HTML / CSS
HTML5拖放功能_动力节点Java学院整理
Jul 13 HTML / CSS
HTML5 Canvas像素处理使用接口介绍
Dec 02 HTML / CSS
H5 meta小结(前端必看篇)
Aug 24 HTML / CSS
使用html2canvas实现将html内容写入到canvas中生成图片
Jan 03 HTML / CSS
HTML5自定义mp3播放器源码
Jan 06 HTML / CSS
html5跳转小程序wx-open-launch-weapp踩坑
Dec 02 HTML / CSS
html+css合并表格边框的示例代码
Mar 31 HTML / CSS
Unicode中的CJK(中日韩统一表意文字)字符小结
Dec 06 HTML / CSS
使用CSS实现按钮边缘跑马灯动画
May 07 HTML / CSS
bootstrapv4轮播图去除两侧阴影及线框的方法
企业开发CSS命名BEM代码规范实践
CSS3实现360度循环旋转功能
CSS实现九宫格布局(自适应)的示例代码
Feb 12 #HTML / CSS
postman中form-data、x-www-form-urlencoded、raw、binary的区别介绍
Jan 18 #HTML / CSS
MIME类型中application/xml与text/xml的区别介绍
Jan 18 #HTML / CSS
HTTP中的Content-type详解
Jan 18 #HTML / CSS
You might like
PHP中遍历stdclass object的实现代码
2011/06/09 PHP
9个PHP开发常用功能函数小结
2011/07/15 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
php传值和传引用的区别点总结
2019/11/19 PHP
JS 实现导航栏悬停效果
2013/09/23 Javascript
如何正确使用Nodejs 的 c++ module 链接到 OpenSSL
2014/08/03 NodeJs
javascript实现页面刷新时自动清空表单并选中的方法
2015/07/18 Javascript
js 弹出对话框(遮罩)透明,可拖动的简单实例
2016/07/11 Javascript
详解百度百科目录导航树小插件
2017/01/08 Javascript
JavaScript三种绑定事件方式及相互之间的区别分析
2017/01/10 Javascript
JSON 数据格式详解
2017/09/13 Javascript
解决Vue2.x父组件与子组件之间的双向绑定问题
2018/03/06 Javascript
jquery实现图片无缝滚动 蒙版遮蔽效果
2020/01/11 jQuery
vue tab切换,解决echartst图表宽度只有100px的问题
2020/07/19 Javascript
[12:36]《DOTA2》国服注册与激活指南全攻略
2013/04/28 DOTA
Python中尝试多线程编程的一个简明例子
2015/04/07 Python
windows 10下安装搭建django1.10.3和Apache2.4的方法
2017/04/05 Python
Python下实现的RSA加密/解密及签名/验证功能示例
2017/07/17 Python
python+selenium开发环境搭建图文教程
2017/08/11 Python
python dataframe 输出结果整行显示的方法
2018/06/14 Python
Python mutiprocessing多线程池pool操作示例
2019/01/30 Python
python使用MQTT给硬件传输图片的实现方法
2019/05/05 Python
python通过robert、sobel、Laplace算子实现图像边缘提取详解
2019/08/21 Python
美国著名的团购网站:Woot
2016/08/02 全球购物
ALDO美国官网:加拿大女鞋品牌
2018/12/28 全球购物
免税水晶:Duty Free Crystal
2019/05/13 全球购物
白俄罗斯女装和针织品网上商店:Presli.by
2019/10/13 全球购物
简历中求职的个人自我评价
2013/12/03 职场文书
继承公证书样本
2014/04/04 职场文书
见习报告的格式
2014/11/04 职场文书
2014年酒店前台工作总结
2014/11/14 职场文书
幼儿园圣诞节活动总结
2015/05/06 职场文书
教师教育心得体会
2016/01/19 职场文书
zabbix agent2 监控oracle数据库的方法
2021/05/13 Oracle
Nginx中使用Lua脚本与图片的缩略图处理的实现
2022/03/18 Servers
CSS 左边固定宽右边自适应的6种方法
2022/05/15 HTML / CSS