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 相关文章推荐
JQuery显示隐藏页面元素的方法总结
Apr 16 Javascript
AngularJs ng-repeat 嵌套如何获取外层$index
Sep 21 Javascript
使用BootStrapValidator完成前端输入验证
Sep 28 Javascript
浅谈JS验证表单文本域输入空格的问题
Feb 14 Javascript
jQuery的时间datetime控件在AngularJs中的使用实例(分享)
Aug 17 jQuery
JS实现定时任务每隔N秒请求后台setInterval定时和ajax请求问题
Oct 15 Javascript
vue微信分享 vue实现当前页面分享其他页面
Dec 02 Javascript
Bootstrap Table中的多选框删除功能
Jul 15 Javascript
jQuery超简单遮罩层实现方法示例
Sep 06 jQuery
JS实现的tab切换并显示相应内容模块功能示例
Aug 03 Javascript
如何通过javaScript去除字符串两端的空白字符
Feb 06 Javascript
vue3弹出层V3Popup实例详解
Jan 04 Vue.js
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连接Oracle数据库
2006/10/09 PHP
手把手教你使用DedeCms V3的在线采集图文教程
2007/04/03 PHP
php self,$this,const,static,-&amp;gt;的使用
2009/10/22 PHP
smarty巧妙处理iframe中内容页的代码
2012/03/07 PHP
php数组去重的函数代码
2013/02/03 PHP
ThinkPHP3.1新特性之多层MVC的支持
2014/06/19 PHP
PHP开发框架kohana3 自定义路由设置示例
2014/07/14 PHP
php提交post数组参数实例分析
2015/12/17 PHP
JavaScript 对话框和状态栏使用说明
2009/10/25 Javascript
javascript获取浏览器类型和版本的方法(js获取浏览器版本)
2014/03/13 Javascript
JS实现密码框根据焦点的获取与失去控制文字的消失与显示效果
2015/11/26 Javascript
BootStrap智能表单实战系列(四)表单布局介绍
2016/06/13 Javascript
jquery过滤特殊字符',防sql注入的实现方法
2016/08/17 Javascript
jquery实现手机端单店铺购物车结算删除功能
2017/02/22 Javascript
JavaScript转换数据库DateTime字段类型方法
2017/06/27 Javascript
Angular X中使用ngrx的方法详解(附源码)
2017/07/10 Javascript
vue better-scroll插件使用详解
2018/01/25 Javascript
原生js封装的ajax方法示例
2018/08/02 Javascript
原生JS实现贪吃蛇小游戏
2020/03/09 Javascript
jQuery中event.target和this的区别详解
2020/08/13 jQuery
[01:30:54]《加油DOTA》 第三期
2014/08/18 DOTA
在Python中操作文件之truncate()方法的使用教程
2015/05/25 Python
Python实现SMTP发送邮件详细教程
2021/03/02 Python
python使用beautifulsoup4爬取酷狗音乐代码实例
2019/12/04 Python
3种python调用其他脚本的方法
2020/01/06 Python
Python如何访问字符串中的值
2020/02/09 Python
Python如何输出整数
2020/06/07 Python
2021年值得向Python开发者推荐的VS Code扩展插件
2021/01/25 Python
小学毕业演讲稿
2014/04/25 职场文书
优秀班主任经验交流材料
2014/06/02 职场文书
毕业生应聘求职信
2014/07/10 职场文书
慈善捐赠倡议书
2014/08/30 职场文书
合同权益转让协议书模板
2014/11/18 职场文书
员工拾金不昧表扬稿
2015/05/05 职场文书
2015年中学总务处工作总结
2015/07/22 职场文书
MySQL into_Mysql中replace与replace into用法案例详解
2021/09/14 MySQL