前言:

最近玩了玩用css来构建3D效果,写了几个demo,所以博客总结一下。  在阅读这篇博客之前,请先自行了解一下css 3D的属性,例如:transform-style,transform-origin,transform, perspective。

demo1

高度可变的立方体,先来看看最终效果,自己弄得有点丑,如果设计师调下色,添加点元素应该会好看的多

  

1.  我们先用css实现一个长方体,一个长方体有6个边,我们写6个div,并用一个div包裹起来

<div class="cube-box">
<div class="cube1 cube"></div>
<div class="cube2 cube"></div>
<div class="cube3 cube"></div>
<div class="cube4 cube"></div>
<div class="cube5 cube"></div>
<div class="cube6 cube"></div>
</div>

2.  给.cube-box设置宽高以及preserve-3d属性保留子元素3d转换,子元素.cube全部绝对定位

.cube-box{
transform-style: preserve-3d;
width: 30px;
height: 100px;
position: relative;
}
.cube{
position: absolute;
left:;
top:;
}

3.  先写一个面.cube1,宽高100%等同于父元素的宽高,背景色为red,代码和效果如下

.cube1{
width: 100%;
height: 100%;
background: red;
}

4.  为了之后方便我们看到立体效果,现在我们旋转一下父元素,加入如下代码,效果如下

.cube-box{
transform: rotateX(-30deg) rotateY(45deg);
}

5.  .cube1作为第一个元素,我们不需要它旋转,它作为默认面,现在拼接第二个面.cube2,按照.cube1的写法,但是我们设置为绿色,效果如下,.cube2重叠在.cube1上,因此我们还需要旋转.cube2

.cube2{
width: 100%;
height: 100%;
background: green;
}

6.  我们现在试着旋转一下.cube2,变成了如下效果。关于rotate的旋转方向这里不解释,不懂的朋友可以自行查看其他文档。

.cube2{
width: 100%;
height: 100%;
background: green;
transform: rotateY(-90deg);
}

7.  在用translate3d移动一下吧。  效果如下图,屌屌屌。  但是问题来了,这里的代码不够灵活,translate的值需要手动计算,现在宽是30px,需要移动它的一半15px进行拼接,这个值需要我们手动计算写上去,或者到时候用js计算,太low,我希望只需要用js根据后端数据动态设置父元素.cube-box的宽高,子元素全部自适应就行,这样才更好用。

.cube2{
width: 100%;
height: 100%;
background: green;
transform: rotateY(-90deg) translate3d(15px,0,15px);
}

8.  因此现在我们要使用另一个属性transform-origin,transform-origin默认是“center center 0;”或者说“50% 50% 0;”,所以在第6个步骤的时候,我们旋转.cube2的时候是根据它自身中间的位置进行的旋转,我们改造一下,把转换的位置定在元素左边,也同样达到了效果,代码反而更简单了

.cube2{
width: 100%;
height: 100%;
background: green;
transform-origin: left top;
transform: rotateY(-90deg);
}

9.  按照.cube2的方法我们给.cube3按照同样的写法旋转,并设置蓝色,效果如下

.cube3{
width: 100%;
height: 100%;
background: blue;
transform-origin: right top;
transform: rotateY(90deg);
}

10.  .cube4就有点不一样了,下一个面不需要旋转,只需要把.cube1向Z轴方向移动30px宽的位置,X和Y轴可以用width和height作为基数设置百分比,比如width是20px,如果要X轴移动20px,可以设置translateX(100%),但是Z就只能用具体值了。  所以这里我没有解决low的问题,我只能手动的写上translateZ的值,或者用js来动态赋值。  效果如下,如果有更好的方案,可以评论博客告知我。

.cube4{
width: 100%;
height: 100%;
background: gray;
transform-origin: right top;
transform: translateZ(30px);
}

11.  .cube5也就是顶面,我们的顶面和低面都是正方形的,.cube5如果写宽高100%就是长方形了,为了不手动或者动态写高度,这里使用了另一种写法设置width:100%;不设置height,设置padding-top:100%;这样同样使.cube5变成了正方形,定义粉红色,延X轴旋转90度,代码和效果如下

.cube5{
width: 100%;
padding-top: 100%;
background: pink;
transform-origin: left top;
transform: rotateX(90deg);
}

