详解如何用 CSS3 完成 3D transform变换

Tips:阅读提示!!!

  1. 首先,本文针对的是3D transform变换的学习,所以你需要对2D transform变换 有一定的了解
  2. 其次,需要说明的是,代码是一种需要自己不断实践的学科,建议各位在开始学习本篇文档的时候,先创建一个 html页面来边读边练,
    相信这样,一定会给你留下一个非常直观且深刻的印象!

本文练习一些公共代码

鉴于本文贴了不少代码来演示,所有这里提前放一个所有演示的公共代码片段

    // 公共DOM元素,后续均为此写样式表
    // 舞台容器
    <div class="stage">
        // &#x53D8;&#x6362;&#x5143;&#x7D20;

    </div>

    // &#x6837;&#x5F0F;&#x517C;&#x5BB9;&#x7684;&#x5404;&#x4E2A;&#x6D4F;&#x89C8;&#x5668;&#x5C5E;&#x6027;&#x5934;&#xFF0C;&#x6709;&#x9700;&#x8981;&#x7684;&#x5728;&#x5404;&#x81EA;&#x4EE3;&#x7801;&#x4E2D;&#x6DFB;&#x52A0;
    // &#x4E0B;&#x5217;&#x6D4B;&#x8BD5;&#x4EE3;&#x7801;&#x4F7F;&#x7528;Chorme&#x8FD0;&#x884C;
    -webkit-  /* Safari &#x548C; Chrome */
    -ms-      /* IE */
    -moz-     /* Firefox */
    -o-      /* Opera */

实现3D变换的基础 — 透视(perspective)

当我们步入 CSS3动画殿堂之时,我们一般都会从一些简单动的东西开始学习,比如元素的位移,旋转,放大缩小之类的 2D transform&#x53D8;&#x6362;
那么如何在一个 2D的屏幕上实现 3D的变换呢,这里我们就先需要有一个概念,就是 透视

从一个最简单的 透视 说起,我们小时候的数学课上,数学老师一定会给我们画一个立体正方形,能够在 2D平面上看出 3D效果就是 透视 的作用

用一张直观的图片来说明一下

详解如何用 CSS3 完成 3D transform变换

透视的类型有以下几种

详解如何用 CSS3 完成 3D transform变换

那么在CSS3中如何用代码实现透视呢?

  1. 主要是通过 perspective属性来实现定义透视距离
  2. perspective属性定义 3D元素距视图的距离,以像素计,该属性允许您改变 3D元素查看 3D元素的视图
  3. 透视距离可以这么理解,如果你的显示器宽度是 1920px的分辨率,那么 2000px的透视距离就近似于,从显示器平面开始,一个显示器宽度的距离
  4. 默认值是 0px,可以理解为初始位置
  5. 注意!!!当为元素定义 perspective 属性时,其子元素会获得透视效果,而不是元素本身
  6. 它有两种写法,单个元素时候看似效果相同,但是多元素在同一个舞台上呈现时,就会出现问题了
  7. 第一种,是写在舞台元素上,定义 perspective属性
  8. 第二种,是配合 transform属性一起,例如: transform: perspective(600px) rotateY(45deg)
  9. 参考下方示例,您可以在自己的demo中测试效果区别,你会发现第二种所有元素都是同一角度的旋转,
    这是因为第一种透视点是 .stage中央,第二种透视点是每一个 .box中央
    // 第一种写法
    .stage {
        width: 100%;
        height: 100%;
        perspective: 1000px;
        -webkit-perspective: 500px;
    }
    .stage .box {
        width: 100px;
        height: 100px;
        margin: 100px 100px;
        background-color: #55ffff;
        display: inline-block;
        transform: rotateY(65deg);
        -webkit-transform: rotateY(65deg);
    }

    // 第二种写法
    .stage {
        width: 100%;
        height: 100%;
    }
    .stage .box {
        width: 100px;
        height: 100px;
        margin: 100px 100px;
        background-color: #55ffff;
        display: inline-block;
        transform: perspective(1000px) rotateY(65deg);
        -webkit-transform: perspective(1000px) rotateY(65deg);
    }

