xml地图|网站地图|网站标签 [设为首页] [加入收藏]

软件资讯

当前位置:美高梅游戏网站 > 软件资讯 > 略知意气风发二SVG坐标种类和改换: transform属性

略知意气风发二SVG坐标种类和改换: transform属性

来源:http://www.gd-chuangmei.com 作者:美高梅游戏网站 时间:2019-11-07 03:14

理解SVG坐标系统和变换: 建立新视窗

2015/09/23 · HTML5 · SVG

原文出处: SaraSoueidan   译文出处:Blueed@Ivan_z3   

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

这是SVG坐标系和变换系列的第三篇也是最后一篇文章。在第一篇中,包括了任何要理解SVG坐标系统基础的需要知道的内容;更具体的是, SVG viewport, viewBox和 preserveAspectRatio属性。在第二篇文章里,你可以了解到任何你需要了解的关于SVG系统变换的内容。

  • 理解SVG坐标系和变换(第一部分)-viewport,viewBox,和preserveAspectRatio
  • 理解SVG坐标系和变换(第二部分)-transform属性
  • 理解SVG坐标系和变换(第三部分)-建立新视窗

通过这篇文章,我假定你已经读了这个系列的第一部分关于SVG viewport, viewBox 和 preserveAspectRatio 属性的内容。在阅读这篇文章之前你不需要读第二篇关于坐标系变换的内容。

理解SVG坐标系统和变换: transform属性

2015/09/23 · HTML5 · SVG

原文出处: SaraSoueidan   译文出处:Blueed@Ivan_z3   

SVG元素可以通过缩放,移动,倾斜和旋转来变换-类似HTML元素使用CSS transform来变换。然而,当涉及到坐标系时这些变换所产生的影响必然有一定差别。在这篇文章中我们讨论SVG的transform属性和CSS属性,包括如何使用,以及你必须知道的关于SVG坐标系变换的知识。

这是我写的SVG坐标系统和变换部分的第二篇。在第一篇中,包括了任何要理解SVG坐标系统基础的需要知道的内容;更具体的是, SVG viewport, viewBox 和 preserveAspectRatio 属性。

  • 理解SVG坐标系和变换(第一部分)-viewport,viewBox,和preserveAspectRatio
  • 理解SVG坐标系和变换(第二部分)-transform属性
  • 理解SVG坐标系和变换(第三部分)-建立新视窗

这一部分我建议你先阅读第一篇,如果没有,确保你在阅读这篇之前已经读了第一篇。

嵌套<svg>元素

在第一部分我们讨论了<svg>元素如何为SVG画布内容建立一个视窗。在SVG绘制过程中的任何一个时刻,你可以创建一个新的视窗其中包含的图形是通过把一个<svg>元素包含在另一个中绘制的。通过建立新视窗,你隐性得建立了一个新视窗坐标系和新用户坐标系。

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

XHTML

<svg xmlns="" xmlns:xlink="; <!-- some SVG content --> <svg> <!-- some inner SVG content --> </svg> <svg>

1
2
3
4
5
6
<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,widthheight属性定义的viewport的边界。任何超过边界的内容会被裁切。

如果你不声明xy属性,它们默认是0。如果你不声明heightwidth属性,<svg>会是父SVG宽度和高度的100%。

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

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

XHTML

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

1
2
3
4
5
<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元素有独立于它父元素的坐标系,它可以有独立的viewBoxpreserveAspectRatio属性,你可以任意修改里面内容的尺寸和位置。

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

为了演示嵌套svg如何发挥作用,让我们来看一些例子。

transform属性值

tranform属性用来对一个元素声明一个或多个变换。它输入一个带有顺序的变换定义列表的<transform-list>值。每个变换定义由空格或逗号隔开。给元素添加变换看起来如下:

有效地SVG变换有:旋转缩放移动, 和倾斜transform属性中使用的变换函数类似于CSS中transform属性使用的CSS变换函数,除了参数不同。

