CSS3 3D 技术手把手教你玩转


Posted in Javascript onSeptember 02, 2016

css3的3d起步

要玩转css3的3d,就必须了解几个词汇,便是透视(perspective)、旋转(rotate)和移动(translate)。透视即是以现实的视角来看屏幕上的2D事物,从而展现3D的效果。旋转则不再是2D平面上的旋转,而是三维坐标系的旋转,就包括X轴,Y轴,Z轴旋转。平移同理。

当然用理论来说明,估计你还不明白。下面是3个gif:

沿着X轴旋转

CSS3 3D 技术手把手教你玩转

沿着Y轴旋转

CSS3 3D 技术手把手教你玩转

沿着Z轴旋转

CSS3 3D 技术手把手教你玩转

旋转应该没问题了,那理解平移起来就比较容易了,就是在在X轴、Y轴、z轴移动。

你可能会说透视比较不好理解,下面我介绍一下透视的几个属性。

perspective

perspective英文名便是透视,没有这东西就没办法形成3D效果,但是这个东西是怎么让我们浏览器形成3D 效果的呢,可以看下面这张图,其实学过绘画的应该知道透视关系,而这里就是这个道理。

CSS3 3D 技术手把手教你玩转

但是在css里它是有数值的,例如perspective: 1000px这个代表什么呢?我们可以这样理解,如果我们直接眼睛靠着物体看,物体就超大占满我们的视线,我们离它距离越来越大,它在变小,立体感也就出来了是不是,其实这个数值构造了一个我们眼睛离屏幕的距离,也就构造了一个虚拟3D假象。

perspective-origin

由上面我们了解了perspective,而加上了这个origin是什么,我们前面说的这个是眼睛离物体的距离,而这个就是眼睛的视线,我们的视点的不同位置就决定了我们看到的不同景象,默认是中心,为perspectice-origin: 50% 50%,第一个数值是 3D 元素所基于的 X 轴,第二个定义在 y 轴上的位置

当为元素定义 perspective-origin 属性时,其子元素会获得透视效果,而不是元素本身。必须与 perspective 属性一同使用,而且只影响 3D 转换元素。(W3school)

CSS3 3D 技术手把手教你玩转

transform-style

perspective又来了,没错,它是css中3D的关键,transform-style默认是flat,如果你要在元素上视线3D效果的话,就必须用上transform-style: preserve-3d,否则就只是平面的变换,而不是3D的变换

手把手带你玩转css3-3d

以上我们稍微了解概念,下面就开始实战吧!

我们看一个效果,是不是很酷炫:直接访问https://bupt-hjm.github.io/css3-3d/,觉得可以的话记得给star咯hh

第一步:html结构

很简单的一个容器包裹着一个装了6个piece的piece-box

<div class="container">
 <div class="piece-box">
  <div class="piece piece-1"></div>
  <div class="piece piece-2"></div>
  <div class="piece piece-3"></div>
  <div class="piece piece-4"></div>
  <div class="piece piece-5"></div>
  <div class="piece piece-6"></div>
 </div>
</div>

第二步: 加上必要的3D属性,进入3D世界

通过上面的讲解,应该对perspective比较熟悉了吧,

/*容器*/
.container {
 -webkit-perspective: 1000px;
 -moz-perspective: 1000px;
 -ms-perspective: 1000px;
 perspective: 1000px;
}
/*piece盒子*/
 .piece-box {
  perspective-origin: 50% 50%;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -ms-transform-style: preserve-3d;
  transform-style: preserve-3d;
}

第三步:加入必要的样式

/*容器*/
.container {
 -webkit-perspective: 1000px;
 -moz-perspective: 1000px;
 -ms-perspective: 1000px;
 perspective: 1000px;
}
/*piece盒子*/
.piece-box {
 position: relative;
 width: 200px;
 height: 200px;
 margin: 300px auto;
 perspective-origin: 50% 50%;
 -webkit-transform-style: preserve-3d;
 -moz-transform-style: preserve-3d;
 -ms-transform-style: preserve-3d;
 transform-style: preserve-3d;
}
/*piece通用样式*/
.piece {
 position: absolute;
 width: 200px;
 height: 200px;
 background: red;
 opacity: 0.5;

}
.piece-1 {
 background: #FF6666;

}
.piece-2 {
 background: #FFFF00;
}
.piece-3 {
 background: #006699;
}
.piece-4 {
 background: #009999;
}
.piece-5 {
 background: #FF0033;
}
.piece-6 {
 background: #FF6600;
}

