查看原文
其他

babby 2018-05-29

前言

我们今天再来分享分享svg相关的,在公司的某个项目中有部分用到这个技术,包括之前做的公司用户在全国的分布情况,其中地图就是利用到svg。


正文从这开始~


如果你还未曾见过乔•哈里森响应式图标http://responsiveicons.co.uk/的技术,那你很可能会像我第一次看到它时一样,对它印象深刻。在这篇文章中,我想探究一下,我们该如何使用SVG来做一些更有趣的事情,而不只是作为“可伸缩矢量图形”来对PNG位图进行替换。事实上,我们知道SVG作为一个独立的模块,不光能够通过封装CSS实现自定义视图,也能够通过封装javascript实现交互逻辑。


那现在,让我们深入了解一下该技术。


响应式SVG:流浪汉的方法

哈里森的响应式图标的网站实现方式很简单。它使用了一个众所周知的前端技术, image sprites。如果你不了解该技术,那我来介绍一下。 image sprites是一门以节省带宽、提升网络性能为目的的以往只用于光栅图像的技术。它的实现逻辑是让很多小图像组合成一个文件,这样客户端就只需要从服务器下载一张图片。


你可以使用CSS来移动图片,使其显示在需要让它显示的地方,这种方式相比于下载每个图片,将会更加节约网络流量。


除了将PNG替换成SVG,哈里森对于SVG的处理方式与image sprites并没有什么不同。他将所有图标合并为一个文件,如下图所示:


所有的图标组合在单个SVG文件,该文件之后会被设置为一个容器的背景,在该容器中,一个图标会显示出来:


上面所举的例子虽然很简单,但也存在一些问题。那就是该解决方案不够简便。实际上,想要使用这种方式,两部分必不可少:外联的CSSSVGSprite


响应式SVG:穷人的方法

因为CSS可以在SVG内部定义,那我们来修改一下上面的例子,使用更简便的方法来封装图标。首先,删除sprite里图标的所有的空间相关属性。当然,这也给我们留下了一堆堆积杂乱的图标: http://codepen.io/pukhalski/embed/inxym?height=343&theme-id=8287&slug-hash=inxym&default-tab=result&user=pukhalski


然后,按照图标重新排列所有的形状和组,添加.icon类到每个组,还有编号,以便能够获取任意一个我们所需要的(例如,#home_icon_0,#home_icon_1到#home_icon_8):



现在,我们准备添加媒体查询,这样我们就可以选择我们想要显示的SVG文件中的图标了。为此,我们可以用<defs>标签把CSS直接写在<svg>标签中。


ps:完整代码可以通过阅读原文了解

这样,相同的图标就可以适应视图的大小了,现在,CSS规则,媒体查询和SVG形状都封装在SVG文件中。缩放你的浏览器,来看看它在下面的例子中是如何运行的: http://codepen.io/pukhalski/embed/uxIKB?height=349&theme-id=8287&slug-hash=uxIKB&default-tab=result&user=pukhalski


响应式SVG:持枪男人的方法

上面的例子虽然看起来比第一个稍微好一点,但问题依然存在:

1)响应式SVG能否以一种更好的方式实现?

2)相比隐藏和显示部分文件,使用自定义元素与响应式的方式对图标进行布局是否更可行?


细查响应式网页设计所用的内容编排和布局结构调整的方法会发现,我们仍然可以优化我们的方法。我们可以使用响应式设计,图形重构和变换,以使图标适用不同的视图的大小。


首先,在我们的SVG sprite中重绘最大且最详细的房子的图标,拆分所有路径,并把形状加入到元素的形状中。这种方式更易读,而且移植性更强:

http://codepen.io/pukhalski/embed/Azqyn?height=325&theme-id=8287&slug-hash=Azqyn&default-tab=result&user=pukhalski


重绘的图标虽然看起来和sprite里最大的图标一样,但它包含更多的形状,而这仅多占用了一丢丢空间。神奇之处在于,我们把媒体查询和变换添加到新的变种中,通过改变图标本身的形状可以得到和SVG sprite相同的结果。


ps:完整代码可以通过阅读原文了解

只要我们使用上面提到的方法,图标就会表现的像乔哈里森的SVG sprite一样,而且它自己会包含全部的逻辑。在新窗口中打开下面的例子,调整其大小以查看所有图标变种。

http://codepen.io/pukhalski/embed/hFLDG?height=336&theme-id=8287&slug-hash=hFLDG&default-tab=result&user=pukhalski


使图标适应父容器的尺寸

还有一件事,就是让图标能够对父容器的宽高变化实现响应。为了做到这一点,我尝试加载一个包裹在div中使用img标签的SVG文件。但似乎SVG文件所有的媒体查询都失效了。


我的第二次尝试是加载了一个由div包裹的object元素中的图标。这种方式下,所有的媒体查询都起作用了:让对象能够充满整个父容器。(记得将SVG元素的宽度和高度的设置为100%或者完全删除。)


下面是其他将媒体查询和变换嵌入SVG的方式,你可以使用SVG作为块级元素的背景图像。内联的SVG也可以,但媒体查询将会对视图变化产生响应。


下面的例子演示了图标是如何适配不同大小容器的。根据SVG将要渲染的尺寸大小,SVG中将通过媒体查询来实现对图标的绘制。这里是八个嵌入在一个相同的SVG文件中但尺寸不同的例子。

http://codepen.io/pukhalski/embed/hszLl?height=485&theme-id=8287&slug-hash=hszLl&default-tab=result&user=pukhalski


添加JavaScript到SVG

其他的好消息! SVG文件不仅可以封装CSS,也可以封装JavaScript。本质上,我们在使用任何一种旧标记的语言时,都可以把一个被引用SVG文件当做一个独立的模块。


当JavaScript 内联到在元素中时,还能够完美地执行。多奇妙的世界,是吧?


浏览器支持

能够完美支持在SVG文件中实现媒体查询和变换的浏览器版本有:

1)互联网浏览器9+

2)火狐17+

3)谷歌17+

4)欧朋15+

5)Safari浏览器6.0+

6)Safari浏览器iOS 6.0或更高版本 Android浏览器 Android 3.0+

该技术有可能在某些旧版本的浏览器中能够实现,但一些转换效果,如缩放,可能还不支持。


结论

响应式SVG图标可以应用在很多方面,如下所示:

1)响应式广告;

2)标志;

3)应用程序的图标。


后语

前一段时间有一本图书《svg精髓》刚刚面世,想了解svg更详细的内容,更系统化去了解svg,可以来本看看。可以在微信后台回复 svg 了解此书。


关于本文

作者:@babbystar

原文链接:http://www.w3ctech.com/topic/1555


长按图片识别图中二维码


    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存