做者:imyzfcss
上周三,你的朋友圈是否是这样子的?前端
与此同时,有网友开始分析起了本次活动的计算逻辑,甚至反编译出了全部可能的颜色结果。做为本次活动的核心开发人员,接下来将为你们介绍颜色测试活动的技术细节。react
小剧透:本文将在最后重点介绍你们最想了解的结果计算逻辑git
本次活动的 H5 实际上是一个单页应用(SPA),经过 react-router 进行路由控制,内部包含了 13 个页面,包括首页、问题页、结果页等部分,其中每一个问题都是一个页面。页面之间采用了 react-transition-group 实现淡入淡出的切换效果,问题页之间用 canvas 实现了相似幕布拉动的切换动画。github
答题类页面与通常的 H5 页面的不一样之处在于,用户的操做路径是肯定的,即每一个页面的下一页路由是固定的,因此在 router 层面作了优化,提早预加载了下一个页面,这样作的目的有两点:编程
click
事件触发 video
标签的播放,同时也实现了视频的预加载如图所示,下一页会提早加载,隐藏在当前页面底下。canvas
本次活动页面运用了大量动效来提高用户体验。使用的方式主要分为如下两类:后端
接下来将介绍一下几个比较酷炫的动效。markdown
每一个问题页面之间的切换会有带弹性的幕布拉动效果,采用了 canvas 进行实现,基于贝赛尔曲线进行绘制。react-router
如图所示,用户触发跳转下一页的点击操做后,咱们使用 P1-P5 五个点构成的灰色遮罩闭合区域遮挡当前页面。其中 P4 和 P5 是固定的点,用于肯定右边界。经过不断向左移动 P一、P2 和 P3 的 x 轴坐标,而且修改贝塞尔曲线控制点值,实现拉动效果。这里用到的最核心的 canvas API 是 bezierCurveTo方法。
第 5 个问题中,背景中出现了云层动效,这一部分基于 three.js 实现,采用了 WebGL 进行渲染。这里的云朵采用了着色器材质(ShaderMaterial)载入顶点着色器和片元着色器,贴图进行渲染,而后移动相机位置,模拟穿梭效果。这里每朵云出现的位置都是随机的,不一样人看到的都不同。
第 7 个问题中,进入页面会有按键和物品掉落的效果,这里采用了物理引擎 Matter.js 模拟了自由落体运动和碰撞效果。这里掉落后的位置也是随机的,千人千面,更加真实。
接下来将为你们揭秘测试结果是如何计算出来的。
一、每一个选项都有对应的数个颜色,例如第一题:
二、咱们会记录每一个题目的选择,在最后计算的时候,将对应的颜色进行累加计数。例如第一题选了 A,则会将金
和绿
各加 1。
三、至于单色仍是双色,是根据第 8 题的选择来判断的,若是选了“悲伤”,结果就是单色,选了“浪漫”,结果就是双色。
四、若是是单色,就取单色计数最高的颜色做为结果。
五、若是是双色,就取组合两色之和最高的颜色做为结果,例如,假设橙+金
计数之和是最高的,结果就是橙+金
。固然,这里的组合是有限制的,只有 9 种预设的组合,因此计算的时候将结果限定在了这 9 种以内。
六、若是在排序时遇到了求和结果相同的颜色或组合,会按照策划同窗给出的优先级取结果。例如单色状况下,假设橙
和金
的计数都是 5,会按照橙>金
的优先级,取橙
为结果。
整体流程以下图所示:
举个例子,某位小伙伴的选择是:
[B, C, A, C, C, C, C, A]
复制代码
那么他的颜色计数是
{ '紫': 3, '银': 6, '橙': 3, '金': 3, '绿': 2, '粉': 2, '蓝': 3 }
复制代码
因为最后一题选择了“浪漫”,因此结果是双色,按优先级求和,金+橙
最大(排除不存在的结果组合),因此结果是金+橙
。
本次测试总共有 3^7*2=4374
种选择路径,有 7 种单色结果和 9 种双色结果,总共 16 种结果。
单色结果:
['绿', '橙', '银', '紫', '蓝', '金', '粉']
复制代码
双色结果:
['粉金', '金橙', '粉紫', '金蓝', '金紫', '橙粉', '蓝粉', '金绿', '橙绿']
复制代码
因为结果总数相对可控,而且不须要结合其余后台数据(例如用户我的数据)做计算,因此计算逻辑都在前端完成,而且读取内置的配置展现文案,本次活动并无后端同窗参与开发。
以上结果计算逻辑根据著名性格色彩培训师 Tom Maddron 的著做《最准确的性格色彩测量工具》得出
另外值得一提的是,本次的结果计算逻辑中,并无将颜色和对应的英文进行映射,而是全程使用了中文。例如结果配置文件中,直接使用了中文 key:
export default {
蓝: {
attracted: ['橙粉', '粉金'],
keepAway: ['金', '银'],
......
}
}
复制代码
目前 JS 对 Unicode 的支持已经足够好,甚至支持 Unicode 变量名,在开发完成后,咱们进行了最低版本为安卓 5.0 的兼容性测试,并无发现任何问题,实际上线后也没有遇到这方面的问题。
甚至在 less 代码中使用了中文类名:
.金 {
background: rgb(228, 198, 114);
}
复制代码
据相关资料显示,从 HTML 4.01 开始,就支持了 Unicode 字符做为 class 属性名。固然因为该工程启用了 CSS Module,这里的中文类名会被转换为纯英文的 hash 字符串,不用考虑兼容性问题。
虽然咱们不推荐在编程过程当中大范围使用中文,可是在该场景下,结果的颜色枚举数量较多,使用中文做为每一个颜色的惟一标识,更加直观,能够增长代码可读性,减小将颜色翻译成英文并进行映射的工做量,也是很是值得的作法。
本次活动开发的技术细节就介绍到这里,但愿能给你们带来一些收获。可能有小伙伴还会问,为何相同的回答路径会产生不一样的结果?这里就不细说了,保留一点神秘感,等着你们去挖掘吧!
本文发布自 网易云音乐大前端团队,文章未经受权禁止任何形式的转载。咱们常年招收前端、iOS、Android,若是你准备换工做,又刚好喜欢云音乐,那就加入咱们 grp.music-fe(at)corp.netease.com!