当然,在你完成这步之后你还是只看到一个正方形,也就是我们的piece-6,因为我们的3Dtransform还没开始

CSS3 3D 技术手把手教你玩转

第四步:3D变换来袭

首先是实现走马灯,我们先不要让它走,先实现灯部分。

如何实现呢?因为要构成一个圆,圆是360度,而我们有6个piece,那么,很容易想到,我们需要把每一个piece以递增60度的方式rotateY,就变成如下

CSS3 3D 技术手把手教你玩转

如何把他们从中心拉开呢?

这里我们还要注意一点,在我们使元素绕Y轴旋转以后,其实X轴和Z轴也会跟着旋转,所所以正方体的每个面的垂直线还是Z轴,我们就只需要改变下translateZ的值,而当translateZ为正的时候,就朝着我们的方向走来,这样就可以拉开了

但是拉开的距离如何衡量?

CSS3 3D 技术手把手教你玩转

是不是一目了然了~

下面我们再修改下css

.piece-1 {
 background: #FF6666;
 -webkit-transform: rotateY(0deg) translateZ(173.2px);
 -ms-transform: rotateY(0deg) translateZ(173.2px);
 -o-transform: rotateY(0deg) translateZ(173.2px);
 transform: rotateY(0deg) translateZ(173.2px);

}
.piece-2 {
 background: #FFFF00;
 -webkit-transform: rotateY(60deg) translateZ(173.2px);
 -ms-transform: rotateY(60deg) translateZ(173.2px);
 -o-transform: rotateY(60deg) translateZ(173.2px);
 transform: rotateY(60deg) translateZ(173.2px);
}
.piece-3 {
 background: #006699;
 -webkit-transform: rotateY(120deg) translateZ(173.2px);
 -ms-transform: rotateY(120deg) translateZ(173.2px);
 -o-transform: rotateY(120deg) translateZ(173.2px);
 transform: rotateY(120deg) translateZ(173.2px);
}
.piece-4 {
 background: #009999;
 -webkit-transform: rotateY(180deg) translateZ(173.2px);
 -ms-transform: rotateY(180deg) translateZ(173.2px);
 -o-transform: rotateY(180deg) translateZ(173.2px);
 transform: rotateY(180deg) translateZ(173.2px);
}
.piece-5 {
 background: #FF0033;
 -webkit-transform: rotateY(240deg) translateZ(173.2px);
 -ms-transform: rotateY(240deg) translateZ(173.2px);
 -o-transform: rotateY(240deg) translateZ(173.2px);
 transform: rotateY(240deg) translateZ(173.2px);
}
.piece-6 {
 background: #FF6600;
 -webkit-transform: rotateY(300deg) translateZ(173.2px);
 -ms-transform: rotateY(300deg) translateZ(173.2px);
 -o-transform: rotateY(300deg) translateZ(173.2px);
 transform: rotateY(300deg) translateZ(173.2px);
}

是不是已经实现了走马灯了?

CSS3 3D 技术手把手教你玩转

第五步:animation让3D动起来

要实现走马灯动,其实很简单,我们只要在piece-box上加上旋转动画就行了,5s完成动画,从0度旋转到360度

/*piece盒子*/
.piece-box {
 position: relative;
 width: 200px;
 height: 200px;
 margin: 300px auto;
 perspective-origin: 50% 50%;
 -webkit-transform-style: preserve-3d;
 -moz-transform-style: preserve-3d;
 -ms-transform-style: preserve-3d;
 transform-style: preserve-3d;
 animation: pieceRotate 5s;
 -moz-animation: pieceRotate 5s; /* Firefox */
 -webkit-animation: pieceRotate 5s; /* Safari and Chrome */
 -o-animation: pieceRotate 5s ; /* Opera */
}
/*走马灯动画*/
@keyframes pieceRotate
{
0% {-webkit-transform: rotateY(0deg);
  -ms-transform: rotateY(0deg);
  -o-transform: rotateY(0deg);
  transform: rotateY(0deg);}
100% {-webkit-transform: rotateY(360deg);
  -ms-transform: rotateY(360deg);
  -o-transform: rotateY(360deg);
  transform: rotateY(360deg);}
}
/* Firefox */
@-moz-keyframes pieceRotate
{
0% {-webkit-transform: rotateY(0deg);
  -ms-transform: rotateY(0deg);
  -o-transform: rotateY(0deg);
  transform: rotateY(0deg);}
100% {-webkit-transform: rotateY(360deg);
  -ms-transform: rotateY(360deg);
  -o-transform: rotateY(360deg);
  transform: rotateY(360deg);}
}
/* Safari and Chrome */
@-webkit-keyframes pieceRotate
{
0% {-webkit-transform: rotateY(0deg);
  -ms-transform: rotateY(0deg);
  -o-transform: rotateY(0deg);
  transform: rotateY(0deg);}
100% {-webkit-transform: rotateY(360deg);
  -ms-transform: rotateY(360deg);
  -o-transform: rotateY(360deg);
  transform: rotateY(360deg);}
}
/* Opera */
@-o-keyframes pieceRotate
{
0% {-webkit-transform: rotateY(0deg);
  -ms-transform: rotateY(0deg);
  -o-transform: rotateY(0deg);
  transform: rotateY(0deg);}
100% {-webkit-transform: rotateY(360deg);
  -ms-transform: rotateY(360deg);
  -o-transform: rotateY(360deg);
  transform: rotateY(360deg);}
}

