博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SVG <foreignObject>简介与截图等应用 (转载)
阅读量:5264 次
发布时间:2019-06-14

本文共 3012 字,大约阅读时间需要 10 分钟。

一、从SVG文本换行说起

SVG和CSS几乎可以看成是同一个年代出来的东西,但是在Web界面展示这块,CSS长期统领江山,SVG偃旗息鼓,直到这些年,SVG开始乘势而上。

时势造英雄。当年web网页都是以图文展示为主,所以门户,博客这些网站兴起。而SVG擅长的是图形展示,对于文本呈现,只能嘿嘿一下,跟CSS相比那可就弱了几条街。举个最简单的效果,文本换行。在CSS下,当我们一段文字很长的时候,是会自动换到下一行的,但是在SVG中,基本上就是要手动控制换行,对于新闻、博客展示而言简直就是噩梦。于是,CSS火了,SVG萎了。

但,时代是发展的,现代网络带宽有大腿粗,电脑性能比第一次还快,屏幕密度比姚明还高,丰富的富媒体展现和复杂的图形表现需求越来越高,随着flash的日渐衰微,显然,规范标准化的SVG就顺势崛起。

然而需求是千变万化的,当我们使用SVG实现一些视觉表现精湛的效果的时候,免不了会有增加一段描述文字的需求。呵呵,这个时候SVG怕是要傻眼了,SVG的<text>元素应付多行文字实在不擅长,如果SVG中的文字可以如同CSS中的表现一样就好了?

嘿,还真有,那就是SVG的<foreignObject>元素。

二、SVG forginObject元素简介

我们平常使用SVG使用的是SVG的命名空间:

xmlns全称是“XML Namespaces”,指“XML命名空间”。XML是一个比较大的统称,是一种用于标记电子文件使其具有结构性的标记语言。我们平时写的HTML代码是XML,也是种XML,SVG也属于XML。而这些XML类型的渲染规则是有差异的,例如HTML中裸露的<circle>元素是不会表现为圆,而是一个普通的自定义元素。RSS中的XML浏览器会自动进行文章排版渲染等。

所以我们可以看到,指定命名空间可以让浏览器精准解析,举个例子,如下XML代码:

虽然是SVG标签,明摆着应该安装SVG渲染,但是,实际上,由于没有指定xmlns,在浏览器中打开的时候,直接以普通XML文档树渲染了。

可狠狠的点击此SVG文件亲自感受下:

Chrome浏览器下:

Chrome下无命名空间SVG代码表现截图

Firefox浏览器下:

Firefox下无命名空间SVG代码表现截图

一旦我们加上了SVG专属命名空间,如下代码:

则符合预期的SVG图形就渲染出来了。

可狠狠的点击此SVG文件亲自感受下:

结果如下截图:

Chrome有命名空间SVG代码表现截图

这就是命名空间的作用。但这里有必要额外说明下:如果我们的SVG文件是直接内联在XHTML页面中,是可以不指定命名空间的!

好,回到<foreignObject>这里,<foreignObject>元素的作用是可以在其中使用具有其它XML命名空间的XML元素,换句话说借助<foreignObject>标签,我们可以直接在SVG内部嵌入XHTML元素,举个简单的例子:

文字。

可以看到<foreignObject>标签里面有一个设置了xmlns="http://www.w3.org/1999/xhtml"命名空间的<body>标签,此时<body>标签及其子标签都会按照XHTML标准渲染,实现了SVG和XHTML的混合使用。

这种混合特性有什么作用呢?作用很多,其中之一就是轻松实现SVG内的文本自动换行。

三、SVG forginObject元素与文本自动换行

SVG要实现文本换行,往往需要手动阻断,类似下面的代码:

一段需要word wrap
的文字。

需要2<tspan>元素,这一点都不工程。虽然Chrome浏览器可以对<text>标签进行white-space:normal的强制设置,但也只是Chrome浏览器可以。

但是如果使用<foreignObject>元素,则自动换行就是小菜:

