作者:imyzf
上周三,你的朋友圈是不是这样子的?
与此同时,有网友开始剖析起了本次流动的计算逻辑,甚至反编译出了所有可能的色彩后果。作为本次流动的外围开发人员,接下来将为大家介绍色彩测试流动的技术细节。
小剧透:本文将在最初重点介绍大家最想理解的后果计算逻辑
整体构造
本次流动的 H5 其实是一个单页利用(SPA),通过 react-router 进行路由管制,外部蕴含了 13 个页面,包含首页、问题页、后果页等局部,其中每个问题都是一个页面。页面之间采纳了 react-transition-group 实现淡入淡出的切换成果,问题页之间用 canvas 实现了相似幕布拉动的切换动画。
答题类页面与个别的 H5 页面的不同之处在于,用户的操作门路是确定的,即每个页面的下一页路由是固定的,所以在 router 层面做了优化,提前预加载了下一个页面,这样做的目标有两点:
- 优化体验,点击立刻呈现下一页,无加载过程
- 很多页面内有视频,须要提前加载 DOM 节点,能力通过
click
事件触发video
标签的播放,同时也实现了视频的预加载
如图所示,下一页会提前加载,暗藏在以后页面底下。
动画成果
本次流动页面使用了大量动效来晋升用户体验。应用的形式次要分为以下两类:
- 预渲染:对于简单的、没有交互逻辑的动画,采纳动效师事后渲染好的视频,以获得最佳的性能和兼容性,例如大部分问题的背景动画。惟一的毛病就是须要加载更大的资源,这一点通过最大水平压缩视频体积和下面提到的预加载得以解决。
- 实时渲染:对于有交互要求的动效,采纳 canvas、WebGL、物理引擎等形式实时渲染,提供更高的可玩性。
接下来将介绍一下几个比拟酷炫的动效。
翻页动效
每个问题页面之间的切换会有带弹性的幕布拉动成果,采纳了 canvas 进行实现,基于贝赛尔曲线进行绘制。
如图所示,用户触发跳转下一页的点击操作后,咱们应用 P1-P5 五个点形成的灰色遮罩闭合区域遮挡以后页面。其中 P4 和 P5 是固定的点,用于确定右边界。通过一直向左挪动 P1、P2 和 P3 的 x 轴坐标,并且批改贝塞尔曲线控制点值,实现拉动成果。这里用到的最外围的 canvas API 是 bezierCurveTo 办法。
云层动效
第 5 个问题中,背景中呈现了云层动效,这一部分基于 three.js 实现,采纳了 WebGL 进行渲染。这里的云朵采纳了着色器材质(ShaderMaterial)载入顶点着色器和片元着色器,贴图进行渲染,而后挪动相机地位,模仿穿梭成果。这里每朵云呈现的地位都是随机的,不同人看到的都不一样。
掉落动效
第 7 个问题中,进入页面会有按键和物品掉落的成果,这里采纳了物理引擎 Matter.js 模仿了自由落体静止和碰撞成果。这里掉落后的地位也是随机的,千人千面,更加实在。
后果计算
接下来将为大家揭秘测试后果是如何计算出来的。
1、每个选项都有对应的数个色彩,例如第一题:
- 选项 A:金、绿
- 选项 B:紫、银、橙
- 选项 C:粉、蓝
2、咱们会记录每个题目的抉择,在最初计算的时候,将对应的色彩进行累加计数。例如第一题选了 A,则会将 金
和 蓝
各加 1。
3、至于单色还是双色,是依据第 8 题的抉择来判断的,如果选了“悲伤”,后果就是单色,选了“浪漫”,后果就是双色。
4、如果是单色,就取单色计数最高的色彩作为后果。
5、如果是双色,就取组合两色之和最高的色彩作为后果,例如,假如 橙 + 金
计数之和是最高的,后果就是 橙 + 金
。当然,这里的组合是有限度的,只有 9 种预设的组合,所以计算的时候将后果限定在了这 9 种之内。
6、如果在排序时遇到了求和后果雷同的色彩或组合,会依照策动同学给出的优先级取后果。例如单色状况下,假如 橙
和 金
的计数都是 5,会依照 橙 > 金
的优先级,取 橙
为后果。
总体流程如下图所示:
举个例子,某位小伙伴的抉择是:
<!– [2,3,1,3,3,3,3,1] {‘ 紫 ’: 3, ‘ 银 ’: 6, ‘ 橙 ’: 3, ‘ 金 ’: 3, ‘ 绿 ’: 2, ‘ 粉 ’: 2, ‘ 蓝 ’: 3} 金橙 –>
[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!