这里就不放gif了~hhh是不是实现了酷炫的效果,还没结束哦~更酷炫的正方体组装

正方体,其实也不难实现,我这里就不很详细说了,你首先可以想象一个面,然后去拓展其他面如何去实现,比如我们把正方体的前面translateZ(100px)让它靠近我们100px,然后后面translateZ(-100px)让它远离我们100px,左边是先translateX(-100px再rotateY(90deg),右边就是translateX(100px)再rotateY(90deg),上面是先translateY(-100px),rotateX(90deg),下面是先translateY(100px),rotateX(90deg),只要我们写进动画,一切就大功告成。

css就为如下,以下就只放piece1,其他读者可以自己类比实现,或者看我github的源码

.piece-1 {
  background: #FF6666;
  -webkit-transform: rotateY(0deg) translateZ(173.2px);
  -ms-transform: rotateY(0deg) translateZ(173.2px);
  -o-transform: rotateY(0deg) translateZ(173.2px);
  transform: rotateY(0deg) translateZ(173.2px);
  animation: piece1Rotate 5s 5s;
  -moz-animation: piece1Rotate 5s 5s; /* Firefox */
  -webkit-animation: piece1Rotate 5s 5s; /* Safari and Chrome */
  -o-animation: piece1Rotate 5s 5s; /* Opera */
  -webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */
  animation-fill-mode: forwards;
 }
/*front*/
 @keyframes piece1Rotate
 {
 0% {-webkit-transform: rotateY(0deg) translateZ(173.2px);
  -ms-transform: rotateY(0deg) translateZ(173.2px);
  -o-transform: rotateY(0deg) translateZ(173.2px);
  transform: rotateY(0deg) translateZ(173.2px);}
 100% {-webkit-transform: rotateY(0deg) translateZ(100px);
  -ms-transform: rotateY(0deg) translateZ(100px);
  -o-transform: rotateY(0deg) translateZ(100px);
  transform: rotateY(0deg) translateZ(100px);}
 }
 /* Firefox */
 @-moz-keyframes piece1Rotate
 {
 0% {-webkit-transform: rotateY(0deg) translateZ(173.2px);
  -ms-transform: rotateY(0deg) translateZ(173.2px);
  -o-transform: rotateY(0deg) translateZ(173.2px);
  transform: rotateY(0deg) translateZ(173.2px);}
 100% {-webkit-transform: rotateY(0deg) translateZ(100px);
  -ms-transform: rotateY(0deg) translateZ(100px);
  -o-transform: rotateY(0deg) translateZ(100px);
  transform: rotateY(0deg) translateZ(100px);}
 }
 /* Safari and Chrome */
 @-webkit-keyframes piece1Rotate
 {
 0% {-webkit-transform: rotateY(0deg) translateZ(173.2px);
  -ms-transform: rotateY(0deg) translateZ(173.2px);
  -o-transform: rotateY(0deg) translateZ(173.2px);
  transform: rotateY(0deg) translateZ(173.2px);}
 100% {-webkit-transform: rotateY(0deg) translateZ(100px);
  -ms-transform: rotateY(0deg) translateZ(100px);
  -o-transform: rotateY(0deg) translateZ(100px);
  transform: rotateY(0deg) translateZ(100px);}
 }
 /* Opera */
 @-o-keyframes piece1Rotate
 {
 0% {-webkit-transform: rotateY(0deg) translateZ(173.2px);
  -ms-transform: rotateY(0deg) translateZ(173.2px);
  -o-transform: rotateY(0deg) translateZ(173.2px);
  transform: rotateY(0deg) translateZ(173.2px);}
 100% {-webkit-transform: rotateY(0deg) translateZ(100px);
  -ms-transform: rotateY(0deg) translateZ(100px);
  -o-transform: rotateY(0deg) translateZ(100px);
  transform: rotateY(0deg) translateZ(100px);}
 }

细心的读者可以发现我用了一个animation-fill-mode: forwards;,这个其实就是让这些piece保持动画最后的效果,也就是正方体的效果,读者可以不加试试看,那还是会恢复原样。

最后就是正方体的旋转了,前面我们的容器已经用过animation了,读者可能会想我再加个class放animaiton不就行了,hhh,animaiton会覆盖掉前面的,那前面的走马灯的动画就没了,所以在html结构中,我再加了一个box包裹piece, 如下

<div class="container">
 <div class="piece-box">
  <div class="piece-box2"><!--新加的容器-->
   <div class="piece piece-1"></div>
   <div class="piece piece-2"></div>
   <div class="piece piece-3"></div>
   <div class="piece piece-4"></div>
   <div class="piece piece-5"></div>
   <div class="piece piece-6"></div>
  </div>
 </div>
</div>

在动画上我们可以控制正方体动画的延时时间,就是等到正方体组装完成后再开始动画

animation: boxRotate 5s 10s infinite;第一个5s是动画时长,第二个10s是延时时间,然后我们让正方体的旋转,绕X轴从0度到360度,绕Y轴也0到Y轴360度。

.piece-box2 {
 -webkit-transform-style: preserve-3d;
 -moz-transform-style: preserve-3d;
 -ms-transform-style: preserve-3d;
 transform-style: preserve-3d;
 animation: boxRotate 5s 10s infinite;
 -moz-animation: boxRotate 5s 10s infinite; /* Firefox */
 -webkit-animation: boxRotate 5s 10s infinite; /* Safari and Chrome */
 -o-animation: boxRotate 5s 10s infinite; /* Opera */
}
/*正方体旋转动画*/
@keyframes boxRotate
{
0% {-webkit-transform: rotateX(0deg) rotateY(0deg););
 -ms-transform: rotateX(0deg) rotateY(0deg););
 -o-transform: rotateX(0deg) rotateY(0deg););
 transform: rotateX(0deg) rotateY(0deg););}
