SVG矢量图视窗viewBox,嵌套HTML综合实例:建立用户自定义相对坐标系统


发布者 ourjs  发布时间 1584406873551
关键字 前端  心得体会 

       SVG绘制的任何一个时刻,你可以通过嵌套svg或者使用例如symbol的元素来建立新的viewport和用户坐标系。在这篇文章中,我们将看一下我们如何这样做,以及这样做如何帮助我们控制SVG元素并让它们变得更加灵活(或流动)。

嵌套svg元素

  在SVG绘制过程中的任何一个时刻,你可以创建一个新的视窗其中包含的图形是通过把一个svg元素包含在另一个中绘制的。通过建立新视窗,你隐性得建立了一个新视窗坐标系和新用户坐标系。

例如,试想有一个svg以及里面的内容:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
<!-- some SVG content -->
<svg>
<!-- some inner SVG content -->
</svg>
</svg> 

第一件需要注意的是内容svg元素不需要声明一个命名空间xmlns因为默认和外层svg的命名空间相同。当然,如果在HTML5文档中外层svg也不需要命名空间。

你可以使用一个嵌套的SVG来把元素组合在一起然后在父SVG中定位它们。现在,你也可以把元素组合在一起并且使用组g来定位-通过把元素包括在一组g元素中。你可以使用transform属性在画布中定位它们。然而,使用svg肯定好过使用g。使用x和y坐标来定位,在许多情况下,比使用变换更加方便。另外,svg元素接受宽高值,g不行。这意味着,svg也许并必要的,因为它可以创建一个新的viewport和坐标系,你可以不需要也不想要。

通过给svg声明宽高值,你把内容限制在通过x,y,width和height属性定义的viewport的边界。任何超过边界的内容会被裁切。

如果你不声明x和y属性,它们默认是0。如果你不声明height和width属性,svg会是父SVG宽度和高度的100%。

另外,声明用户坐标系而不是默认的也会影响内部svg的内容。

给svg内的元素百分比值的声明会根据svg计算,而不是外层svg。例如,下面的代码会导致内层SVG等于400单位,里面的长方形是200个单位:

<svg width="800" height="600"> 
<svg width="50%" ..>
<rect width="50%" ... />
</svg>
</svg> 


  如果最外层svg的宽度为100%(例如,如果它在一个文档中内联或者你想要它可以流动),内层SVG会扩展拉伸来保持宽度为外层SVG的一半-这是强制的。

  嵌套SVG在给SVG画布中的元素增加灵活性和扩展性时尤其有用。我们知道,使用viewBox值和preserveAspectRatio,我们已经可以创建响应式SVG。最外层svg的宽度可以设置成100%来确保它扩展拉伸到它的容器(或页面)扩展或拉伸。然后通过使用viewBox值和 preserveAspectRatio,我们可以保证SVG画布可以自适应viewport中的改变(最外层svg)。我在CSSConf演讲的幻灯片中写到了关于响应式SVG的内容。你可以在这里查看这个技术。

  然而,当我们像这样创建一个响应式SVG,整个画布以及所有绘制在上面的元素都会有反应并且同时改变。但有时候,你只想让图形中的一个元素变为响应式,并且保持其他东西“固定”在一个位置和/或尺寸。这时候嵌套svg就很有用。

  svg元素有独立于它父元素的坐标系,它可以有独立的 viewBox 和 preserveAspectRatio 属性,你可以任意修改里面内容的尺寸和位置。

  所以,要让一个元素更加灵活,我们可以把它包裹在svg元素中,并且给svg一个弹性的宽度来适应最外层SVG的宽度,然后声明preserveAspectRatio=”none”这样的话里面的图形会扩展和拉伸到容器的宽度。注意svg可以多层嵌套,但是为了让事情简洁,我在这篇文章里只嵌套一层深度。

  为了达到这个效果,蛋的上半部分必须和其他部分分离出来单独包含一个自己的svg。这个svg包含框会有一个IDupper-shell。

  然后,我们保证新的svg#upper-shell和外层SVG有一样的高度和宽度。可以通过在svg上声明width=”100%” height=”100%”或者不声明任何高度和宽度来实现。如果内层SVG上没有声明任何宽高,它会自动扩展为外层SVG宽高的100%。

  为了确保上壳被“抬”起或定位在svg#upper-shell顶部的中心,我们将使用适当的preserveAspectRatio值来确保viewBox被定位在视窗的顶部中心-值是xMidYMin。

  SVG图形的代码如下:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> 
