记一次Hackathon经历

本文总浏览量

抱着小伙伴的大腿参加了今年北大、清华、北航、北邮四校MSC联合主办的Hackathon,本来想着做做前端划划水,没想到项目中对前端可视化动画要求挺高,整个不够两天的Hackathon基本一直处于出现问题、解决问题的过程,过程足够难忘,最后也获得了“最佳视觉奖”,happy,写此文章纪录一下与小伙伴们奋斗两天的历程~纪录下开发中遇到的一些问题~


Hackathon之初了解

其实从名字就可以看出来,hack+marathon,简单来说,比赛就是需要参赛队伍在有限的时间内根据主题想出一个创意idea,并且去实现这个idea。
但是其实连两天都不到,周六早上去的时候先是有一个开场,然后周日下午1点就开始demo opening,时间是相当紧迫,不仅考验思维和创意方面,在代码能力和精力体力方面也是一个考验。

走进我们的Hackathon

一图解千言(烤鱼精湛的美工:-D)

核心都在算法方面上,培根大佬引领我们走向成功:-D

算法方面表示我也了解不多,最多刷刷leetcode233,所以本文就不再多阐述算法方面如何实现车辆/人的识别以及实现如何红绿灯调度,重点放在前端方面~

Hackathon之前端开发历程

主要是设计稿还原,然后就是红绿灯调度动画的实现,实现调度可视化,显示倒计时以及各种道路转向、红绿灯切换、堵塞情况展示等等。

录制了一段简单的gif,帧数取得不多,看起来没有现实的流畅


(可以稍微看下整体的动画,红绿灯的调度)

基本实现了所需的功能。

项目部分细节

整体布局方面不成问题,主要时间都花在控制页中那个红绿灯调度动画的实现上,刚开始看到这个需求,由于需要展现堵塞情况,有个圆是动画扩散的,很容易让我想到css3动画的transition或者keyframe去轻松地完成它,并且背景中有些东西是固定不变的,只需将css3动画的dom元素定位到图片的某个位置即可,但是又一想,css3在画线方面能力是不足的,考虑到如果增加需求的话需要更复杂的动画(果然后面真的需要动态的线路),那css3根本做不到,就决定全部使用canvas来实现。

当时在实现时画的各种草图

1. 绘制各种图形

其实canvas动画在画项目中直线和圆方面并不难,都是直接使用canvas里的一些方法直接调用绘制即可。不过在画一些没有那么规则的图形时是需要费工夫去思考的。

roundRect圆角矩形

(也就是红绿灯外面的框),其实就是在绘制的时候使用arcTo()方法绘制弧线;

虚线

canvas是没有专门的方法去实现虚线的,所以其实在画直线虚线时,其实是直接使用for循环对所要画的直线端点之间分割成很多点,实现间隔的moveTo,lineTo实现的,可能你会想问曲线虚线怎么画,其实这个我当时也没有做到,本来是绘制动态曲线采用虚线间隔变化,但是虚线曲线没有实现,所以采用另外一种方式,后面会讲。

曲线

绘制曲线这种平时接触比较少,本项目使用的是bezierCurveTo()方法,绘制三次贝塞尔曲线,说实话挺麻烦的,需要用两个点去控制曲线,所以那两个控制点的位置都得算好。

基本绘制方面也就这些,基本就是封装一些对象可供调用来复用绘制各种图形,因为每个图形基本不会只画一次,需要注意的点在于当你的canvas足够复杂时,更应该关注ctx.save()ctx.restore()ctx.beginPath(),ctx.closePath()这些方法的使用,不然之间互相影响,就将留下祸患,在后面出现bug你找都找不到。

2. 实现动画控制

项目中的动画基本就几个,一个是堵塞情况展示圆的动态扩散,一个是红绿灯的切换,还有一个是红绿灯切换相应路线的动态引导曲线。动画均放在requestAnimationFrame实现,不断擦除重绘。

堵塞情况展示圆的动态扩散

这个实现比较简单,封装一个对象,然后对象里内圆的绘制使用fill(),然后外面扩散圆以内圆半径为基础设一个outRadius,然后每次重绘时这个outRadius增加,增加到一定程度再重新设为初值,就能实现扩散动画。

红绿灯切换相应路线的动态引导曲线

本来设计方面其实是一条条虚线的曲线,但是觉得虚线难以实现,参考了皮蛋学长的文章https://molunerfinn.com/marklinejs/#ds-thread,使用svg绘制贝塞尔曲线,因为svg可以轻松地取到svg长度length的相应的x和y坐标,通过在绘制svg,然后通过定时器来改变(每次增加percent偏移量)我们所需要取到的svg的length*percent,得到相应的x和y坐标,然后将这些坐标给让canvas绘制,就能实现跟随曲线运动(有兴趣可以点击文章,写得挺清楚的~),然后我在曲线上放三个白色小球(与背景色相同),然后设定它们的间隔,循环地在曲线上运动,也就实现了动态引导线的效果(产生线上有间隔的错觉,其实就是几个圆在上面运动)

红绿灯切换

其实这部分动画并不难,就是我根据倒计时然后将灯的颜色变了就行,但是难点在于需要实现比较真实的红绿灯,本项目中,实现的是,先直行->转弯->此路口红灯,每个路口都是这样,然后横向全红灯,则纵向出现绿灯,反之亦然,当时半夜在实现这个,有点乱,培根大大跟我讲了几遍,我后面捋了捋才恍然大悟233,其实就是一个状态机的实现,有兴趣的可以再仔细看看上面那个gif~

最后

基本我做的部分就这些,不过花的时间真挺多的,需求在变化,说实话刚开始要是一来让我看这个东西需要的需求,我肯定是惊呆的,写了1000多行代码(时间紧,很多是垃圾代码),烤鱼算我的时间说我写了17个小时233,开发效率有待提高,不过最后完成了需求也是蛮高兴的,也是不管结果怎样,这个Hackathon的过程是印象深刻的,也算是锻炼了自己吧,最后还出乎意料地拿到了“最佳视觉奖”,真是令人兴奋的,当然这跟队友是分不开的,感谢培根/烤鱼/菜菜/猫猫~

最后附上大功臣之一烤鱼(美工大佬)做的很好玩的图吧~哈哈哈

最后广告hhh,个人公众号,欢迎关注

转载/引用需要经过作者同意。