12.   最后.cube6和.cube5写法一样,只是我们需要把位置绝对定位到底部,这时候把.cube类设置为透明度50%,方便我们查看,代码和效果如下

.cube6{
width: 100%;
padding-top: 100%;
background: black;
top: inherit;
bottom:;
transform-origin: left bottom;
transform: rotateX(-90deg);
}

13.  我们把每一个面都定义为红色,调整一下每一个面的颜色值,这样看起来就有视角的效果

14.   现在长方体已经写好,我们来点动效吧,添加一个div.cube-wapper把刚才的cube-box再包裹一层,让cube-box绝对定位到父元素底部,这样高度变化的时候是向上延伸和收缩,js定时器每隔5秒改变一下box的高度,效果如下

let boxs = document.getElementsByClassName('cube-box');
setInterval(()=>{
for(let item in boxs){
if(boxs[item].style) boxs[item].style.height = `${Math.random()*300}px`;
}
},5000)

15.  不对啊,怎么底部还是有移动?  原因是我们tranform的rotate写在了.cube-box上,当高度改变的时候,会受到旋转的影响导致位置偏移,因此把.cube-box的tranform写到.cube-wrapper上去便没有这个问题了。效果如下

demo2

一个圆柱体,因为被转换为gif效果有点差,实际运行会好很多。  这个的实现比较奇葩,在实际场合中几乎没有什么卵用,下面我还是大致说下实现方法吧。

1.  还是和demo1差不多,先定义包裹层,定义preserve-3d,代码大致如下

<div class="wrapper">
<div class="box" id="circles">
</div>
</div>
<style>
.wrapper{
transform-style: preserve-3d;
width: 100px;
height: 100px;
}
.box{
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transform: rotateX(-73.5deg) rotateY(5deg);
}
</style>

2.  在box里插入n个div,每一个div样式相同设置为border-radius:50%和1px的border边框,唯一不同的是它们的translateZ位置相邻相差1,其实就是把1px的边框依次排列起来形成一个圆柱,这样会需要生成很多div,最后我们还是用js去生成我们需要的div数量。

let circles = document.getElementById('circles');
for(let i=0;i<100;i++){
let div = document.createElement('div');
div.style = `transform: translateZ(${i}px)`;
div.className = `circle ${i==0||i==99?'bg':''}`;
circles.appendChild(div);
}

n个1px的div是无缝拼接起来的,为什么还是会有缝隙呢?  大家想象一张纸画了一个圈,从纸的最薄的一面看,是不是看不到圈了,如果再转换一点角度,也许也只能看到一点点,就是这个道理。如此方式我还试了下,写一个球,这里不传gif了,截图看看效果,github上会有代码可以亲自下载下来看看,效果还是挺神奇的

          

demo3

串挂的卡片效果,效果大致如下,像是挂在线上的6张照片,还带一点风吹的效果。  实际也非常简单,还是利用上面demo1的原理旋转卡片,再通过定位把卡片排列,定义一个无限循环的摇摆动画,给每个卡片使用不同的时间,最后绑定点击事件,给元素使用css过渡动画transition。  过渡动画保证元素改变或者还原的时候,都能有效果,所以过渡动画很适合用来做交互。  注意: 进行了3d转换后,要注意元素的可点击区域,用chrome调试工具查看比较准确。

结语:

  css 3d大部分时候使用场景不多,同时也比较消耗设备性能,如果有机会用到,能在网页中给用户体验带来那么一点点惊喜,也是不错的。

  好了,我知道大家需要什么,仓库地址已经准备好 https://github.com/zimv/css3d

  都看到这里了,要不点个赞~