<!-- ... -->
<svg viewBox="0 0 315 385" preserveAspectRatio="xMidYMid meet">
<!-- the chicken illustration -->
<g id="chicken">
<!-- ... -->
</g>
<!-- path forming the lower shell -->
<path id="lower-shell" fill="url(#gradient)" stroke="#000000" stroke-width="1.5003" d="..."/>
</svg>

<svg id="upper-shell" viewBox="0 0 315 385" preserveAspectRatio="xMidYMin meet">
<!-- path forming the upper shell -->
<path id="the-upper-shell" fill="url(#gradient)" stroke="#000000" stroke-width="1.5003" d="..."/>
</svg>
</svg> 

 

 

使用iframe建立新视窗

  代表SVG文件的iframe元素建立新坐标系的情况类似于上述解释的image元素的情况。iframe元素也可以有x,y,width和height属性,除了它自身的preserveAspectratio之外。

使用foreignObject建立新视窗

  foreignObject元素建立一个新的viewport来渲染这个元素的内容。

  foreignObject标签允许你把非SVG内容添加到SVG文件中。通常,foreignObject的内容被认为不同于命名空间。例如,你可以把一些HTML放到SVG元素的中间。

  foreignObject接收属性包括x,y,height和width,用来定位对象和调整尺寸,创建用于呈现它里面所引用的内容的范围。

  有需要关于foreignObject元素的要说因为它给内容创建了新的viewport。如果你感兴趣,可以查看MDN entry或者在The Nitty Gritty Blog上查看Christian Schaeffer创建的实际使用。

<svg width="812.595" height="1138.155" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:html="http://www.w3.org/1999/xhtml">
<foreignObject font-style="normal" font-weight="normal" style="vector-effect: non-scaling-stroke;" id="svg_157" font-size="14" height="207" width="341.00001" y="209.84497" x="63.40503">
<div align="left" style="vector-effect: non-scaling-stroke; color: rgb(63, 63, 63);" font-color="black" class="text-wrapper" o-bind="text:invoice" xmlns="http://www.w3.org/1999/xhtml">
<h4>Shanghai electromechanical Co., Ltd.</h4>
<br>
<h4>Introduction</h4>
Shanghai Mechanical was founded in Feb., 2006.We specialize in designing and manufacturing port mechanical spare parts and provide maintenance service.
</div>
</foreignObject>
</svg>

 









 热门文章 - 分享最多
  1. OnceDB:使用Redis全文字符串模糊搜索,多条件查询,创建索引搜索等使用帮助教程
  2. Node.JS中回调嵌套和async/await执行空函数性能效率对比测试
  3. node.js将回调函数嵌套,用promise改造成async/await顺序执行:异常处理和返回多个参数
  4. Node.JS如何按顺序调用async函数,如何判断是否为async函数,在mocha中自动化测试async/await代码
  5. 怎么通过OnceOA免费实现外网访问家庭、企业内网服务器网站、网盘、办公系统
  6. 用旺司OnceOA免费搭建企业多人知识文档管理协作办公软件
  7. 基于Node.JS和Electron编写的集成开发环境 VS Code,成为最受欢迎的IDE
  8. 使用node.js和oAuth2协议集成Github/LinkedIn第三方登录以OnceOA模块源码为例
  9. Redis源码分析,在C语言中将当前时间转化成毫秒微秒整数值
  10. JavaScript在Array数组中按指定位置删除或添加元素对象

 相关阅读
  1. 用网页table thead tfoot元素完美控制页眉页脚显示内容打印的简单方式
  2. jQuery用outterHtml获取相对innerHTML父一级包含其自身的html代码内容
  3. 配置TinyMCE网页文本编辑器不显示html head body等标签信息
  4. css去掉table的td单元格的间距cellspacing,设置隔行显示不同背景颜色
  5. 用JavaScript实现basename获取路径中的文件名
  6. 用纯CSS改变html radio/checkbox默认背景颜色样式
  7. 用css禁用input、checkbox、select等html控件,实现disable效果
  8. 用纯CSS停止冒泡和阻止浏览器默认行为及事件响应,达到禁用(disable)的目的
  9. iPad/iPhone默认input按钮的disabled CSS样式不工作
  10. 我被问得最多的十个JavaScript前端面试问题

  开源的 OurJS
OurJS开源博客已经迁移到 OnceOA 平台。

  关注我们
扫一扫即可关注我们:
OnceJS

OnceOA