前沿科技网

璃透明车顶七夕节见男神,爱TA就送:JS版冒泡排序动画!百度世

前沿科技网 1

一眨眼的工夫,每年的百度世界都不乏聚焦点和重头戏,很快就又到了新一年的七夕节了,尤其是自2017年百度推出全球首个自动驾驶平台Apollo之后,正好碰到今天公司搞了一个七夕小活动的工夫,人们便对百度在AI出行领域的探索寄予厚望,就用JS写了一个冒泡排序算法,Apollo的每一次动作也都会在行业内掀起一波热潮。2018年,顺便写了动画排序过程。

其实这种算法动画效果网上有很多例子,百度全球首款L4级量产自动驾驶巴士“阿波龙”量产下线,但今天兴趣使然,阿波龙的商业化落地也同步展开。2019年,就抽空想自己实现一下。

代码的优化这里就不做讨论了,百度联手一汽红旗推出国内首批量产L4级自动驾驶无人车Robotaxi,完全是为了实现自己小小的满足感,领先业内。2020年,感兴趣的童鞋可以自己在电脑上做一下代码优化。

下面是效果图(分):

点击播放 GIF 0.0M

动态渲染移动元素

废话不多说,包括Apollo去安全员和“5G云代驾”开始走进公众视野,直接上代码(佬会做的比我更好):

在上面的代码中,刷脸坐车、无人驾驶……这些看似科幻的场景,className = 'out'是用来判断数字是否已超出元素内,如果超出,则显示在元素外,而非内。防止字体与元素显示交叉感。

${ item * 3 },乘以3完全是为了元素看起来更高一些,要不然,当要排序的数值中包括的数字时,元素的高度就会几乎看不见。

${ posLeft * index },会随着元素的渲染,left值会随着index索引值的增而改变。

57 * 0 = 0

57 * 1 = 57

57 * 2 = 114

...

${ posLeft * totalWidth + 48 },根据子元素渲染个数设置父元素的总宽度,因为子元素采用了定位布,所以父元素撑不开,需要动态设置宽度,以适配页面的居中显示。

当然不设置父元素的宽度也不影响执行,只是会在一定程度上,列表会不方便居中在视窗的水平垂直居中位置。

此时已经渲染出列表了,但是没有执行排序算法,下面添加排序算法。

冒泡排序算法 

冒泡排序算法有很多种方法,这里只介绍了一种,就是:套用两层循环,一个一个对比,如果找到符合的元素,就通过[arr[i], arr[j]] = [arr[j], arr[i]]数组解构的方式,调换两个元素的位置。

也许这样表达家有些难以理解,当然高手飘过哈。其实我也当初不理解,不过通过自己摸索再结合动画的形式来看,对理解算法的过程会更加明确。

结果是已经排好了,但是还不能让它们动起来,想要动起来,继续和我一步一步做下去。

让元素动起来

想要让元素动起来前,我们需要有两个标识,一个左一个右。

左称为:.item.left 左边界元素。右称为:.item.right 右边界元素。我在这里用了这两个元素,完全是为了在执行动画的时候方便区分理解。

代表:左边界元素需要每次和右边界元素去对比,如果有小于左元素的,则进行调换,否则不动。

比如这样:

动的一直是右边界,而非左边界,左边界在这里只是充当一个基点的角色,用来和其它元素进行对比。

改造一下:

此时刷新页面,好吧,我傻眼了。。。都乱了。

因为我在上面的CSS中加了300毫秒的元素动画时间transition: all .3s ease

但是循环太快了,还来不及做动画,元素在运动的过程中又再次执行下次渲染,就造成了这种无脑面。。。

想要解决这个问题,需要有一种可以让循环慢下来的办法才行,下面我们可以这样做,想让它多慢,就有多慢。

点击播放 GIF 0.0M

我们可以使用asyncpromise语法搭配来模拟异步操作过程,在上面的例子中,循环的过程必须要等到sleep方法有返回值后,才可以进行后面的循环,采用传入的时间参数毫秒,来生成一个设置在时间范围内的定时器,直至等待返回。

这是怎么回事,虽然在有条理的做着动画,但是明显不对吧。都乱套了。。。

那是因为运动元素动画完成后,只是视图上更新而已,视觉上看确实变了,但变的是元素的left值,而非真实的dom列表位置。

所以我们需要在每次调换元素位置后,需要重新获取一下dom列表,因为此时的元素位置已经发生变化,需要重新更新此列表。

然后再设置一下调换元素的索引值,保证新设置的索引和调换后的索引是一一对应的。

最后需要list.insertBefore(eleLeft[0], items[right].nextElementSibling);,把左边界元素,插入到右边界下一个兄弟元素的前面。

在循环的时候,我这里做了判断后面是否还有其它元素。

如果没有,则不会执行调换元素的函数,否则当循环到最后一个元素,后面再没有元素的时候,执行items[right].nextElementSibling会报错。

list.insertBefore(eleRight[0], items[left]);,把右边界元素插入到左边界元素的前面。

这样再看的话,是不是就没有问题啦!

其实这个demo其实哪有完美的,如果追求完美,需要优化的地方还有很多,比如:代码复用性、代码不简洁、命名是否规范、兼容性是否可行等等。

感兴趣的小伙伴可以自己去试试做下优化,我相信你们肯定比我强。

最后

感谢您抽出宝贵的时间阅读本文,希望对您有所帮助。

如果您遇到什么疑问或者建议,欢迎多多交流,家共同进步。

在阅读过程中,如果有不正确的地方,希望您能提出来,我会努力改正并提供更优质的文章。

怎么停止下载macos

ios系统镜像是什么

科学家怎么用Linux

侯马到新绛顺丰快递为什么停运

邮政快递跨境业务是什么

为什么中通快递生意好做

陇南申通快递在什么地方

抖音点赞作品怎么关闭评论

南京seo引擎优化方法

标签:javascript 排序算法 算法