一段需要word wrap的文字。

结果Chrome浏览器下效果为:

foreignObject文本换行效果截图

您可以狠狠地点击这里:

四、SVG forginObject元素其它作用-图片生成

除了轻松实现文本换行,SVG <foreignObject>元素还有其他更高级的应用,就是可以将页面上的DOM元素轻松变成图片,原理如下:

  1. 获取对应DOM元素的outerHTML代码;
  2. 放在<foreignObject>元素中;
  3. 图片方式显示我们的SVG图形,例如:
  4. 上一步的图片本质还是SVG,我们可以借助canvas drawImage()方法将图片放在画布上,然后使用canvas.toDataURL()方法转换成pngjpg图片,核心代码:
    var canvas = document.createElement('canvas');var context = canvas.getContext('2d');canvas.drawImage(img, 0, 0);img.src = canvas.toDataURL('image/png');

    上一篇文章“”有详细的canvas绘图和转图片示意,有兴趣可以参考下。

一旦我们可以把DOM元素转换成图片,我们就可以轻轻松松配合JS在前端实现网页截图功能。

想了想,还是做个demo示意下吧,您可以狠狠地点击这里:

点击demo页面右侧小模块任意区域,都可以保存想要内容,例如,外面框框:

点击区域效果截图

结果:

保存效果截图

触发保存,(点击可预览)就是DOM页面的样子。

补充说明:理论上,借助<foreignObject>实现截图效果Firefox也是支持的,但是,上面例子为了简化,直接把页面上的<style>元素以及里面CSS代码一起内联到SVG的<foreignObject>中了,这种用法只有Chrome浏览器支持。因此,上面demo效果仅在Chrome及其内核浏览器下有效。Firefox浏览器要想支持,需要使用特殊方法将所有元素样式style属性内联在元素上。

SVG forginObject兼容性

可以看出SVG的<foreignObject>的特性非常棒!但相比其他SVG元素兼容性要差一些,主要是IE浏览器,好在大头Chrome和Firefox都支持,Safari虽然支持<foreignObject>貌似由于安全限制,转换成图片功能受限。

五、结束语

SVG <foreignObject>元素可以让DOM变图片,发挥我们的创造力,我们可以做的事情就非常非常多,举个例子,各种特效,因为DOM图片化,我们就能使用canvas读取图片完整的像素点信息,通过特点的算法,我们就可以做很多效果,例如常见的高斯模糊。高斯模糊浏览器天然支持,那我们可以实现浏览器默认没有的动感模糊或者镜像模糊;又或者我们可以把DOM元素变成粒子特效(canvas擅长的);又或者实现类似OS X系统的DOCK中软件打开和收起的拉伸扭曲效果等等。

有技术,有创意,还不赶快行动,把你的网页炫起来!

转载于:https://www.cnblogs.com/xy2c/p/7501311.html

你可能感兴趣的文章
Kafka学习笔记
查看>>
Octotree Chrome安装与使用方法
查看>>
Windows 环境下基于 Redis 的 Celery 任务调度模块的实现
查看>>
趣谈Java变量的可见性问题
查看>>
C# 强制关闭当前程序进程(完全Kill掉不留痕迹)
查看>>
ssm框架之将数据库的数据导入导出为excel文件
查看>>
语音识别中的MFCC的提取原理和MATLAB实现
查看>>
验证组件FluentValidation的使用示例
查看>>
0320-学习进度条
查看>>
解决windows系统的oracle数据库不能启动ora-00119和ora-00130的问题
查看>>
ip相关问题解答
查看>>
MetaWeblog API Test
查看>>
反弹SHELL
查看>>
关闭Chrome浏览器的自动更新和升级提示
查看>>
移动、尺寸改变
查看>>
poj2255Tree Recovery【二叉树重构】
查看>>
tcpcopy 流量复制工具
查看>>
vue和react的区别
查看>>
第十一次作业
查看>>
负载均衡策略
查看>>