svg实战 - 图片压缩

svg一方面是“图”,一方面又具备彻底可编程特性,这让它在网页开发中有很大的想象空间。除了常见的图表、icon之类,还有其它一些好玩的地方。本文就讨论一下svg图片压缩上的应用。常见的相关应用场景有:css

  • 高清矢量图。好比logo,icon等几何图形或者由几何图形组合的复杂结构,用svg代码文原本作,会比jpg或者png小不少。好比微软搜索的logo,cn.bing.com/
  • 动画。能用css实现的动画,尽可能用css来作,须要的代码会少不少;但常常有一些css作不到的,如路径动画。若是用gif或者video,资源就大不少了。这时候就适合用svg来作;
  • 使用svg作“裁剪路径”,与jpeg配合实现“镂空”效果。大部分状况下,这种组合会比直接用png小不少。

本文的核心就是第三种方案的应用。html

需求

活动需求,开发一个以下图的功能vue

图1:效果图

每一个用户抽奖后,能够得到不一样的字。弹窗就是一个可复用的组件,把通用的UI抽出来,就是react

图2:可复用UI

这个图片的格式是PNG,大小84K。使用PNG是由于它的四个角须要镂空。咱们的目标就是压缩这个Png图,好比换成jpg,就会减少不少。git

优化第一波:mask-image

上面的png图比较大,换成jpg就小不少了。同尺寸的jpg格式,肉眼几乎看不出差别的jpg图,大小29K,是Png的34%。不过它不支持透明,四个角无法作到镂空的效果。github

图3:jpg版本
如上图,jpg的四个角裁不掉。

这时候就能够使用css属性mask-image了,这个属性用于设置元素上遮罩层的图像。使用遮罩,就能够把不须要的地方裁切掉。可是它额外须要一个遮罩图:web

图4:遮罩图

由于它是纯色的图,虽然是png,但它的size很小,只有3K编程

代码以下:markdown

.dia{
	background: url(./bg.jpg);
	background-size: 100%;
	-webkit-mask-image: url(./mask.png);
	-webkit-mask-size: 100%;
	mask-image: url(./mask.png);
	mask-size: 100%;
}
复制代码

这种解决方案,须要的资源总量为 29+3=32k,是原始方案的 38%demo 源码dom

优化第二波:svg介入

上面的方案已经不错了,但另外一种更“小”的方案:用svg替代遮罩图。svg既然是“图片”,就能够作一些图片的工做。上面的mask图,是一个特别简单的几何结构,能够直接用svg替代。

mask.svg文件内容以下:

<svg viewBox="0 0 566 700">
	<path id="baseShape" fill="red" d="M25 0h516a25,25 0 0,0 25,25v650a25,25 0 0,0 -25,25h-516a25,25 0 0,0 -25,-25v-650a25,25 0 0,0 25,-25Z"></path>
</svg>
复制代码

而后调整上面css文件的内容:

.dia{
	background: url(./bg.jpg);
	background-size: 100%;
	-webkit-mask-image: url(./mask.svg);
	-webkit-mask-size: 100%;
	mask-image: url(./mask.svg);
	mask-size: 100%;
}
复制代码

一通操做后,就不须要mask.png这个图片了,增长了一个100多字节的svg文件,资源又减小了些许。 demo 源码

优化第三波:svg的直接绘制

上面即然已经用了svg,咱就把svg用到极致,连弹窗背景也直接用svg画吧。

看图2,背景图轮廓、边线,均可以使用svg直接画出来。(固然中间一起也是能够用svg作的,只是有些复杂)。

<svg viewBox="0 0 566 700" xmlns="http://www.w3.org/2000/svg">
	<defs>
		<path id="baseShape" d="M25 0h516a25,25 0 0,0 25,25v650a25,25 0 0,0 -25,25h-516a25,25 0 0,0 -25,-25v-650a25,25 0 0,0 25,-25Z"></path>
	</defs>
	<use id="bg" href="#baseShape" fill="#db3e4a" />
	<use id="line" href="#baseShape" stroke="#e09b6c" fill="transparent" stroke-width="1" x="11" y="11" style="transform:scale(0.96,0.97);" />
	<image id="card" x="95" y="78" href="./card.jpg" height="382" width="420"></image>
</svg>
复制代码

由于轮廓和边线形状一致,就把path抽离,作了一个可复用的组件。背景和边线都复用了这个path。而后在上面盖上了最小尺寸的图。

这个方式下,最后的资源总量为 21kdemo 源码

扩展

svg是能够直接在html中用inline的方式嵌入的,这种状况下:

  • 能够和页面共享css
  • 经过js操做dom
  • 能够直接用vue、react的库,方便展现。
相关文章
相关标签/搜索