透视基点位置属性(perspective-origin)

  1. 既然我我们有透视距离的概念,那么这个透视基点的意思就是,我们所看的舞台或者元素的中心
  2. perspective(透视)属性必须和 perspective-origin(透视基点)属性一同使用
  3. perspective-origin: x-axis y-axis,xy可以分别是这些值:
  4. left
  5. right
  6. center
  7. length,像素
  8. %,百分比
  9. 举个不恰当的例子,透视基点类似看足球比赛中那个球的位置,因为所有人眼都会盯着场上的足球,你和球的距离理解为透视距离就好,当然这并不恰当,不要在意
  10. 该属性必须与 perspective属性一同使用,而且只影响 3D转换元素,它可以定义在元素中,并且同 perspective属性一样,定义在哪里影响哪里
  11. 默认值是 50% 50%,表示 xy 中心位置
  12. 下面我们利用一个示例来看看,你依旧可以通过修改demo中的参数,看到效果的变化
    // 50% 50% 正好是变换元素的中心点,也是默认值
    .stage {
        width: 100%;
        height: 100%;
        perspective: 604px;
        -webkit-perspective: 604px;
        // 使用百分比
        perspective-origin: 50% 50%;
        -webkit-perspective-origin: 50% 50%;
        // 使用像素
        // perspective-origin: 200px 100px;
        // -webkit-perspective-origin: 200px 100px;
        // 使用位置
        // perspective-origin: left center;
        // -webkit-perspective-origin: left center;
        // 也可以混用
        // perspective-origin: 200px 10%;
        // -webkit-perspective-origin: 200px 10%;
    }
    .stage .box {
        width: 100px;
        height: 100px;
        margin: 100px 100px;
        background-color: #55ffff;
        display: inline-block;
        transform: rotateY(65deg);
        -webkit-transform: rotateY(65deg);
    }

透视盲区

在我们进行3D变换的时候还会遇到透视盲区的问题,比如一个正方形,旋转45°之后,正好和你的视线完全平行,那么这个面你就看不到,这就是视觉盲区
你可以利用下方代码在自己的demo中查看一下效果

    // 我的电脑分辨率是1920*1080,透视距离是604px
    // 如果你看不到效果,可以尝试修改旋转角度或透视距离,找一下出现盲区的角度
    .stage {
        width: 100%;
        height: 100%;
        perspective: 604px;
        -webkit-perspective: 604px
    }

    .stage .box {
        width: 100px;
        height: 100px;
        margin: 100px 100px;
        background-color: #55ffff;
        display: inline-block;
        transform: rotateY(65deg);
        -webkit-transform: rotateY(65deg);
    }

实现静态的3D变换 — 转换(transform)

相信在2D变换的学习中对于 transform属性一定不陌生了,它不仅可以进行 2D变换,也可以进行 3D变换,只不过需要借助上一个透视的属性,我们才可以在屏幕中看到变换的效果

先来说明一个三维坐标系的概念,通俗点来说, z&#x8F74;对应垂直方向, x&#x8F74;对应前后方向, y&#x8F74;对应左右方向
后续我们所说的绕轴变化,你就可以参考这个图例,想象一下发生的变换

详解如何用 CSS3 完成 3D transform变换

接下来我们来看看 transform支持的变换类型,如果对此您有疑问,可以参考w3school的可测试教程

  1. 2D类型

    转换(位移) translate(x,y) / translateX(x) / translateY(y)
    缩放 scale(x,y) / scaleX(x) / scaleY(y)
    旋转 rotate(angle) / rotateX(angle) / rotateY(angle)
    倾斜 skew(x-angle,y-angle) / skewX(angle) / skewY(angle)
    matrix(),把所有 2D 变换方法组合为一个,可接受六个参数, matrix(scaleX(),skewY(),skewX(),scaleY(),translateX(),translateY())

  2. 3D类型

    转换(位移) translate3d(x,y,z) / translateZ(z),主要是垂直距离的位移
    缩放 scale3d(x,y,z) / scaleZ(z),同样是垂直距离的缩放
    旋转 rotate3d(x,y,z,angle) / rotateX(angle) / rotateY(angle) / rotateZ(angle)
    rotateX/ rotateY/ rotateZ三种函数分别意思是绕着 XYZ轴做旋转运动, angle参数为单位为 deg的角度
    rotate3d函数定义一个变换,它将元素围绕固定轴移动而不使其变形,运动量由指定的角度定义,
    如果为正,运动将为顺时针,如果为负,则为逆时针,想要了解更多可以参考 这篇文档中的动态示例 理解

2D变换请参考 本文Tips中的链接 或百度教程,下面我们来详细看下实现静态 3D变换的代码

    .stage {
        width: 100%;
        height: 100%;
        perspective: 500px;
        -webkit-perspective: 500px;
        perspective-origin: 50% 50%;
        -webkit-perspective-origin: 50% 50%;
    }

    .stage .box {
        width: 100px;
        height: 100px;
        margin: 100px 100px;
        background-color: #55ffff;
        display: inline-block;
        // 这里表示绕Y轴做旋转65度的变换
        transform: rotate3d(0, 1, 0, 65deg);
        -webkit-transform: rotate3d(0, 1, 0, 65deg);
    }

转换基点位置属性(transform-origin)

  1. transform-origin属性允许您改变被转换元素的位置, 2D转换元素能够改变元素xy轴, 3D转换元素还能改变其z轴
  2. transform-origin: x-axis y-axis z-axis,这定义了视图被置于xyz轴的何处,z值只能是 length,xy可以分别是这些值:
  3. left
  4. right
  5. center
  6. length,像素
  7. %,百分比
  8. transform-origin属性必须和 transform属性一同使用
  9. 默认值是 50% 50% 0,表示转换基点位于 xy 中心以及 z轴 0 的位置
  10. 下面我们利用一个示例来看看,你依旧可以通过修改demo中的参数,看到效果的变化
    .stage {
        width: 100%;
        height: 100%;
        perspective: 500px;
        -webkit-perspective: 500px;
        perspective-origin: 50% 50%;
        -webkit-perspective-origin: 50% 50%;
    }

    .stage .box {
        width: 100px;
        height: 100px;
        margin: 100px 100px;
        background-color: #55ffff;
        display: inline-block;
        transform: rotate3d(0, 1, 0, 65deg);
        -webkit-transform: rotate3d(0, 1, 0, 65deg);
        // 表示旋转元素的基准点在 x 100px  y 100px  z -900px 位置
        // 值类型自由使用,不做过多说明,参考上方透视基点属性
        transform-origin: 100px 100px -900px;
        -webkit-transform-origin: 100px 100px -900px;
    }

转换如何呈现属性(transform-style)

  1. transform-style属性规定如何在 3D空间中呈现被嵌套的元素
  2. transform-style: flat | preserve-3dflat表示子元素将不保留其 3D位置, preserve-3d表示子元素保留其 3D位置
  3. 默认值是 flat,不保留3D位置
  4. 下面用一个不同于上面几个示例的示例来展示整个属性的效果,你可以在demo中修改几个属性来查看效果

    .stage {
        width: 100%;
        height: 100%;
        perspective: 1600px;
        -webkit-perspective: 1600px;
    }

    .stage .box {
        width: 400px;
        height: 400px;
        margin: 100px 100px;
        background-color: #55ffff;
        transform: rotate3d(0, 1, 0, 65deg);
        -webkit-transform: rotate3d(0, 1, 0, 65deg);
        // 这里会展示3D效果
        transform-style: preserve-3d;
        -webkit-transform-style: preserve-3d;
        // 不展示3D效果
        // transform-style: flat;
        // -webkit-transform-style: flat;
    }

    .stage .box .box-out {
        width: 90%;
        height: 90%;
        background-color: #ffff00;
        transform: rotate3d(0.5, 1, 0, 85deg);
        -webkit-transform: rotate3d(0.5, 1, 0, 85deg);
    }

    .stage .box .box-out .box-in {
        width: 150%;
        height: 150%;
        background-color: #aaff7f;
        transform: rotate3d(0.1, 1, 0.5, 85deg);
        -webkit-transform: rotate3d(0.1, 1, 0.5, 85deg);
    }

