在这篇文章中:

本文介绍了CSS来实现3D效果,并且有详细代码和解释。建议大家只字不差的阅读。本文的作者是「子慕大诗人」

前言:

最近玩了玩用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: 0;
top: 0;
}

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: 0;
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

CSS 3D的魅力的更多相关文章

  1. CSS 3D 的魅力

    作者 | 子慕大诗人 来源 | www.cnblogs.com/1wen/p/9064011.html   前言:   最近玩了玩用css来构建3D效果,写了几个demo,所以博客总结一下.  在阅读 ...

  2. Intro to CSS 3D transforms

    原文地址:Intro to CSS 3D transforms,本文只是翻译了其中的一部分,省去了作者写文章的原因浏览器兼容部分(已经过时) Perspective 元素需要设置需要设置perspec ...

  3. Codrops 优秀教程:CSS 3D Transforms 实现书本效果

    这个使用  CSS 3D Transforms 实现创意书本效果的来自 Codrops 网站.你可以看到两种类型的书设计:精装书和平装书.这两个效果都可以很容易地使用 CSS 修改.赶紧体验一下吧. ...

  4. 从css 3d说到空间坐标轴

    有一次我们说到掷骰子那个游戏,当时是用了一个steps属性+雪碧图来制作帧动画,这当然颇为不错,但其实一开始我想的不是这样的,我想的是用真的3d和动画去做,这个方案涉及到不少空间的知识,今天来给大伙好 ...

  5. 探究 CSS 混合模式\滤镜导致 CSS 3D 失效问题

    今天在写一个小的 CSS Demo,一个关于 3d 球的旋转动画,关于 CSS 3D,少不了会使用下面这几个属性: { transform-style: preserve-3d; perspectiv ...

  6. CSS 3D transforms

    https://www.creativebloq.com/css3/20-stunning-examples-css-3d-transforms-11112759 https://github.com ...

  7. EF Core使用SQL调用返回其他类型的查询 ASP.NET Core 2.0 使用NLog实现日志记录 CSS 3D transforms cSharp:use Activator.CreateInstance with an Interface? SqlHelper DBHelper C# Thread.Abort方法真的让线程停止了吗? 注意!你的Thread.Abort方法真

    EF Core使用SQL调用返回其他类型的查询   假设你想要 SQL 本身编写,而不使用 LINQ. 需要运行 SQL 查询中返回实体对象之外的内容. 在 EF Core 中,执行该操作的另一种方法 ...

  8. 10个超漂亮的CSS 3D特效

    10个超漂亮的CSS 3D特效 一.总结 一句话总结: 后面有空得好好练一练,也可以作为录课素材 二.10个超漂亮的CSS 3D特效 转自或参考:10个超漂亮的CSS 3D特效https://blog ...

  9. css 3D动画

    一.今天让我们来学习一下css 3D吧! 1.首先我们要学习好css3 3d一定要有一定的立体感! 2.再来那就聊聊原理吧! 3.css3 3d 顾名思义是由两个2d名片组成的 但不是让你建立连个2d ...

随机推荐

  1. python uwsgi 配置

    启动:uwsgi --ini xxx.ini 重启:uwsgi --reload xxx.pid 停止:uwsgi --stop xxx.pid ini 文件 [uwsgi] chdir = /vag ...

  2. Ranger-AdminServer安装Version2.0.0

    Ranger-AdminServer安装, 对应的Ranger版本2.0.0. 1.安装规划 RangerAdmin安装依赖如下组件: mysql solr IP/机器名 安装软件 运行进程 dap2 ...

  3. centos6.5搭建LAMP

    实验前准备    (1)service iptables stop   #关闭防火墙       service iptables status   #查看防火墙是否已经关闭       iptabl ...

  4. 内联模板、X-Template

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <script s ...

  5. mysql数据库忘记root密码怎么办?

    mysql数据库忘记root密码怎么破解和修改 1.停止数据库的运行 [root@localhost ~]# /etc/init.d/mysqld stop 或者[root@localhost ~]# ...

  6. 【原创】美团二面:聊聊你对 Kafka Consumer 的架构设计

    在上一篇中我们详细聊了关于 Kafka Producer 内部的底层原理设计思想和细节, 本篇我们主要来聊聊 Kafka Consumer 即消费者的内部底层原理设计思想. 1.Consumer之总体 ...

  7. 使用 SourceGenerator 简化 Options 绑定

    目录 摘要 Options 绑定 使用 SourceGenerator 简化 如何 Debug SourceGenerator 如何 Format 生成的代码 使用方法 SourceCode & ...

  8. 洛谷 CF196A 题解

    题目传送门 题目描述: 读入字符串,求该串的最大字典序子序列. 我的思路: 循环判断只要当前字符比后面所有的字符的字典序大,就把这个字符存到另一个字符串中,最后和输入的字符串循环比较如果该字符和输入时 ...

  9. 解决nRF Connect for PC无法连接网络的问题(非FQ)

    各位小伙伴是不是也遇到过国内不能正常使用nRF Connect的问题,现在教大家一个十分有效的办法. 1.找到nrf connect的脚本配置文件"apps.json",默认在&q ...

  10. 浅谈MySQL同步到ElasticSearch的几种方式及其优缺点

    同步双写 优点:业务逻辑简单. 缺点: 硬编码,有需要写入mysql的地方都需要添加写入ES的代码: 业务强耦合: 存在双写失败丢数据风险: 性能较差:本来mysql的性能不是很高,再加一个ES,系统 ...