100% {-webkit-transform: rotateX(360deg) rotateY(360deg);
 -ms-transform: rotateX(360deg) rotateY(360deg);
 -o-transform: rotateX(360deg) rotateY(360deg);
 transform: rotateX(360deg) rotateY(360deg);}
}
/* Firefox */
@-moz-keyframes boxRotate
{
0% {-webkit-transform: rotateX(0deg) rotateY(0deg););
 -ms-transform: rotateX(0deg) rotateY(0deg););
 -o-transform: rotateX(0deg) rotateY(0deg););
 transform: rotateX(0deg) rotateY(0deg););}
100% {-webkit-transform: rotateX(360deg) rotateY(360deg);
 -ms-transform: rotateX(360deg) rotateY(360deg);
 -o-transform: rotateX(360deg) rotateY(360deg);
 transform: rotateX(360deg) rotateY(360deg);}
}
/* Safari and Chrome */
@-webkit-keyframes boxRotate
{
0% {-webkit-transform: rotateX(0deg) rotateY(0deg););
 -ms-transform: rotateX(0deg) rotateY(0deg););
 -o-transform: rotateX(0deg) rotateY(0deg););
 transform: rotateX(0deg) rotateY(0deg););}
100% {-webkit-transform: rotateX(360deg) rotateY(360deg);
 -ms-transform: rotateX(360deg) rotateY(360deg);
 -o-transform: rotateX(360deg) rotateY(360deg);
 transform: rotateX(360deg) rotateY(360deg);}
}
/* Opera */
@-o-keyframes boxRotate
{
0% {-webkit-transform: rotateX(0deg) rotateY(0deg););
 -ms-transform: rotateX(0deg) rotateY(0deg););
 -o-transform: rotateX(0deg) rotateY(0deg););
 transform: rotateX(0deg) rotateY(0deg););}
100% {-webkit-transform: rotateX(360deg) rotateY(360deg);
 -ms-transform: rotateX(360deg) rotateY(360deg);
 -o-transform: rotateX(360deg) rotateY(360deg);
 transform: rotateX(360deg) rotateY(360deg);}
}

最后效果,大功告成!

以上就是对CSS 3D的实现例子,有需要的同学可以参考下,谢谢大家对本站的支持!