背面是否可见属性(backface-visibility)

  1. backface-visibility属性定义当元素不面向屏幕时是否可见
  2. backface-visibility: visible | hiddenvisible表示背面是可见的, hidden表示背面不可见
  3. 该属性主要用于不想展示被旋转元素的背面时使用,通常用于一些翻转动效,比如炉石的抽卡,就属于背面可见
  4. 下面我们可以通过翻拍效果示例来理解一下这个属性的作用

    .stage {
        width: 100%;
        height: 100%;
        perspective: 1600px;
        -webkit-perspective: 1600px;
    }

    .box {
        width: 400px;
        height: 400px;
        margin: 100px 100px;
        position: relative;
        transition: 0.5s all;
        transform-style: preserve-3d;
        -webkit-transform-style: preserve-3d;
    }

    .box-prev,
    .box-next {
        width: 100%;
        height: 100%;
        position: absolute;
        transition: 0.5s all;
        backface-visibility: hidden;
    }

    .box-prev {
        background-color: #ffff00;
        z-index: 1;
    }

    .box-next {
        background-color: #aaff7f;
        transform: rotateY(180deg);
        z-index: 0;
    }

    .box:hover{
        transform: rotateY(180deg);
    }

做一些简单的循环动效

学习了上述代码之后,我们可以做一些简单的循环动效了,这里我们用一个简单的翻书效果来练习,当然还有很多奇思妙想期待你自己去实践啦!


    .stage {
        width: 100%;
        height: 100%;
    }

    .box {
        width: 400px;
        height: 400px;
        margin: 100px 100px;
        position: relative;
        transition: 0.5s all;
        transform-style: preserve-3d;
    }

    .box-prev,
    .box-midd,
    .box-next {
        width: 100%;
        height: 100%;
        position: absolute;
        transition: 3s all;
    }

    .box-prev {
        background-color: #ffff9b;
        z-index: 2;
    }

    .box-midd {
        background-color: #aaff7f;
        z-index: 1;
    }

    .box-next {
        display: flex;
        justify-content: space-between;
        z-index: 0;
    }

    .box-next span {
        width: 50%;
        height: 100%;
    }

    .box-next span:nth-child(1) {
        background-color: #ffff9b;
    }

    .box-next span:nth-child(2) {
        background-color: #aaff7f;
    }

    .box:hover .box-prev {
        transform: perspective(800px) rotateY(-180deg);
        transform-origin: perspective(800px) 50% 50% 0;
    }

    .box:hover .box-midd {
        transform: perspective(800px) rotateY(-180deg);
        transform-origin: perspective(800px) 50% 50% 0;
    }

参考文档一 ———— 带你玩转css3的3D!
参考文档二 ———— 好吧,CSS3 3D transform变换,不过如此!
参考文档三 ———— CSS perspective 属性
参考文档三 ———— CSS perspective-origin 属性
参考文档五 ———— CSS transform 属性
参考文档六 ———— CSS transform-origin 属性
参考文档七 ———— CSS transform-style 属性
参考文档八 ———— CSS backface-visibility 属性
参考文档九 ———— CSS3中设置3D变形的transform-style属性详解

我是 fx67ll.com,如果您发现本文有什么错误,欢迎在评论区讨论指正,感谢您的阅读!
如果您喜欢这篇文章,欢迎访问我的 本文github仓库地址,为我点一颗Star,Thanks~ 😃
转发请注明参考文章地址,非常感谢!!!

