16

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

 4 years ago
source link: http://ourjs.com/detail/k7v6xzv31eaq
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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>

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK