113

图片加载时使用 SVG 作为图片 placehold

 6 years ago
source link: https://zhuanlan.zhihu.com/p/31231427?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

图片加载时使用 SVG 作为图片 placehold

简评:使用 SVG 作为占位符不但可以减少数据大小还可以达到不错的显示效果。

不同类型的图片 placehold

v2-5e6415276473e5c4bffe40d70400d542_720w.jpg

对于图片占位符,通常我们会使用以下几种处理方式。

  • 保持图像为空:这样可以保证内容不会出现跳动。
  • 默认占位符:比如说用户想要查看个人资料显示头像内容,如果请求失败或者没有上传过图片,那么通常会使用默认占位符(这种占位符一般会使用 SVG 资源)。
  • 纯色:从图像中获取颜色,并作为背景颜色。图片在过度是时候回显得比较平滑(pinterest 就是使用这种方式)。
  • 模糊的图像:这种方式会获取原图的缩略图并对其进行渲染,等图片加载完成再过度到原图。

以上是我们比较常见的处理图片 placehold 的方法。还有另外一种方式是使用 SVG。

基于 SVG 的 placehold

SVG 是矢量图像的理想选择,但是大部分情况是需要显示位图,我们需要考虑的是如何将位图转换成矢量图,下面提供几种转换方案。

  1. 使用矢量绘制原图的轮廓,具体代码可以参考 demo
动图封面

2. 将原图转换为色块图,具体代码可以参考 demo

这里推荐 Primitive 这个库,这个库可以将位图生成矢量图,我们来看看效果。

上图分别使用不同数量的形状来绘制原图。使用矢量图作为 placehold 有一个很好的优点是小,例如上图 10 个图形的矢量图仅仅只占了 1030 个字节,当通过 SVGO 来传输时,代码还能减少到 640 个字节。

<svg xmlns =“http://www.w3.org/2000/svg”width =“1024”height =“1024”> <path fill =“#817c70”d =“M0 0h1024v1024H0z”/> <g fill- opacity =“。502”> <path fill =“#03020f”d =“M178 994l580 92L402-62”/> <path fill =“#f2e2ba”d =“M638 894L614 6l472 440”/> <path fill =“# fff8be“d =”M-62 854h300L138-62“/> <路径填充=”#76c2d9“d =”M410-62L154 530-62 38“/> <路径填充=”#62b4cf“d =”M1086-2L498- 305148 508“/> <path fill =”#010412“d =”M430-2l196 52-76 356“/> <path fill =”#eb7d3f“d =”M598 594l488-32-308 520“/> <path fill =“#080a18”d =“M198 418l32 304 116-448”/> <path fill =“#3f201d”d =“M1086 1062l-344-52 248-148”/> <path fill =“#ebd29f”d = “M630 658l-60-372 516 320”/> </ g> </ svg>

要达到满意的效我们就必须使用更多的图形来绘制它,如果用 100 个图形来绘制位图,生成的 SVG 大概有 8kB(SVGO 大概 5KB)。随着图形数量的增加,大小也会随之增加。

这是一种折中处理方式,我们可以理解为 Primitive 和高斯模糊的简单叠加,这种方式我可以使用少量的图形块就能达到我们满意的效果。

上图输出的 SVG 大小为 900 字节。

<svg xmlns =“ http://www.w3.org/2000/svg ”viewBox =“0 0 2000 2000”> <filter id =“b”> <feGaussianBlur stdDeviation =“12”/> </ filter> <路径填充=“#817c70”d =“M0 0h2000v2000H0z”/> <g filter =“ url(#b)“transform =”translate(4 4)scale(7.8125)“fill-opacity =”。5“> <ellipse fill =”#000210“rx =”1“ry =”1“transform =”matrix(50.41098 -3.7951 11.14787 148.07886 107 194.6)“/> <ellipse fill =”#eee3bb“rx =”1“ry =”1“transform =”matrix(-56.38179 17.684 -24.48514 -78.06584 205 110.1)“/> <ellipse fill =”#fff4bd “rx =”1“ry =”1“transform =”matrix(35.40604 -5.49219 14.85017 95.73337 16.4 123.6)“/> <ellipse fill =”#79c7db“cx =”21“cy =”39“rx =”65“ ry =“65”/> <ellipse fill =“#0c1320”cx =“117”cy =“38”rx =“34”ry =“47”/> <ellipse fill =“#5cb0cd”rx =“1” ry =“1”transform =“矩阵(-39.46201 77.24476 -54.56092 -27.87353 219.2 7.9)“/> <path fill =”#e57339“d =”M271 159l-123-16 43 128z“/> <ellipse fill =”#47332f“cx =”214“ cy =“237”rx =“242”ry =“19”/> </ g> </ svg>

Mikael Ainalem 分享了一个 codepen,使用双色轮廓作为 placehold,结果效果非常好:

上面这种 SVG 是通过手绘得到的,不过我们也可以使用自动化工具自动生成。

原文:How to use SVG as a Placeholder, and Other Image Loading Techniques

推荐阅读:前端开发备忘录(合集)

欢迎关注:知乎专栏「极光日报」,每天为 Makers 导读三篇优质英文文章。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK