最近到了赛季末了,输赢也不怎么在乎了,开始关注守望先锋的设计。在我看来,守望先锋的 UI 还是很好看的,不仅设计得十分间接,而且用户体验很友好。昨天注意到了 UI 中的英雄血槽,觉得很奇怪。
奇怪的地方
来看看 DJ 的血槽。以前没怎么注意,昨天仔细数了一下有 8 个小格,嗯?为什么不是 10 个格呢?正常来说我们都希望取整呀。
再来看看别的英雄血槽。
烈空是 6 个小格。要是我来设计显示格数应该是 200 血的对应 10 小格,150 血对应 5 小格。这样才符合我们生活中的取整规则呀。
初步实现
因为最近也在做守望的 UI 组件,所以就想实现这个“血槽”组件。一开始还很容易的,在外面的“血槽” Wrapper 给定一个宽度,然后里面的小格就简单地除一下就好了,再设置 margin-left 搞个空隙,美滋滋。
先看看初步实现的代码
<div class="ow-blood-items" :style="{width: width + 'px'}">
<span class="ow-blood-item"
:style="getItemStyles(item)"
v-for="item in itemNum"
:key="item">
</span>
</div>
Vue 文件里的 JS 实现如下
props: {
total: {
type: Number,
default: 200
},
width: {
type: Number,
default: 200
},
},
computed: {
itemNum() {
return this.total / 25
},
},
methods: {
getItemStyles(item) {
return {
width: this.width / this.itemNum - 2 + 'px',
background: (item >= this.residual / 25) ? this.goneColor : this.residualColor
}
}
}
这里说下我是怎么算每个小格的宽度的,公式如下
写完一看,我感觉不太行。
怎么相隔会一大一小呢?打开开发者工具一看,上面的公式是算对的呀,宽度都是 31.333px。
再看看计算后的样式,直接吐血
明显四舍五入了,虽然只差了 0.002px,但是一看就看出来了,得改呀。
选定宽度
浏览器四舍五入真没办法了,要解决这个问题也很简单,只要不出现小数不就好了?所以我开始想 props 里的默认宽度应该选什么值才能 最大地被整除 呢。
这时候,我回看了一下守望先锋里所有英雄的血槽数,分别是 150, 200, 250, 500, 600, 800, 1000,对应的小格个数应该是(全部除以 25)6, 8, 10, 20, 24, 32, 40。现在的目标就是找到一个数,可以将这些小格数整除就好了。这个问题也太简单了,他们的公倍数太容易找到了——240 嘛。
设置了 240px 后果然好看多了。
因为这里每个小格的宽度都是可以被整除的,也就不会出现四舍五入的情况了。
总结
现在可以回答 “为什么要守望先锋为什么要设置 8 个格而不是 10 个格” 这个问题了,主要的原因就是找最小公倍数的时候,设置 8 个格的最小公倍数在其他方案里最小的。想像一下如果小格数是 3, 17, 23,那他们的最小公倍数就是 ,这样也太大了,很不方便设置总宽度。
联想到之前做的栅格系统,它的设计理念和刚刚推理的类似的,只不过是反过来用,如为什么一定要分 12,24 格呢?这里的原因是因为可以分成 1, 2, 3, 6, 8, 12, 24,而如果最大的为 10 就只能分成 1, 2, 5 了,分割的方案很少。
那如果 5, 10, 20, 25 不是更好么?这样的最小公倍数是 50,多完美呀。嗯。。。,因为英雄血槽数不是我规定的呀,是暴雪规定的呀。
网友评论