CSS3的 3D立方体旋转动画

今次就来个大家用3D属性最爱炫技的场景,旋转的立方体,有人声称这种动画简直代表了CSS3的癫疯,不不,是巅峰。做完之后只想吼一声,你说的没差!由平面动效进阶到立体动效真是……立方体六个面要做足足六种不同的设置,所以那些玩八面体,十二面体,……等等的,大写的“服”字。其他人做的立方体3D动画,看了几个,差不多都是<div>实现的,嗯哼,我用<SVG>来做一下吧,至于原因嘛,后面揭晓,当然,如果失败的话,此句请自动忽略。

1. 先立起来

不可避免的,要先来个基础图形。错错错,是基础物体,反正就是个需要立体的东西,随便怎么称呼。基本上有两种方法可以实现,先来一种直观好理解的。

看上面这张图,我把立方体的六个面平铺开,右上角的那个是后面。此时,假设立方体是在视线正前方,好了,面有了,现在需要把它们折叠起来,像折纸盒一样,组成一个立方体。先看一下dom结构。

<div class="stage">
<div class="content">
<svg   id="cubic1" xmlns="http://www.w3.org/2000/svg" >
<rect   height="200" width="200" />
</svg>
<svg   id="cubic2" xmlns="http://www.w3.org/2000/svg" >
<rect   height="200" width="200" />
</svg>
<svg   id="cubic3" xmlns="http://www.w3.org/2000/svg" >
<rect   height="200" width="200" />
</svg>
<svg   id="cubic4" xmlns="http://www.w3.org/2000/svg" >
<rect   height="200" width="200" />
</svg>
<svg   id="cubic5" xmlns="http://www.w3.org/2000/svg" >
<rect   height="200" width="200" />
</svg>
<svg   id="cubic6" xmlns="http://www.w3.org/2000/svg" >
<rect   height="200" width="200" />
</svg>
</div>
</div>

非常简单,我定义了两个容器,一个是舞台stage,一个是包裹立方体的content,content里是6个SVG,每个SVG只有一个简单的矩形rect。我的目的是让content在stage里进行3D动效变化。

CSS定义如下:

