程序员的知识教程库

网站首页 > 教程分享 正文

CSS3专题(三)—我再说一遍,这不是webgl

henian88 2024-08-16 17:36:12 教程分享 6 ℃ 0 评论

欢迎来到我的CSS3专题系列文章,更多精彩内容持续更新中,欢迎关注 :)

上章节回顾

  1. 我们通过transform的两大特性制作出了立方体,并将整个过程可视化出来,相信大家看了就懂了其中的原理。
  2. 接着我们继续深入推导出了正N面体的计算过程,并制作出了正10面体的几体图形。

本章目标

  1. 基本dom结构的生成
  2. 移动端的适配
  3. css3的transform样式的获取问题以及解决方案
  4. 拖拽的应用

先来看我们今天要实现的效果吧!

很多人看到这种效果第一反应它是通过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的公式一样。

也就是说让图片在每一个手机下看到的效果有两个条件:

  1. 视角,即我能看到多大的范围
  2. 景深,我站在多远的地方去看屏幕

两个条件缺一不可。

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专题的系列文章,更多精彩内容持续更新中……

未完待续。。。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表