css3D的魅力的更多相关文章

  1. 魅力 .NET:从 Mono、.NET Core 说起

    前段时间,被问了这样一个问题:.NET 应用程序是怎么运行的? 当时大概愣了好久,好像也没说出个所以然,得到的回复是:这是 .NET 程序员最基本的...呵呵! 微软开源,其实不只是对 .NET 本身 ...

  2. 《转》 浅谈C# 多态的魅力(虚方法,抽象,接口实现)

    前言:我们都知道面向对象的三大特性:封装,继承,多态.封装和继承对于初学者而言比较好理解,但要理解多态,尤其是深入理解,初学者往往存在有很多困惑,为什么这样就可以?有时候感觉很不可思议,由此,面向对象 ...

  3. CSS3D效果

    效果如本博客中右边呢个浅色框框,来自webpack首页(IE绕路0_0) github地址:http://wjf444128852.github.io/demo02/css3/css3d/ 思路: 1 ...

  4. 利用CSS3D效果制作简易旋转木马效果

    最近看一下css3d的一些特性,想着也实验学习一下,制作个小demo之类的.就练习了一下.开发一个粗糙的选择木马效果,如图 其实就是找到角度和位置,计算每根柱子的旋转角度摆放到3d空间的置顶位置即可. ...

  5. 依赖注入的威力,.NET Core的魅力:解决MVC视图中的中文被html编码的问题

    有园友在博问中提了这样一个问题 —— .NET Core 中文等非英文文字html编码输出问题,到我们的 ASP.NET Core 项目中一看,也是同样的问题. 比如下面的Razor视图代码: @{ ...

  6. HTML5 模拟现实物理效果,感受 Web 技术魅力

    Ball Pool 是一个基于 HTML5 技术的实验,模拟现实物理效果,让你在 Web 中感受自然物体的运动.玩法介绍:可以随意拖动圆球.点击页面背景.晃动浏览器.双击页面背景或者按住鼠标左键,有不 ...

  7. JS 特殊字符的魅力

    特殊字符的魅力 说在前面—鸭子类型 鸭子类型是动态类型的一种风格,在这种风格中,一个对象有效的语义,不是由继承自特定的类或者实现特定的接口,而是由当前方法和属性的集合决定. “当看到一只鸟走起来像鸭子 ...

  8. 异步编程之Generator(1)——领略魅力

    异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...

  9. (翻译)异步编程之Promise(1):初见魅力

    原文:https://www.promisejs.org/ by Forbes Lindesay 异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2) ...

随机推荐

  1. Junit指定测试执行顺序

    原文链接: Test execution order原文日期: 2012年12月06日翻译日期: 2014年7月2日翻译人员: 铁锚说明: Junit4.11版本及以后才支持,建议升级到最新版本.按照 ...

  2. PS 图像调整算法——黑白

    这个算法是参考自 阿发伯 的博客: http://blog.csdn.net/maozefa 黑白调整 Photoshop CS的图像黑白调整功能,是通过对红.黄.绿.青.蓝和洋红等6种颜色的比例调节 ...

  3. HBase 二级索引与Join

    二级索引与索引Join是Online业务系统要求存储引擎提供的基本特性.RDBMS支持得比较好,NOSQL阵营也在摸索着符合自身特点的最佳解决方案. 这篇文章会以HBase做为对象来探讨如何基于Hba ...

  4. LeetCode(35)-Path Sum

    题目: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up ...

  5. Centos下安装mysql 和挂载硬盘

    一,CentOS下安装Mysql 6.5 1.检测系统是否自带安装mysql # yum list installed | grep mysql 2.删除已经安装的Mysql # yum -y rem ...

  6. ip地址扫描

    自己写的一个ip地址扫描脚本,功能是输入ip地址和掩码,通过ping检测整个网段的ip地址,输出ping的结果. 主要的几个函数如下: 1.ip地址转化为数值,方便计算 ip2num() { ip=$ ...

  7. LambdaToSql 发布 兰姆达转换sql

    文档目录索引 查询.函数.分组.排序.分页 添加 Insert into 编辑 Update set 删除 Delete 生成实体 内置常用工具类库  文档完善中... 事务处理 Join 连接查询 ...

  8. two sum II

    Given an array of integers that is already sorted in ascending order, find two numbers such that the ...

  9. Eclipse两种部署web项目方法

    一).首先使用J2EE的Eclipse的Servers(可以从show view中取出). 1).通过Eclipse建立一个Dynamic Web Project 2).通过Servers视图来创建一 ...

  10. python结巴(jieba)分词

    python结巴(jieba)分词 一.特点 1.支持三种分词模式: (1)精确模式:试图将句子最精确的切开,适合文本分析. (2)全模式:把句子中所有可以成词的词语都扫描出来,速度非常快,但是不能解 ...