By accessing the website and accepting the Cookie Policy, you agree to use the cookies provided by the Site in accordance with to analyze traffic, remember your preferences, and optimize your experience.
如何让svg图标始终对齐到像素
2020-11-26 14:35:06    161    0    0
emengweb

为解决图标1x、2x、3x多种尺寸的问题,大家经常会想到svg或者iconfont图标库。这里我们不比较svg与iconfont两种形式的优缺点,单独对svg图标库进行研究,找到它的不足,并给出弥补这种不足的解决方法。


首先明确一下svg图标的优点,这也是我们舍弃传统的位图,使用svg图的原因所在:


• 图形自由缩放不发虚

• 图形大小可通过CSS自由控制

• 图形颜色可通过CSS自由赋予

• 图形的不同区域可赋予不同颜色

• 同一图形可通过改变大小及颜色用于不同场景



也就是说,只要图形形状没发生变化,那就只需要一个svg图,而不会出现像位图那样即便形状完全一样,只要大小、颜色任意一项发生变化就需要输出一套新图标的情况。举个例子,假设我们已经给开发同学提供了一个加号svg图标,并用于tab bar上,大小为24*24,颜色为#FFFFFF,若有其他情况也需要用到这个加号图标,但大小跟颜色都有所不同时,我们不用再重新切图,只需要将尺寸及色值给到开发同学,开发同学继续调用这个svg图标,并赋予新给出的大小与颜色。这样会大大的降低图标维护成本,提高设计与开发之间的协作便利性。


svg虽说是矢量图形,放大缩小都不会影响图形本身的锐利程度,但受限于屏幕显示机制的原因,如果图形缩放一定倍率后,边缘没有对齐到像素,屏幕显示时还是会模糊、不锐利。其实从本质上说,这并不是svg的原因,因为不管在缩放什么倍率,svg图形本身是不会模糊或者虚化的,只是因为屏幕的显示机制缺陷,才造成了svg图标在一些情况下看起来模糊不清。而我们要做的工作,就是通过控制svg图标的部分特性,来实现对屏幕显示缺陷的规避,进而实现清晰锐利的图标显示效果。


我们发现,svg图标在缩放过程中,有几个关键因素可能会影响到图形的显示效果:图标绘制尺寸L、缩放倍率i、线宽b、绘制时安全区宽度p,如下图

Image title

 

虽然图标绘制尺寸L可以是任意值,但基于绘制及使用的方便性,我们一般设定为整数。而若想缩放后的尺寸依然是整数,则需要保证缩放倍率为整数或部分特定的小数,比如L值为为5的倍数时,部分小数倍率值如n.2、n.4、n.6、n.8也可以满足缩放后为整;L值为偶数时,则小数倍率n.5也可以满足缩放后为整。但绘制尺寸是否为整数,并不影响图标的清晰锐利程度,我们只是为了绘制或使用的方便性人为将其设定成整数。影响图标是否清晰锐利的关键因素是,绘制时线宽是否为整或n.5、绘制时安全区宽度是否为整或n.5、形状边缘是否对齐到像素或0.5个像素、缩放后线宽是否为整或n.5、缩放后安全区是否为整或n.5,同时满足以上所有因素才能保证图标缩放后显示清晰锐利。基于这个原因,当L值为5的倍数的奇数时,线宽只有满足5的整数倍或n.5倍时才能实现n.2、n.4、n.6及n.8的小数倍率下为整数或n.5,显然2.5、5、7.5…的线宽对于图标而言有些太宽了,基本没有可用性。而剩余奇数如9、11、13、17、19等,要么因为太小如9、7、5等不方便绘制,要么因为只支持整数倍率缩放,造成图标尺寸跨度过大,比如L值为11时,图标尺寸序列为11、22、33、44…其中可用的图标就只有22与33,11太小44又太大。所以,我们可以得出一个结论,L值不能为奇数,也就是说L值只能为偶数。


可能有同学会问为什么n.5也能满足,这里补充一下,因为绘制图标时一般使用sketch软件,并将画板设定为x1尺寸,所以当图标线宽或绘制时安全区宽度为n.5时在X2后依然可以得到整数,自然可以保证边缘对齐到像素。但如果是针对web的设计,尽量对齐到整数像素,毕竟高清或retina屏电脑还没有达到手机高清屏的普及程度。


接下来我们通过详细的数据计算、验证,提炼出一些通用规则,方便大家使用。


目的:一套svg图标满足一个产品所有图标需求。

难点:保证放大或缩小后的图标边缘全部对齐到整数或.5个像素。

影响因子:图标绘制尺寸L、缩放倍率i、线宽b、绘制时安全区宽度p。

画板尺寸:375*667、375*812



正文:


图标类型分为线型、面型、线面接合型三种,三种图标影响像素锐度的因子有所不同。

线型影响因子:图标绘制尺寸、缩放倍率、线宽、绘制时安全区宽度;

面型影响因子:图标绘制尺寸、缩放倍率、绘制时安全区宽度;

线面接合型影响因子:图标绘制尺寸、缩放倍率、线宽、绘制时安全区宽度;

其中线型与线面型因为影响因子相同可以归为一类,视为一种。


一、图标绘制尺寸L与缩放倍率i