Javascript 相关文章推荐
验证码按回车不变解决方法
Mar 29 Javascript
JS实现仿京东淘宝竖排二级导航
Dec 08 Javascript
浅谈javascript中的闭包
May 13 Javascript
纯jquery实现模仿淘宝购物车结算
Aug 20 Javascript
js实现div模拟模态对话框展现URL内容
May 27 Javascript
JavaScript基于DOM操作实现简单的数学运算功能示例
Jan 16 Javascript
Bootstrap标签页(Tab)插件使用方法
Mar 21 Javascript
详解用Node.js实现Restful风格webservice
Sep 29 Javascript
vue 2.1.3 实时显示当前时间,每秒更新的方法
Sep 16 Javascript
Node.js对MongoDB进行增删改查操作的实例代码
Apr 18 Javascript
JS实现水平遍历和嵌套递归操作示例
Aug 15 Javascript
微信小程序实现购物车代码实例详解
Aug 29 Javascript
js实现StringBuffer的简单实例
Sep 02 #Javascript
纯JS实现可拖拽表单的简单实例
Sep 02 #Javascript
vue.js入门教程之绑定class和style样式
Sep 02 #Javascript
js绘制购物车抛物线动画
Nov 18 #Javascript
基于jQuery实现发送短信验证码后的倒计时功能(无视页面关闭)
Sep 02 #Javascript
基于JS实现发送短信验证码后的倒计时功能(无视页面刷新,页面关闭不进行倒计时功能)
Sep 02 #Javascript
node.js中module.exports与exports用法上的区别
Sep 02 #Javascript
You might like
PHP+FLASH实现上传文件进度条相关文件 下载
2007/07/21 PHP
PHP实现的汉字拼音转换和公历农历转换类及使用示例
2014/07/01 PHP
php中adodbzip类实例
2014/12/08 PHP
php封装的smartyBC类完整实例
2016/10/19 PHP
PHP内置加密函数详解
2016/11/20 PHP
PHP分享图片的生成方法
2018/04/25 PHP
jQuery的实现原理的模拟代码 -4 重要的扩展函数 extend
2010/08/03 Javascript
jquery jqPlot API 中文使用教程(非常强大的图表工具)
2011/08/15 Javascript
javascript动态加载实现方法一
2012/08/22 Javascript
jQuery下实现等待指定元素加载完毕(可改成纯js版)
2013/07/11 Javascript
Js实现滚动变色的文字效果
2014/06/16 Javascript
Linux下编译安装php libevent扩展实例
2015/02/14 Javascript
jQuery实现冻结表头的方法
2015/03/09 Javascript
IE6兼容透明背景图片及解决方案
2015/08/19 Javascript
javascript中for/in循环及使用技巧
2015/09/01 Javascript
浅谈Cookie的生命周期问题
2016/08/02 Javascript
简单实现bootstrap选项卡效果
2017/02/08 Javascript
bootstrap+jQuery 实现下拉菜单中复选框全选和全不选效果
2017/06/12 jQuery
jQuery事件对象的属性和方法详解
2017/09/09 jQuery
Vue.js表单标签中的单选按钮、复选按钮和下拉列表的取值问题
2017/11/22 Javascript
Vue 过滤器filters及基本用法
2017/12/26 Javascript
jQuery常见的遍历DOM操作详解
2018/09/05 jQuery
详解关于Vue2.0路由开启keep-alive时需要注意的地方
2018/09/18 Javascript
JavaScript实现简单随机点名器
2019/11/21 Javascript
详解阿里Node.js技术文档之process模块学习指南
2021/01/04 Javascript
[50:45]2018DOTA2亚洲邀请赛 4.6 淘汰赛 VP vs TNC 第一场
2018/04/10 DOTA
python定时利用QQ邮件发送天气预报的实例
2017/11/17 Python
Python3中条件控制、循环与函数的简易教程
2017/11/21 Python
python原类、类的创建过程与方法详解
2019/07/19 Python
Python编程学习之如何判断3个数的大小
2019/08/07 Python
Python利用命名空间解析XML文档
2020/08/10 Python
测绘工程系学生的自我评价
2013/11/30 职场文书
小学英语教学反思案例
2014/02/04 职场文书
sqlserver连接错误之SQL评估期已过的问题解决
2022/03/23 SQL Server
纯CSS实现一个简单步骤条的示例代码
2022/07/15 HTML / CSS
Redis过期数据是否会被立马删除
2022/07/23 Redis