注意下列的函数语法定义只在transform属性中有效。查看section about transforming SVGs with CSS properties获取关于CSS变换属性中使用的语法信息。

例子

试想我们有如下的SVG:图片 1

上述SVG是响应式的。改变屏幕的尺寸会导致整个SVG图形根据需要做出反应。下面的截图展示了拉伸页面的结果,以及SVG如何变得更小。注意SVG的内容如何根据SVG视窗和相互之间保持它们的初始位置。图片 2

使用嵌套SVG,我们将改变这个情况。我们可以对SVG中每个独立的元素根据SVG视窗声明一个位置,所以随着SVG 视窗尺寸的改变(即最外层svg的改变),每个元素独立于其他元素发生改变。

注意,在这个时候,你需要熟悉SVG viewport, viewBox, 和preserveAspectRatio是如何生效的。

我们将要创建一个效果,当屏幕尺寸变化时,蛋壳的上部分移动使得其中的可爱的小鸡显示出来,如下图所示:图片 3

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

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

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

SVG图形的代码如下:

XHTML

<svg version="1.1" xmlns="" xmlns: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>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<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>

这个时候,注意在嵌套svg#upper-shell上声明的viewBox和最外层svg有相同的值(在它被移除之前)。我们用相同的viewBox值我原因就是这样,SVG在大屏幕上保持最初的样子。

所以,这件事是这样的:我们开始一个SVG-在我们的例子中,这是一张里面藏着一个小鸡的带裂纹的蛋。然后,我们创建了另一“层”并把上部分的壳放在里面-这一层通过使用嵌套svg创建。嵌套svg和外层svg的尺寸和viewBox一样。最终,内层SVG的viewBox被设置成不管屏幕尺寸是多少都“固定”在viewport的顶部-这确保了当屏幕尺寸很窄时SVG被拉长,上层的壳被向上举起,因此展示出“隐藏”在里面的小鸡。图片 4

一旦屏幕尺寸拉伸,SVG被拉长,使用preserveAspectratio="xMidYMin meet"把包含上部分壳的viewBox被定位到viewport的顶部。图片 5

点击下面按钮来查看在线SVG。记住改变屏幕尺寸再看SVG变化。

在线案例

嵌套或”分层”SVG使你可以根据改变的视窗定位SVG的一部分,在保持元素宽高比的情况下。所以图片可以在不扭曲内容元素的情况下自适应。

如果我们想要整个鸡蛋剥离显示出小鸡,我们可以单独用一个svg层包含下部分壳,viewBox也相同。确保下部分壳向下移动并固定在视窗的底部中心,我们使用preserveAspectRatio="xMidYMax meet"来定位。代码如下:

XHTML

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <svg id="chick" viewBox="0 0 315 385" preserveAspectRatio="xMidYMid meet">
        <!-- the chicken illustration -->
        <g id="chick">
            <!-- ... -->
        </g>
    </svg>
 
    <svg id="upper-shell" viewBox="0 0 315 385" preserveAspectRatio="xMidYMid meet">
        <!-- path forming the upper shell -->
        <path id="the-upper-shell" fill="url(#gradient)" stroke="#000000" stroke-width="1.5003" d="..."/>
    </svg>
 
    <svg id="lower-shell" viewBox="0 0 315 385" preserveAspectRatio="xMidYMax meet">
        <!-- path forming the lower shell -->
        <path id="the-lower-shell" fill="url(#gradient)" stroke="#000000" stroke-width="1.5003" d="..."/>
    </svg>
</svg>

每个svg层/viewport等于最外层svg宽高的100%。所以我们基本有了三个副本。每层包含一个元素-上部分壳,下部分壳,或小鸡。三层的viewBox是相同的,只有preserveAspectRatio不同。图片 6

当然,在这个例子里,一开始的图形中小鸡隐藏在蛋里,随着屏幕变小才显示出来。然而,你可以做一些不一样的:你可以开始在小屏幕上创建一个图形,然后在大屏幕上显示一些东西;即当svg变宽时才有更多垂直空间来展示元素。

