欢迎来到我的CSS3专题系列文章,更多精彩内容持续更新中,欢迎关注 :)
上章节回顾
- 我们通过transform的两大特性制作出了立方体,并将整个过程可视化出来,相信大家看了就懂了其中的原理。
- 接着我们继续深入推导出了正N面体的计算过程,并制作出了正10面体的几体图形。
本章目标
- 基本dom结构的生成
- 移动端的适配
- css3的transform样式的获取问题以及解决方案
- 拖拽的应用
先来看我们今天要实现的效果吧!
很多人看到这种效果第一反应它是通过webgl做的。很负责的告诉大家,这就是用的css3写出来的。
接下来我们分析一下其中的原理的实现吧!
素材数据的准备
可以看到,我这有20张图片,把它的排在一起,就是一张大图了。每张图片的大小为(129px * 1170px),后面将不再获取图片的大小 ,而是直接硬编码。
生成dom结构
依次将20张图片的地址写到一个数组中,用于后面dom的生成。
默认的dom结构
我们接下来要生成20个div追加到box-C的div中去。并计算每一个面的旋转和平移。
平移公式上章节中我们已经推导过,这里我们直接拿过来用了。
var angle = 360 / this.bgImgs.length; var Z = Math.tan(Math.PI / 180 * (180 - angle) / 2) * 129 / 2;
适配移动端
我的思路是动态设置景深。然后将.box-ui的translateZ值设置为景深的值。这个时候,相当于景深为0了,也是就是图片会贴在屏幕上。像这样的
别忘了,我们里面还有一层,.translateZ的div,我们再将它向里平移一个距离,那么图片就往里面缩小了,达到了我们的预期。
这里面的景深的值,通过我们的视角,定义我们的眼睛能看到的区域范围。我这边直接定义成52度,大家可以自己调整。然后我们之前计算translateZ的公式一样。
也就是说让图片在每一个手机下看到的效果有两个条件:
- 视角,即我能看到多大的范围
- 景深,我站在多远的地方去看屏幕
两个条件缺一不可。
var perspective = Math.tan(Math.PI / 180 * 52) * this.viewH / 2 * 2;样
然后我们能tranalateZ的div向里平移。
util.css(toZ, "translateZ", -4500);
为什么平移4500?从gif图中可以看到,最开始的时候。圆柱是很小的。然后由一个动画再将我们的translateZ拉大,拉大的过程同时旋转。
css3的transform样式的获取问题以及解决方案
我先来看一个示例。
我们通过window.getComputedStyle来获取dom的样式的时候,得到了一个叫matrix3d的东西。了解过css3的童鞋应该知道这是线性代数中的矩阵。没错,我们在transform中做的所有的变换都是可以通过它来实现。
那么问题来了,我如果这样去获取样式,这条路肯定走不通。那怎么办?
解决方案
我们自定义一个方法,这个方法可以去获取样式,也可以设置样式,前提是要获取样式之前,我们必须通过这个方法去设置样式。
也就是说,我们在设置样式的时候,可以对设置的值进行劫持,然后将值挂载对这个dom对象上的transform自定义属性上。然后获取的时候,直接从属性上去获取值即可。
具体实现我这里就不见一一解释了,直接贴完整的代码了。
为了更优雅的设置获取样式,进一步再封装一下
拖拽的应用
从gif图中可以看到,我们可以通过手指拖拽让圆柱绕Y轴进行旋转,并且可以根据速度让拖拽完成后的缓冲动画。
在拖拽之前,先获取当前圆柱的旋转角度,并且圆柱有一个向里变小的效果
this.startRotateY = util.css(this.boxC, 'rotateY'); util.xTween.stop(this['toZ']); util.xTween({ el: this['toZ'], attrs: { translateZ: -1600 }, duration: 100, fx: 'easeIn' })
在touchmove事件当中,我们去计算拖拽过程中的水平方向的差值,然后再根据一定的关系作用在圆柱上。并计算出最后一次拖拽的时间和位移,并计算出对应的速度。
v = s / t;
在touchend事件中,整个的圆柱的Z轴恢复原状。
然后根据在移动过程中的最后一帧的速度,lastSpeed可以计算出手指抬起后的速度。
到这里,代码的介绍基本完成了!
总结:
1)整个圆柱的布局其原理我们在上一小节都有介绍,主要是对各种移动端的适配,我们从中利用了两个条件。缺一不可。
2)封装了自己的针对transform样式的操作方法以及基于Tween的动画函数的封装。
这里是【畅哥聊技术】CSS3专题的系列文章,更多精彩内容持续更新中……
未完待续。。。
本文暂时没有评论,来添加一个吧(●'◡'●)