Original: https://www.cnblogs.com/fx67ll/p/15467771.html
Author: fx67ll
Title: 详解如何用 CSS3 完成 3D transform变换

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/599586/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 在Linux中使用crontab

    查看已存在的任务 查看crontab 输入命令: cat /etc/crontab 在设定编辑之前都建议列出服务查看一下: crontab -l 语法: **** user_nam…

    数据库 2023年6月14日
    088
  • ajax与thymeleaf分别实现数据传输

    小杰笔记篇: 1:第一种:利用Model和thymeleaf引擎来完成: Controller层: html:引入引擎 第二种方式:ajax: 第一步:创建User实体类假装数据库…

    数据库 2023年6月6日
    093
  • MySQL约束

    约束指对字段的约束,用于确保数据库的数据满足特定的规则。在MySQL中,数据库的约束包括, NOT NULL,PRIMARY KEY,UNIQUE,FOREIGN KEY,CHEC…

    数据库 2023年6月16日
    064
  • Redis——数据操作

    2022-09-20 Redis——select Redis数据库中的数据库的个数为: 16个,使用0号数据库开始的,到第15个数据库结束。 在ubantu中,进入Redis客户端…

    数据库 2023年6月14日
    071
  • NO.2 Windows桌面图标-间距参数调整

    遇到如下问题: 桌面图标自动排序后间隔过大,且如图二这种指向图标能看到图标之间的间隔虚框,此方法可调整虚框的水平和垂直距离,即调整图标之间的间距。 测试电脑: 华为 mateboo…

    数据库 2023年6月14日
    0100
  • java 考试系统 在线学习 视频直播 人脸识别 springboot框架 前后分离 PC和手机端

    新增功能:培训学习模块, PDF电子课程、视频课程、直播课程(自己搭建直播流服务器) 人脸识别(考试时验证,有开关)、补考开关 组建试卷:创建试卷,题目、类型、总分、及格分数、时长…

    数据库 2023年6月6日
    090
  • 达梦产品技术支持培训-day8-DM8数据库备份与还原-实操

    Disql 工具:联机数据备份与还原,包括库备份、表空间备份与还原、表备份与还原; DMRMAN 工具:脱机数据库备份还原与恢复; 客户端工具 MANAGER和CONSOLE:对应…

    数据库 2023年6月11日
    075
  • ODA→Teigha胎压–学习笔记

    数据库结构 记录对象表 对象字典 具有固定类型和固定可访问操作的特定对象的固定结构的固定集合 可以存储和操作各种类型的对象,包括它自己。 每个记录都有一个特定的类类型,每个表也有一…

    数据库 2023年6月14日
    072
  • Pisanix v0.2.0 发布|新增动态读写分离支持

    1.动态读写分离介绍 1.1 介绍 读写分离是业界使用 MySQL 高可用最常用的方案之一,在实际场景中可以提高查询性能,降低服务器负载。本次版本在 v0.1.0 静态规则基础上增…

    数据库 2023年6月16日
    099
  • 高可用 | 关于 Xenon 高可用的一些思考

    原创:知数堂 Xenon 不会补日志,Xenon 只会从包含最大 GTID 的所有 Follower 中选举一个 Follower,使之成为 Leader 。重新配置主从复制,并把…

    数据库 2023年5月24日
    080
  • Docker Bridge 网络原理

    Docker 的网络子系统是可插拔驱动式的,默认情况下存在或支持多种网络接口,如 bridge、host、overlay、macvlan 以及 none 类型的网络接口。 brid…

    数据库 2023年6月6日
    092
  • entitybuilder–一个简单的业务通用框架

    关于业务通用框架的思考 业务系统是千差万别的,例如,保存、更新和删除订单,或者保存订单和保存客户,走的根本不是一个流程。但是,它们还是有共同点,它们的流程大致可以分成下面的几个部分…

    数据库 2023年6月6日
    090
  • 2020年十大最佳自动化测试工具

    Best Automation Testing Tools for 2020 对更快交付高质量软件(或”快速质量”)的需求要求组织以敏捷,持续集成(CI)和…

    数据库 2023年6月9日
    076
  • mysql主从搭建

    mysql主从搭建 环境:ubuntu20.04.1,mysql:8.0.22。主:192.168.87.3备:192.168.87.6 安装数据库 sudo apt-get in…

    数据库 2023年6月11日
    076
  • COLA 架构规范定义

    基础架构图 Adapter 适配层:对前端展示的路由和适配。 VO:返回给前端的对象 assembler:将 responseDTO 转换为 VO web:处理页面请求的 Cont…

    数据库 2023年6月6日
    0111
  • mysql8主从配置

    一、一般配置主从(这里主是m3300,从是3301、3302) 1.配置m3301 从mysql8里拿出这两个文件到m3301 2.配置my.ini &#x521D;&am…

    数据库 2023年5月24日
    092
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球