你可以更有创造性,根据不同屏幕尺寸来显示和隐藏元素-使用媒体查询-把新元素通过特定方式定位来达到特定的效果。想象力是无穷的。

同时注意嵌套svg不需要和容器svg有相同的宽高;你可以声明宽高并且限制svg内容,超出边界裁切-这都取决于你想要达到什么效果。

Matrix

你可以使用matrix()函数在SVG元素上添加一个或多个变换。matrix变换语法如下:

matrix(<a> <b> <c> <d> <e> <f>)

1
matrix(<a> <b> <c> <d> <e> <f>)

上述声明通过一个有6个值的变换矩阵声明一个变换。matrix(a,b,c,d,e,f)等同于添加变换matrix[a b c d e f]

如果你不精通数学,最好不要用这个函数。对于那些精通的人,你可以在这里阅读更多关于数学的内容。因此这个函数很少使用-我将忽略来讨论其他变换函数。

使用嵌套SVG使元素流动

在保持宽高比的情况下定位元素,我们可以使用嵌套svg只允许特定元素流动-可以不保持这些特定元素的宽高比。

例如,如果你只想SVG中的一个元素流动,你可以把它包含在一个svg中,并且使用preserveAspectRatio="none"来让这个元素扩展始终撑满这个视窗的宽,并且保持宽高比和像我们在之前例子中做的一样定位其他元素。

XHTML

<svg> <!-- ... --> <svg viewBox=".." preserveAspectRatio="none"> <!-- this content will be fluid --> </svg> <svg viewBox=".." preserveAspectRatio=".."> <!-- content positioned somewhere in the viewport --> </svg> <!-- ... --> </svg>

1
2
3
4
5
6
7
8
9
10
<svg>
    <!-- ... -->
    <svg viewBox=".." preserveAspectRatio="none">
        <!-- this content will be fluid -->
    </svg>
    <svg viewBox=".." preserveAspectRatio="..">
        <!-- content positioned somewhere in the viewport -->
    </svg>
    <!-- ... -->
</svg>

Jake Archibald创建了一个简单实用的嵌套SVG使用案例:一个简单的UI可以包含定位在最外层svg角落的元素,并且保持宽高比,UI的中间部分浮动并且根据svg宽度改变进行拉伸。你可以在这里查看。确保你在开发工具里检查代码来选取和想象不同viewbox和svg使用的效果。

Translation

要移动SVG元素,你可以用translate()函数。translate函数的语法如下:

CSS

translate(<tx> [<ty>])

1
translate(<tx> [<ty>])

translate()函数输入一个或两个值得来声明水平和竖直移动值。tx代表x轴上的translation值;ty代表y轴上的translation值。

ty值是可选的,如果省略,默认值为0txty值可以通过空格或者逗号分隔,它们在函数中不代表任何单位-它们默认等于当前用户坐标系单位。

下面的例子把一个元素向右移动100个用户单位,向下移动300个用户单位。

<circle cx="0" cy="0" r="100" transform="translate(100 300)" />

1
<circle cx="0" cy="0" r="100" transform="translate(100 300)" />

上述代码如果以translate(100, 300)用逗号来分隔值的形式声明一样有效。

其他建立新视窗的方法

svg不是唯一能在SVG中创建新视窗的元素。在下面部分,我们会讨论使用其他SVG元素创建新视窗的方法。

Scaling

你可以通过使用scale()函数变换来向上或者向下缩放来改变SVG元素的尺寸。scale变换的语法是:

CSS

scale(<sx> [<sy>])

1
scale(<sx> [<sy>])

scale()函数输入一个或两个值来声明水平和竖直缩放值。sx代表沿x轴的缩放值,用来水平延长或者拉伸元素;sy代表沿y轴缩放值,用来垂直延长或者缩放元素。

sy值是可选的,如果省略默认值等于sxsxsy可以用空格或者逗号分隔,它们是无单位值。