我们发现,设计时常用图标尺寸一般在12-36px之间。为了方便绘制的时候查看页面效果,我们可以从中选择一个尺寸作为绘制尺寸,然后通过设定缩放倍率来获得其他尺寸的图标。

因为L值只能为偶数,所以可选的L值有12、14、16、18、20、22、24、26、28、30、32、34、36。如果要满足所有缩放后的图标尺寸也是偶数,则需满足图标尺寸是4的倍数,即可选L值为12、16、20、24、28、32、36。


• L=12时

Image title

所以,可用icon尺寸为:12、18、24、30、36


• L=16时

Image title

7所以,可用icon尺寸为:16、24、32


• L=20时

Image title

所以,可用icon尺寸为:20、30


• L=24时

Image title

所以,可用icon尺寸为:12、16、24、36


• L=28时

Image title

所以,可用icon尺寸为:14、28


• L=32时

Image title

所以,可用icon尺寸为:16、32


• L=36时

Image title

所以,可用icon尺寸为:12、18、24、36


综上,L=20、28、32时可用尺寸数太少,不宜使用,我们可选的L值为12、16、24、36。其中L=12或16时,最小值即为绘制值;L=24或36时,L为中间值,分别向上递增向下递减速。


L=12时,可用尺寸为:12、18(x1.5)、24(x2)、30(x2.5)、36(x3);

L=16时,可用尺寸为:16、24(x1.5)、32(x2);

L=24时,可用尺寸为:12(x1/2)、16(x1/1.5)、24、36(x1.5);

L=36时,可用尺寸为:12(x1/3)、18(x1/2)、24(x1/1.5)、36



二、绘制时安全区宽度p


图标绘制尺寸L及缩放倍率i确定后,相当于可用图标尺寸已全部确定。这时我们还需要保证图标绘制时安全区宽度p在做相应缩放后为整数或者n.5,且当p=n.5时,缩放倍率i≠n.5,否则会出现.25或者.75的情况,无法对齐到像素。而我们前文也验证了,若不能采用n.5倍率,可用图标尺寸会比较少且图标尺寸跨度比较大,不能满足现实需求。因此,绘制时安全区宽度p≠n.5,p只能取整数


当L=12或16时,绘制时安全区宽度取1或2时都能满足缩放后对齐到像素或者.5像素;但当p=2时,安全区面积所占比例分别达到了55.56%和43.75%,造成绘制区域过小,不符合要求,所以绘制时安全区宽度p只能取1。


当L=24时,L为中间值;若p=1,则向下计算时,12、16尺寸下绘制时安全区宽度分别为0.5和2/3,无法对齐到像素,不符合要求;若p=2,则向下计算时,16尺寸下绘制时安全区宽度为4/3,无法对齐到像素,不符合要求;若p=3,则向下向上皆可对齐到像素,但是安全区面积所占比例达到了43.75%,造成绘制区域过小,不符合要求。因此L=24时,不能满足设计需求。


当L=36时,L即为最大值;p=1或2时,12、18、24至少同时有2个不能满足对齐到像素;p=3时,12、18、24时安全区宽度分别为1、1.5、2,都能对齐到像素或.5像素。


因此,在满足p值符合要求的前提下,可用绘制尺寸L只能取12、16或36三种,12与16时p值为1,36时p值为3。另外我们也发现,L=12或36时,结果已基本趋同,且L=36的结果被包含于L=12的结果中,所以可选L值可以缩减为两种,分别为12及16。


综上,

L=12时,p=1;

L=16时,p=1。



三、绘制时线宽b


因为缩放倍率i一定会有等于n.5的情况,为保证缩放后线宽都对齐到像素,就要求绘制时线宽b必须像p值一样必须取整数,所以

L=12时,b=1、2、3…

L=16时,b=1、2、3…



四、结论


4.1、若绘制面型图标

L=12时,p=1,i=1.5、2、2.5、3,可选图标大小为:12、18、24、30、36;

L=16时,p=1,i=1.5、2、2.5,可选图标大小为:16、24、32、40;


4.2、若绘制线型图标

L=12时,p=1,b=1、2,i=1.5、2、2.5、3,可选图标大小为:12、18、24、30、36;

L=16时,p=1,b=1、2、3,i=1.5、2、2.5,可选图标大小为:16、24、32、40。



五、延展


是否可以基于2个L值绘制图标?

即我们可以选取12与16,或者16与24两个L值来绘制图标,这种情况下我们只需要保证缩放倍率为整数即可,也可以获得满足设计需要的不同icon尺寸。比如:

L为12与16时,可得图标尺寸12、24、16、32;

L为16与24时,可得16、32、12、24;

但是基于两个L值进行图标绘制时会产生两种尺寸的svg图标,增加维护和使用成本,还容易出现同一图标两种尺寸的情况,造成图标冗余。好处是方便图标绘制,提高图标的绘制便捷性。

L=12与16,或L=16与24时

安全区为1.5时,一则不方便图形绘制,二则16px下安全区为1.5会造成安全区占比过大,故方便起见,在12与16的情况下,安全区都设置为1。

Image title

也就是说如果绘制时L值取两个,安全区宽度p的设定可以固化为基于12与16大小情况下都为1,基于24的则为2;而线宽b的值可以根据绘制风格从上方表格中自由选取。

上一篇: 安装docker和docker compose

下一篇: Manjaro安装系统后的必备操作

161 人读过
文档导航