css 3D 的魅力

互联网人学习成长社群

第五期Web全栈架构师火爆报名中~

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

demo1

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

1. 我们先用css实现一个长方体,一个长方体有6个边,我们写6个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,,15px);

}

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

.cube2{

width:100%;

height:100%;

background:green;

transform-origin:lefttop;

transform:rotateY(-90deg);

}

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

.cube3{

width:100%;

height:100%;

background:blue;

transform-origin:righttop;

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

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

transform:rotateX(90deg);

}

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

.cube6{

width:100%;

padding-top:100%;

background:black;

top:inherit;

bottom:;

transform-origin:leftbottom;

transform:rotateX(-90deg);

}

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

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

letboxs=document.getElementsByClassName('cube-box');

setInterval(()=>{

for(let iteminboxs){

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,代码大致如下

.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);

}

2. 在box里插入n个div,每一个

letcircles=document.getElementById('circles');

for(leti=;i

letdiv=document.createElement('div');

div.style=`transform:translateZ(${i}px)`;

div.className=`circle${i==||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。

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

文章作者:子慕大诗人

有你想看的精彩

感谢您的阅读,如果你觉得我的公众号还不错,请多帮我推荐给你的朋友,多谢了。

前端大牛爱好者:每天一篇前端技术文章,不定时前端干货发送

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180528B1HP6L00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券