.stage {width: 800px; height: 600px; background:#e5fffb; perspective:1000px;}
.content{transform-style: preserve-3d}
#cubic1{fill:#f29a76}
#cubic2{fill:#61BFBE}
#cubic3{fill:#BADDD6}
#cubic4{fill:#FFB5BA}
#cubic5{fill:#866667}
#cubic6{fill:#E25D6E}
SVG {position: absolute;top:200px; left:300px;width:200px; height:300px}

6个SVG都是宽200,高200,虽然里面的矩形<rect>也都是相同尺寸,却没有进行统一的定义,是因为想尝试后期给每个SVG定义不同的动画属性。容器的摆放关系如下图:

目前,通过position属性的设置,六个面是重叠在一起的,因此,在折叠之前,先把每个方块挪到自己对应的位置。移动的CSS属性就很简单了。根据图示,cubic1,也就是正对着我们的面,不需要移动,其他增加transform: translate相应的属性设置,定义如下:

#cubic2{fill:#61BFBE;transform: translateZ(-200px)} /*后面远离屏幕200px移动*/
#cubic3{fill:#BADDD6;transform: translateY(-200px)} /*上面垂直向上200px*/
#cubic4{fill:#FFB5BA;transform: translateX(200px)} /*右面水平向右200px*/
#cubic5{fill:#866667;transform: translateY(200px)} /*下面垂直向下200px*/
#cubic6{fill:#E25D6E;transform: translateX(-200px)} /*左面水平向左200px*/

移动之后的效果是下面这种(闲着也是闲着,我把移动过程做了动效):


好了,现在各在其位,下面要各司其职,进行折叠了。


这里有一点要说明,就是移动过之后,关于坐标系的变化,拿其中一个面cubic4为例来说,当发生水平向右移动200px后,此时坐标系也会发生变化同样的位移,因此在做折叠(旋转)90度的3D变形时,旋转的基轴虽然在原坐标系是右边的垂直轴,但对于移动后的坐标系,变成了左边的垂直轴,因此,对应的变形原点的设置为transform-origin: center left。举一反五,其他的几个就不一一细说了,直接放上增加3D旋转后的CSS3属性(cubic2仅仅发生了Z轴方向的位移,没有旋转动画,所以无需设置)。

#cubic3{fill:#BADDD6;transform: translateY(-200px) rotateX(90deg) ;transform-origin: bottom center;}
#cubic4{fill:#FFB5BA;transform: translateX(200px) rotateY(90deg);transform-origin: center left;}
#cubic5{fill:#866667;transform: translateY(200px)  rotateX(-90deg);transform-origin:top center;}
#cubic6{fill:#E25D6E;transform: translateX(-200px) rotateY(-90deg);transform-origin: center right;}

完成之后,效果是下面这种:

(这特么是不是在逗我,就一个平面非说是个立方体……!)别急,就知道你会这样说,所以我用动效展示一下这个过程:

此处应有动画!!应有动画!!应有动画!!(我忘记录屏了,天雷滚滚)

这下信了吧?其实这货就是个立方体,货真价实,只不过我们没有给最外层的容器(也就是3D变形的舞台)设置透视点位置,默认是屏幕正前方,所以你只看到了一面。来来来,我把透明度调整一下,再改改透视原点的位置,效果是下面这种。哟,立方体出来了。


上面说过,关于立方体的组成有两个方法,我们第一种是用了先平移后折叠,那第二种就是先折叠后平移了。说到这里,可能会不解,无所谓了管它呢,有甚区别,我自己做的过程中感觉差别还蛮大,下面这种方法要求对空间的理解能力更强,但代码却优化了很多,省去一干transform-origion的设置。在上面的组合立方体的过程中,我们把面向自己的那一面作为了二维的基面,其他方形都是基于此进行了变换,也就是说最后组成的立方体从三维角度来说,是向背离屏幕的Z轴进行延伸的(代表背面的cubic2进行了Z轴负向的位移)。
这次,我们假定组成后的立方体的中心就是坐标系的原点,首先,我仍然是用绝对定位法把所有的组成面都固定到容器统一的位置,只进行位移的正面和背面不用管,先来进行3D方向的旋转。依旧用动画表示吧。这里为了能看到效果,我把舞台stage的透视原点定义为偏右下方perspective-origin:80% 80%


动画效果有了,只是由于透视点的方向问题,结果似乎少了两个面,再把透视点改成偏左上perspective-origin:20% 20%看一下:


完成第一步的旋转,下面就是要进行全体位移了,那么重点来了。
以左面cubic6为例,如下图所示:


在进行3D旋转变形后,坐标系也相应的做了旋转变形,从视觉角度来看,做完选择变形后的cubic6要进行向左移动100px的水平位移,但由于坐标系变形的缘故,对于其本身旋转后的坐标系而言,此时水平方向变成了Z轴,因此水平位移也就变成了translateZ。 把第二种方法形成立方体的动画看一下:

方法二之所以更优化,是因为关于六个cubic的定义简化如下:

#cubic1{fill:#f29a76;transform:translateZ(100px);}
#cubic2{fill:#61BFBE;transform:translateZ(-100px);}
#cubic3{fill:#BADDD6;transform:rotateX(90deg) translateZ(-100px)}
#cubic4{fill:#FFB5BA;transform:rotateY(-90deg) translateZ(100px)}
#cubic5{fill:#866667;transform:rotateX(-90deg)translateZ(-100px)}
#cubic6{fill:#E25D6E;transform: rotateY(90deg) translateZ(100px)}

2. 再转起来

基础部件已经搭起来了,下面就让这个立方体动起来。说立方体不好理解,但我们在做的时候把它放到了一个content<div>容器里,因此,让这个容器做一些变换就可以了。至于用哪种方法得到的立方体,此处随意,我用了二。先来个最简单的绕Y轴旋转的,CSS部分如下:

@keyframes content{
to{transform: rotateY(360deg)translateZ(20px)}
}
.content{transform-style: preserve-3d; animation:content 2s linear both infinite; }

效果:

写到这里暂时停一下,剩下的放到另一篇吧,我要好好想一下关于3D能做哪些炸裂的效果。等更新。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • 把立方体的盒子搭出来之后,因为怕文章又臭又长(嗯,就是没有想好玩什么效果,偏不告诉你)关于动效没有做更多的处理,只...
    泱泱悲秋阅读 1,980评论 1 8
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,793评论 25 707
  • 1、属性选择器:id选择器 # 通过id 来选择类名选择器 . 通过类名来选择属性选择器 ...
    Yuann阅读 1,621评论 0 7
  • 以前觉得23岁就是最好的年龄了。青春,张扬,可以肆意挥洒自己的精力。熬一个通宵后睡一觉立马精神焕发。尤其生了哥哥以...
    景一夫阅读 374评论 0 0
  • 一 宝贝最近几天,张开眼睛,看到什么,都要指着问:“这是啥?”“这是啥?”告诉她了还是接着问“这是啥?”,全家人都...
    棒棒糖读写笔记阅读 758评论 3 3