下面例子把一个元素的尺寸根据最初的尺寸放大两倍:

XHTML

<rect width="150" height="100" transform="scale(2)" x="0" y="0" />

1
<rect width="150" height="100" transform="scale(2)" x="0" y="0" />

下列例子把一个元素缩放到最初宽度的两倍,并且把高度压缩到最初的一半:

XHTML

<rect width="150" height="100" transform="scale(2 0.5)" x="0" y="0" />

1
<rect width="150" height="100" transform="scale(2 0.5)" x="0" y="0" />

上述例子使用逗号分隔的值例如scale(2, .5)仍然有效。

这里需要注意当SVG元素缩放时,整个坐标系被缩放,导致元素在视窗中重新定位,现在不用担心这些,我们会在下一节中讨论细节。

使用<use>ing <symbol>建立一个新的视窗

symbol元素会定义新视窗,无论它什么时候被use元素实例化。

symbol元素的使用可以参考use元素中的xlink:href属性:

XHTML

<svg> <symbol id="my-symbol" viewBox="0 0 300 200"> <!-- contents of the symbol --> <!-- this content is only rendered when `use`d --> </symbol> <use xlink:href="#my-symbol" x="?" y="?" width="?" height="?"> </svg>

1
2
3
4
5
6
7
<svg>
    <symbol id="my-symbol" viewBox="0 0 300 200">
        <!-- contents of the symbol -->
        <!-- this content is only rendered when `use`d -->
    </symbol>
    <use xlink:href="#my-symbol" x="?" y="?" width="?" height="?">
</svg>

上面值中的问号表示这些值也许没有声明-如果xy没有声明,默认值为0,也不需要声明宽高。

看到了吧,当你use一个symbol元素,然后使用开发工具检查DOM,你不会看到use标签中symbol的内容。因为use的内容在shadow tree里被渲染,如果你在开发工具中允许shadow DOM显示你就能看到。

symbol被使用时,它被深度克隆到生成的shadow tree中,例外是symbolsvg替换。这个生成的svg总是有明确的宽高。如果宽高的值在use元素上,这些值会被转换生成svg。如果属性宽和/或高没有声明,生成的svg元素会使用这些值的100%。

因为我们在DOM中使用了svg,并且因为这个svg实际上包含在外层svg中,我们遇到的嵌套svg的状况和我们在之前一章讨论到的并没有多少不一样-嵌套的svg形成了一个新的viewport。嵌套svgviewBox是在symbol元素上声明的viewBox。(symbol元素接受viewBox元素值。更多信息,阅读这篇文章:Structuring, Grouping, and Referencing in SVG – The , , and Elements)

所以我们现在有了一个新的viewport,尺寸和位置可以使用元素(x,ywidthheight)声明,viewBox值可以在symbol元素上声明。symbol的内容随后再这个视窗和viewBox中被渲染和定位。

最后,symbol元素也接收preserveAspectratio属性值,你可以在由use建立的新视窗中定位viewBox。这很清楚,不是吗?你可以像我们在之前的部分里一样控制新创建的嵌套svg

Dirk Weber 也创建了一个使用嵌套SVG和symbol元素来模仿CSS border images的表现。你可以在这里查看文章。

Skew

SVG元素也可以被倾斜,要倾斜一个元素,你可以使用一个或多个倾斜函数skewX 和 skewY

skewX(<skew-angle>) skewY(<skew-angle>)

1
2
skewX(<skew-angle>)
skewY(<skew-angle>)

函数skewX声明一个沿x轴的倾斜;函数skewY声明一个沿y轴的倾斜。

倾斜角度声明是无单位角度的默认是度。

注意倾斜一个元素可能会导致元素在视窗中重新定位。在下一节中有更多细节。

本文由美高梅游戏网站发布于软件资讯,转载请注明出处:略知意气风发二SVG坐标种类和改换: transform属性

关键词:

上一篇:浅谈图片宽度自适应解决方案

下一篇:没有了