SVGforeignObject简介与截图(html转图⽚)等应⽤
⼀、从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的命名空间:
<svg xmlns="/2000/svg"></svg>
xmlns全称是“XML Namespaces”,指“XML命名空间”。XML是⼀个⽐较⼤的统称,是⼀种⽤于标记电⼦⽂件使其具有结构性的标记语⾔。我们平时写的HTML代码是XML,也是种XML,SVG也属于XML。⽽这些XML类型的渲染规则是有差异的,例如HTML中裸露
的<circle>元素是不会表现为圆,⽽是⼀个普通的⾃定义元素。RSS中的XML浏览器会⾃动进⾏⽂章排版渲染等。
所以我们可以看到,指定命名空间可以让浏览器精准解析,举个例⼦,如下XML代码:
<svg width="12" height="12" viewBox="0 0 12 12"><path d="M10.263 10.874L6 6.61l-4.264 4.264a.431.431 0 0 1-.61-.61L5.39 6.001 1.128
1.736a.431.431 0 0 1 .61-.61L6 5.391l4.264-4.263a.431.431 0 0 1 .61.61L6.61 6l4.262 4.264a.43.43 0 1 1-.61.609z" stroke="#979797" fill="#999"/>
</svg>
虽然是SVG标签,明摆着应该安装SVG渲染,但是,实际上,由于没有指定xmlns,在浏览器中打开的时候,直接以普通XML⽂档树渲染了。
可狠狠的点击此SVG⽂件亲⾃感受下:
Chrome浏览器下:
Firefox浏览器下:
⼀旦我们加上了SVG专属命名空间,如下代码:
<svg width="12" height="12" viewBox="0 0 12 12" xmlns="/2000/svg"><path d="M10.263 10.874L6 6.61l-4.264 4.264a.431.431 0 0 1-.61-.61L5.39 6.001 1.128 1.736a.431.431 0 0 1 .61-.61L6 5.391l4.264-4.263a.431.431 0 0 1 .61.61L6.61 6l4.262 4.264a.43.43 0 1 1-.61.609z" stroke="#979797" fill="#999"/></svg>
则符合预期的SVG图形就渲染出来了。
可狠狠的点击此SVG⽂件亲⾃感受下:
结果如下截图:
这就是命名空间的作⽤。但这⾥有必要额外说明下:如果我们的SVG⽂件是直接内联在XHTML页⾯中,是可以不指定命名空间的!
好,回到<foreignObject>这⾥,<foreignObject>元素的作⽤是可以在其中使⽤具有其它XML命名空间的XML元素,换句话说借
助<foreignObject>标签,我们可以直接在SVG内部嵌⼊XHTML元素,举个简单的例⼦:
<svg xmlns="/2000/svg">
<foreignObject width="120" height="50">
<body xmlns="/1999/xhtml">
<p>⽂字。</p>
</body>
</foreignObject>
</svg>
可以看到<foreignObject>标签⾥⾯有⼀个设置了xmlns="/1999/xhtml"命名空间的<body>标签,此时<body>标签及其⼦标签都会按照XHTML标准渲染,实现了SVG和XHTML的混合使⽤。
这种混合特性有什么作⽤呢?作⽤很多,其中之⼀就是轻松实现SVG内的⽂本⾃动换⾏。
三、SVG forginObject元素与⽂本⾃动换⾏
SVG要实现⽂本换⾏,往往需要⼿动阻断,类似下⾯的代码:
<svg xmlns="/2000/svg">
<text font-size="12">
<tspan x="0" y="10">⼀段需要word wrap</tspan>
<tspan x="0" y="26">的⽂字。</tspan>
</text>
</svg>
需要2个<tspan>元素,这⼀点都不⼯程。虽然Chrome浏览器可以对<text>标签进⾏white-space:normal的强制设置,但也只是Chrome浏览器可以。
但是如果使⽤<foreignObject>元素,则⾃动换⾏就是⼩菜:
<svg xmlns="/2000/svg">
<foreignObject width="120" height="50">
<body xmlns="/1999/xhtml">
<p >⼀段需要word wrap的⽂字。</p>
</body>
</foreignObject>
</svg>
结果Chrome浏览器下效果为:
您可以狠狠地点击这⾥:
四、SVG forginObject元素其它作⽤-图⽚⽣成
除了轻松实现⽂本换⾏,SVG <foreignObject>元素还有其他更⾼级的应⽤,就是可以将页⾯上的DOM元素轻松变成图⽚,原理如下:
1. 获取对应DOM元素的outerHTML代码;
2. 放在<foreignObject>元素中;
3. 图⽚⽅式显⽰我们的SVG图形,例如:
<img width="300" height="150" src='data:image/svg+xml;charset=utf-8,<svg xmlns="/2000/svg"><foreignObject width="120"
height="50"><body xmlns="/1999/xhtml"><p >⼀段需要word wrap的⽂字。</p></body> </foreignObject></svg>'>
4. 上⼀步的图⽚本质还是SVG,我们可以借助canvas drawImage()⽅法将图⽚放在画布上,然后使⽤DataURL()⽅法转换
成png或jpg图⽚,核⼼代码:
var canvas = ateElement('canvas');
var context = Context('2d');
canvas.drawImage(img, 0, 0);
img.src = DataURL('image/png');
上⼀篇⽂章“”有详细的canvas绘图和转图⽚⽰意,有兴趣可以参考下。
⼀旦我们可以把DOM元素转换成图⽚,我们就可以轻轻松松配合JS在前端实现⽹页截图功能。
svg图形想了想,还是做个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中软件打开和收起的拉伸扭曲效果等等。
有技术,有创意,还不赶快⾏动,把你的⽹页炫起来!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论