JavaScript是一门计算机语言,它使用的目的早期就是给HTML网页增加动态功能,这也是我们绝大多数学习它的原因之一,因为学习它直观、简单、浏览器容错性强大等等。可是,随着学习的深入,我们发现想学好JavaScript真的不是一件简单的事情,先不说这眼花缭乱的各种库、插件啊,还有要进军后台的趋势,都让你无所适从。
同时,现在的前端程序员就业也逐步出现了一种怪相,一方面大量的程序员充斥着市场,一方面优秀的企业还是如饥似渴的期待优秀的程序员呢?这中间核心的一个问题就是“编程思维”问题。你对照着自己,你也许会灵活的使用Vue或者React框架,也会使用很多优秀的插件,可是让你使用原生JavaScript和ECMAScript 写一个小案例你都会抓耳挠腮。
今天,我分享的是百度公司早期的一个笔试题,要你使用原生的JavaScript封装一个动画方法,并在页面上实现效果。
我对这个题目提出了一些更高的要求,程序逻辑是:第一步,动画效果是8个小球同时辐射展开(同步动画)或者一一辐射展开(异步动画);第二步,8个小球展辐射到一定位置后开始如彩灯般闪动。编码要求是:1、使用函数封装实现,面向过程编程;2、写入配置参数,根据参数调整动画效果;3、不使用图片,不使用H5画布,使用原生JavaScript编程实现。好了,现在由你打开编辑器自己先思考一下,动笔试试吧?写完以后,敬请阅读以下本人的思路和想法,取长补短,希望能给你一些体会。
首先,我们进行页面布局HTML和CSS,先将需要的东西画到页面上去,好吧,这个不难,就是布局。为了拓展你的知识面,这里我使用了flex布局将画布在屏幕中居中显示,然后中心大球和8个小球都是采取相对于画布进行定位的,现在我们视野中就是一个红色的大球(如下图),还有8个需要运动的球被红色大球覆盖着。你可以自己动手写一下布局,我也进行了非常详细的HTML和CSS注释,当然你也可以将你下载demo的JS文件进行清空,然后跟着我一步一步往下走。
基础效果
现在,我们就要开始思考动画了,这一步有点绕,首先你要理解页面动画其本质是什么:页面动画其实其本质就是让动画目标在极短的时间内运动一小段位移,然后在固定的时间间隔中重复这个动作,最终在我们视觉中是连续的动画效果。
我们不要急,先思考一个小球的运动轨迹,在结合这个球思考另外7个小球的运动轨迹,我们现在就动2号球吧?我们希望2号球运动到右上方向(如下图):
- 2号球运动轨迹
- 2号球运动实现代码
同理,为了让8个小球都实现径向的辐射到一个圆弧上去,我们现在还是忘记动画,我们就先让它进行定位,2号球x轴向右和y轴向上都运动了100px,那么1号球呢?x轴没有,y轴向上动了多少?数学计算一下141.4px,不懂?画图体验一下,这个很简单,好啦,另外6个球依次类推。
-
8 个球运动轨迹
-
8个球运动代码实现
好啦,这个时候,我们开始思考动画,前面就是一个使用JS操作DOM的定位,动画是什么呢?就是我们不希望这8个球一步啪嚓就跑到这个位置了,我们希望的是这8个球慢慢的分步运动到这个位置上来,好吧,我们就分10步,那么一步运动的位移就是现在的十分之一,这个你能明白吧?用图说话如下:
- 出来一点
- 再出来一点
- 接着出来一点
这里需要补充一点的是,悄悄的告诉你,其实这8个球是按照代码在内存中的先后顺序定位移动的,但是计算机计算速度超级快超过你肉眼反应速度,所以你看到的是8个球啪叽就一起移动到你想要的位置了。这个涉及到的是,代码在内存中的执行顺序了,叫什么汇编原理,不累述,你可以去看看这本书,会有帮助的。
好啦,我们将这个定位写成一个函数封装起来,如下图,我这里写的函数执行一次的结果是:根据你选择一个球的索引,然后你就让这个球移动一次位移,如果你想让8个球都运动一次位移,你需要依次传入8个参数然后运行这个函数8次。当然,你也可以暂时不传入参数,运行一次就让8个球都运动一次,我这里主要是为下一步异步动画埋下伏笔。
- 8个球单次动画实现
好了,这里我们开始使用动画的核心,setInterval计时器了,我想补充一句的是setTimeout和setInterval涉及到的东西要想深入理解还是非常不容易的,你若是想进军大牛级别,还是静下心来去看一下,我想你会有收获的。我们进行封装,OK,第一步动画就实现了,见下图代码,具体效果参考页面。
明眼人一看,就问了,你这个timeTag是什么意思啊?你想啊,我们是不是要知道要让动画运动多少次?具体的讲,你每一步让8个小球运动一小段位置,那么你一共要运动多少步啊?到位了就停止了,如何停止?使用clearInterval来清除计时器,看到这里也行大牛就说了,这个你没有考虑用ES6来写,没有防止全局变量被污染,如果封装成一个插件问题如何如何,可是,大牛同志,这里我就是一个简单的页面效果体现,咱们一步步来好吗?
这个时候,8个球就能动画同步运动到指定的位置了也就是我们最初设置的一步到位的位置,关键字同步动画。好了,我们现在再来想想异步动画,就是8个球一步一步的运动如何运动,运动过程效果如下图,你可以在你下载的Demo的JS文件中配置一下参数asyn_tag,
True代表异步false代表同步。
异步动画是如何实现的呢?这里,我们先进行分析,同步动画就是8个球一次动画就是全部外出位移一点,直到结束;异步动画呢?就是1号球先到位,2号球再到位,依次直到8号球到位。为了节省时间,同时也加强你自己的体会,一方面你下载的demo中有详细的注释解释,这里我再将核心的几个地方抽出来说一说,首先看下面的截图:
你会发现代码中有了一个ball_index参数来进行控制,这个参数的意义是什么呢?就是用来依次的控制8个小球,从第1个到第8个,同时每一个球运动到结束位置后,我们又初始化了timeTag这个标签,代表下一个球也要运动这么多步到指定位置。只有8个球都运动完成了以后,代表这一步动画执行完毕了。
俗话说的好,师傅领进门,修行靠个人,我能说的就这么多了,还有一句话是:纸上得来终觉浅,得知此事要躬行。你就对照着下载demo文件,一点点的分析体会,当你自己解决了所有问题的时候,你应该有很大的收获的(大牛除外)。
最后,我想说的是,我为什么要用这个案例demo来作为编程思维的案例来和大家分享。实不相瞒,先后带了这么多学生,我都把这个题目作为测试性质的试题让他们做,到现在为止能够主动思考并且完整实现的学生屈指可数,甚至我把源代码给他,能理解的也不是很多。
我们都说程序员、程序员,但是,我们是不是静下心来想一个问题,什么才是程序员?在我理解,程序员的本质是能将你的编程思维体现出来,而不是简单的会操作几个JavaScript API,会用一下成熟的框架做做业务,更不是会用几个酷炫的插件就代表你会了,编程思维是什么呢?就是从没有到有的一个个人思想的过程并能够体现在你所创作的程序里。如果,你还没有经历到这一步,说明你顶多只能算是一个码农,只有你做到了这一步,你才是一个合格的前端初级工程师,看清楚了,是初级。
我们常常说大牛,大牛的第一步都是这个环节,他们慢慢的在大量的实践工作中寻求自我,然后经过进一步的学习体现自己的编程思维,到后来,很多很多场合,他们都会结合自己的项目写自己的插件,也就是造轮子。是的,我们很多时候听到的建议是,不要随便造轮子,别人的轮子都是经过大量的用户实践过的,肯定更优秀,但是你要理解啊,如果你不理解,你不深思熟虑,你便永远只能停留在浅薄的层次,很难成为一个真正的程序员,只是一个业务代码搬运工。