为什么要写这篇文章?主要是为了帮助自己以及和自己一样学习css3的人,从乏味的属性介绍手册中解脱出来,用这门技术真正去做些有意思的东西,以此来加深对概念的理解,进而逐步掌握这门技术。
之前已经写过一篇 《css3 3d动画学习心得》 ,介绍了构建一个css3的3d动画的基本要素:
1、perspective
2、transform-style:preserve-3d
3、transform
其中perspective用于进行3d旋转元素的父元素,transform-style:preserve-3d则用于子元素,它们共同构建了3d动画的环境。有了它们做铺垫,transform属性中的translateZ、rotateX,rotateY才真正有了3d效果。
本文还是主要使用这3个属性,不过这次会做些更有意思的东西。之前的文章,demo效果如下,3张图片围成的圈,鼠标放上去它会转,纯css实现: 这次完成的效果是一个第一视角的小游戏, 按下回车键,角色(一个小正方形)开始在一个道路上奔驰。使用方向键可以控制角色左右上下移动,以躲避迎面而来的不规则镂空障碍物。如果无碰撞通过,会显示红色“Good!”字样,碰撞通过会显示“Crash!”。角色不断奔驰,迎面而来的障碍物随机出现不同的形状:
有没有感觉一下子变得有意思多了?这里仍然是主要使用perspective、transform-style:preserve-3d、transform这3个属性构建动画,不同的是这次我们加入了js,不再是纯样式动画。我们用js控制这些属性值的变化。
怎么做?就是图片拼接,如果你看过我之前写的 《css3 3d动画学习心得》 ,能够拼出3个图片围圈的形状,这里一定也能拼出这个有围栏的路来。
因为不习惯用3d的方式思考元素的位置,开始拼接它们还是有点困难的。我的办法是想象自己手上有几张叠好的扑克,叠好的扑克整齐如同一张。然后这摞牌的牌面面向我悬浮在我面前。我先让第一张牌绕x轴旋转90度,然后它是第一块地板砖;第二张牌也要绕x轴旋转90度是第二块地板砖,不过第二张牌还要往前或者向后做一定位移,不然2块地板砖就重叠了。然后是第3张...这里绕x轴当然是rotateX,前移和后移则是translateZ。这样逐步铺好了“地板砖”然后再拼“围栏”。最终一个有围栏的“道路”就产生了:
虽然游戏中,是角色在奔驰,但实际上我们是让道路移动的,然后让人产生角色在移动的错觉。
因为游戏可能设定“道路”很长,但是我们不可能用前面介绍的方法一点点去拼接全部“道路”,同时“道路”又比较容易构建一个无缝循环的动态系统,“道路”发生位移,身处其中的角色即使不动也会产生相反的位移错觉。所以这里不必让角色真的移动。
这是小游戏的核心,不过说白了就是一个不间断的无缝滚动。作为前端,大家一定做过很多无缝滚动的效果来展示图文信息,不过多数都是2d的,而这次是3d的无缝滚动,x,y的2维坐标系构成2维图形,加一个维度,z轴就是3维了,这里要突出3维效果,就是要不间断改变z轴的值。具体到css3的属性,就是translateZ属性了。z轴不间断的位移元素,位移到一定的位置,把队首元素放到队尾,再继续位移,和2d的不间断滚动原理相同。
效果:
既然我们能让静止的道路不断向我们延伸,在道路上增加障碍物自然也行,“道路”和“障碍物”都是被我们不断进行z轴位移的dom元素,它们的不同概念是我们赋予的,本质区别其实就是位置不同:
经过上述4个步骤游戏大体就完成了。
你可能会说,你说的这么概括怎么能让不懂的人了解这个游戏的实现呢?首先,我要承认这里我省掉了大量细节。但是教读者完成一个css3的小游戏并不是本文的目的,省掉那些细节是为了突出本文的重点: 只需要熟练掌握perspective、transform-style:preserve-3d、transform这3个属性,你就可以做出有意思的东西来 ,这种有意思的东西是css3独有的,如果使用传统的css2,要达到相同效果,成本要高很多。因为这个游戏的场景本质上是3d的,使用2d的手段达到相同效果,是模拟的间接达到效果,需要制作者有较好的透视基础,但是css3是直接的,它直接在3d的维度操作一个元素。
我想,对于一个css3的初学者,仅仅知道这一点,就是对学习动力的一个巨大增强,至于其他的细节,有了浓厚的兴趣作支撑,你总能解决它。
最后提供本游戏的demo链点( 注 :未做兼容,预览请在chrome下进行): http://htmldog.github.io/run/
在实际的demo中,通过w,a,s,d键还可以控制整体视角,回看前面的游戏gif效果图,读者应该也能感感受到整体视角在后期发生了变化。这里主要是通过改变perspective-origin的值来实现的。不过perspective-origin在此游戏中并非必须,增加主要是为了更绚丽的视觉。
demo代码比较糙,基本是想一点写一点随性来的,看个效果就好。主要还是感受下css3d动画有意思的地方:更低的编码成本,更绚的视觉效果。酝酿出更浓的兴趣,然后更好的学习和掌握这门技术