所有 SVG 内容都绘制在 SVG 视口 内。每个 SVG 视口定义了一个绘图区域,该区域具有尺寸(宽度、高度)和原点,以抽象的 用户单位 为度量。
请注意,SVG 视口一词不同于 CSS 中使用的 “视口” 术语。
初始视口是一个顶层 SVG 视口,它在包含环境使用的坐标系(例如网页浏览器中的 CSS 像素)与 用户单位 之间建立映射。关于建立初始视口的更详细说明,请参见 初始视口。
SVG 视口只能由元素建立。有关哪些元素会生成视口的信息,请参见 建立新的 SVG 视口。
每个 SVG 视口都会生成一个 视口坐标系 和一个 用户坐标系,最初它们是相同的。在视口元素上提供 ‘viewBox’ 会按照《‘viewBox’属性》所述,将用户坐标系相对于视口坐标系进行变换。视口的子元素可以进一步修改 用户坐标系,例如通过指定 transform 属性。
SVG 视口可以嵌套。百分比单位的解析以最近的祖先 SVG 视口的宽度和高度为参考。因此,嵌套 SVG 视口提供了一种重新定义百分比单位含义并为相对特定矩形区域“适配”图形提供新参考矩形的机会。
SVG 视口的宽度、高度以及原点由生成该视口的 SVG 文档片段与该片段的父级(无论是真实的还是隐式的)之间的协商过程决定。有关此协商过程的描述,请参阅 建立新的 SVG 视口。
默认情况下,嵌套 SVG 视口的 视口坐标系 等同于父元素的本地坐标系,并在 SVG 视口元素的原点处进行平移。然而,在 SVG 视口元素上设置的 transform 属性会相对于父元素的用户坐标系修改 视口坐标系。
抽象地说,所有 SVG 视口都嵌入在 画布 中——一个在所有相关维度上都是无限大的绘图区域。
此过程将 viewBox 属性的 min-x、min-y、width、height 值、定义该属性的元素的位置与尺寸,以及该元素上的 preserveAspectRatio 属性值,转换为平移和缩放,从而作用于该元素所包含的内容。
viewBox 属性的 min-x、min-y、width、height 值。preserveAspectRatio 的对齐值;如果未定义 preserveAspectRatio,则取默认值 'xMidYMid'。preserveAspectRatio 的 meetOrSlice 值;如果未定义 preserveAspectRatio,或该值中缺少 meetOrSlice,则取默认值 'meet'。'none' 且 meetOrSlice 为 'meet',则把较大的 scale-x 与 scale-y 中的较小者设为相等。'none' 且 meetOrSlice 为 'slice',则把较小的 scale-x 与 scale-y 中的较大者设为相等。'xMid',则向 translate-x 加上 (e-width - vb-width * scale-x) / 2。'xMax',则向 translate-x 加上 (e-width - vb-width * scale-x)。'yMid',则向 translate-y 加上 (e-height - vb-height * scale-y) / 2。'yMax',则向 translate-y 加上 (e-height - vb-height * scale-y)。对该元素所包含的内容应用的变换为 translate(translate-x, translate-y) scale(scale-x, scale-y)。
初始视口的宽度必须是 width 表示属性在 最外层 svg 元素 上的取值,除非满足以下条件:
在上述条件下,视口的宽度必须通过这些定位属性来确定。
同样,如果在引用元素或 最外层 svg 元素 上指定了足以确定视口高度的 定位属性,则这些定位属性必须决定视口的高度;否则,初始视口的高度必须是 height 表示属性在 最外层 svg 元素 上的取值。
如果 width 或 height 表示属性在 最外层 svg 元素 上使用了 用户单位(即未提供单位标识符),则该值被视为等同于相同数值的 “px” 单位(参见 Units)。
在下面的示例中,SVG 图形以内联方式嵌入在使用 CSS 布局规则的父 XML 文档中。由于未在 最外层 svg 元素 上提供 CSS 定位属性,width="100px" 与 height="200px" 属性决定了初始视口的大小。
<?xml version="1.0" standalone="yes"?>
<parent xmlns="http://some.url">
<!-- SVG graphic -->
<svg xmlns='https://w3org.cn/2000/svg'
width="100px" height="200px">
<path d="M100,100 Q200,400,300,100"/>
<!-- rest of SVG graphic would go here -->
</svg>
</parent>
对于 最外层 svg 元素,SVG 用户代理必须确定一个初始的 视口坐标系 与一个初始的 用户坐标系,使两者相同。两个坐标系的原点都必须位于 SVG 视口的原点,并且初始坐标系中的一个单位必须等同于 SVG 视口中的一个 CSS 2.1 px([CSS2] 第 4.3.2 节)。在独立 SVG 文档以及嵌入(通过引用或内联)在其父文档且父文档布局由 CSS 决定的 SVG 文档片段中,初始视口坐标系(因此也包括初始用户坐标系)必须把原点设在视口的左上角,正 x 轴指向右方,正 y 轴指向下方,文本以“正立”方向渲染,即罗马字母和亚洲文字的全尺寸表意字符的顶部边缘向上、右侧边缘向右。
如果 SVG 实现是支持使用 CSS 2.1 兼容的 px 单位进行文档样式化的用户代理的一部分,则 SVG 用户代理应将其 px 单位在现实世界中的初始大小设为与其他样式操作使用的值相同;否则,如果用户代理能够从其环境中确定 px 单位的大小,则应使用该值;否则,它应自行选择一个合适的 px 单位大小。无论何种情况,px 的大小必须符合 CSS 2.1 中的规定([CSS2] 第 4.3.2 节)。
下面的 Example InitialCoords 显示了初始坐标系统的原点位于左上角,x 轴指向右侧,y 轴指向下方。初始用户坐标系统的一个用户单位等于父(隐式或显式)用户代理的“像素”。
<?xml version="1.0" standalone="no"?>
<svg width="300px" height="100px" version="1.1"
xmlns="https://w3org.cn/2000/svg">
<desc>Example InitialCoords - SVG's initial coordinate system</desc>
<g fill="none" stroke="black" stroke-width="3" >
<line x1="0" y1="1.5" x2="300" y2="1.5" />
<line x1="1.5" y1="0" x2="1.5" y2="100" />
</g>
<g fill="red" stroke="none" >
<rect x="0" y="0" width="3" height="3" />
<rect x="297" y="0" width="3" height="3" />
<rect x="0" y="97" width="3" height="3" />
</g>
<g font-size="14" font-family="Verdana" >
<text x="10" y="20">(0,0)</text>
<text x="240" y="20">(300,0)</text>
<text x="10" y="90">(0,100)</text>
</g>
</svg>
Example InitialCoords
用户代理必须支持 transform 属性及其表现属性,具体定义见 [css-transforms-1]。
| 名称 | 值 | 初始值 | 可动画 |
|---|---|---|---|
| viewBox | [<min-x>,? <min-y>,? <width>,? <height>] | 如同未指定一样。 | 是 |
<min-x>, <min-y>, <width>, <height> = <number>
在 ‘svg’ 元素上使用的 transform 有些特殊,因为它受 ‘viewBox’ 属性的影响。该变换应当被视为如果 ‘svg’ 拥有一个父元素且该父元素设置了同样的变换时的效果。
决议:transform 属性在概念上作用于 ‘svg’ 元素的外部,表现属性与样式属性在视觉结果上没有区别
‘viewBox’ 属性配合 ‘preserveAspectRatio’ 属性,可实现将 SVG 视口拉伸以适配特定容器元素的能力。
‘viewBox’ 属性的值是由四个数字 <min-x>、<min-y>、<width> 与 <height> 组成的列表,数字之间以空白或逗号分隔,用来指定应映射到由该元素建立的 SVG 视口边界的用户空间矩形,同时考虑 ‘preserveAspectRatio’ 属性的影响。存在 ‘viewBox’ 时,会如《计算 SVG 视口的等价变换》所述,对视口坐标系进行一次变换。
若 <width> 或 <height> 为负值,则为错误并使 ‘viewBox’ 属性失效。若值为零,则禁用该元素的渲染。
ViewBox 示例 展示了在 最外层 svg 元素 上使用 ‘viewBox’ 属性,以指定 SVG 内容应拉伸以适配 SVG 视口边界的用法。
<?xml version="1.0" standalone="no"?>
<svg width="300px" height="200px"
viewBox="0 0 1500 1000" preserveAspectRatio="none"
xmlns="https://w3org.cn/2000/svg">
<desc>Example ViewBox - uses the viewBox
attribute to automatically create an initial user coordinate
system which causes the graphic to scale to fit into the
SVG viewport no matter what size the SVG viewport is.</desc>
<!-- This rectangle goes from (0,0) to (1500,1000) in user coordinate system.
Because of the viewBox attribute above,
the rectangle will end up filling the entire area
reserved for the SVG content. -->
<rect x="0" y="0" width="1500" height="1000"
fill="yellow" stroke="blue" stroke-width="12" />
<!-- A large, red triangle -->
<path fill="red" d="M 750,100 L 250,900 L 1250,900 z"/>
<!-- A text string that spans most of the SVG viewport -->
<text x="100" y="600" font-size="200" font-family="Verdana" >
Stretch to fit
</text>
</svg>
| 渲染为 SVG 视口示例 width=300px, height=200px |
渲染为 SVG 视口示例 width=150px, height=200px |
|
|---|---|---|
![]() |
![]() |
使用 ‘viewBox’ 属性的效果是,用户代理会自动提供适当的变换矩阵,将用户坐标系中指定的矩形映射到指定区域(通常是 SVG 视口)的边界。若要实现左图所示的效果,且 SVG 视口尺寸为 300 × 200 像素,用户代理需要自动插入一个将 X 与 Y 同时缩放至 0.2 的变换。该效果等同于拥有一个 300 px × 200 px 的 SVG 视口,并在文档中加入如下的补充变换:
<?xml version="1.0" standalone="no"?>
<svg width="300px" height="200px"
xmlns="https://w3org.cn/2000/svg">
<g transform="scale(0.2)">
<!-- Rest of document goes here -->
</g>
</svg>
要实现右图所示的效果,且 SVG 视口尺寸为 150 × 200 像素,用户代理需要自动插入一个将 X 缩放至 0.1、Y 缩放至 0.2 的变换。该效果等同于拥有一个 150 px × 200 px 的 SVG 视口,并在文档中加入如下的补充变换:
<?xml version="1.0" standalone="no"?>
<svg width="150px" height="200px"
xmlns="https://w3org.cn/2000/svg">
<g transform="scale(0.1 0.2)">
<!-- Rest of document goes here -->
</g>
</svg>
注意,在某些情况下,用户代理除了需要提供 scale 变换外,还必须提供 translate 变换。例如,在 最外层 svg 元素 上,如果 ‘viewBox’ 属性为 <min-x> 或 <min-y> 指定了非零值,则必须加入相应的 translate。
如果同时对同一元素应用了 transform(或 ‘patternTransform’)以及 ‘viewBox’,则会建立两个新的坐标系。transform 为该元素建立第一个新坐标系;‘viewBox’ 为该元素的所有后代建立第二个坐标系。第一个坐标系在后面乘以第二个坐标系。
与 transform 属性不同,由 ‘viewBox’ 自动创建的变换不会影响该元素的 ‘x’、‘y’、‘width’ 与 ‘height’ 属性(在 ‘marker’ 元素的情况下,还包括 ‘markerWidth’ 与 ‘markerHeight’)。因此,在上例中展示的带有 width 与 height 表示属性和 ‘viewBox’ 的 ‘svg’ 元素中,width 与 height 表示的是 ‘viewBox’ 变换**之前**的坐标系中的数值。另一方面,和 transform 属性一样,它会为所有其他属性以及后代元素建立一个新的坐标系。
| 名称 | 值 | 初始值 | 可动画 |
|---|---|---|---|
| preserveAspectRatio | <align> <meetOrSlice>? | xMidYMid meet | 是 |
<align> =
none
| xMinYMin | xMidYMin | xMaxYMin
| xMinYMid | xMidYMid | xMaxYMid
| xMinYMax | xMidYMax | xMaxYMax
<meetOrSlice> = meet | slice
指示是否强制统一缩放。适用于所有建立新 SVG 视口的元素(参见 建立 SVG 视口的元素),以及 ‘image’、‘marker’、‘pattern’ 与 ‘view’ 元素。
在某些情况下(通常是使用 ‘viewBox’ 时),希望图形以非统一的方式拉伸,以填满整个 SVG 视口;而在其他情况下,则希望使用统一缩放以保持图形的宽高比。
对于建立新 SVG 视口的元素(参见 建立 SVG 视口的元素),以及 ‘marker’、‘pattern’ 与 ‘view’ 元素,只有当同一元素上同时提供了 ‘viewBox’ 时,‘preserveAspectRatio’ 才生效;如果未提供 ‘viewBox’,则忽略 ‘preserveAspectRatio’。
对于 ‘image’ 元素,‘preserveAspectRatio’ 指示引用的图像应如何相对于参考矩形进行适配,以及是否应在当前用户坐标系中保持图像的宽高比。
<align> 参数指示是否强制统一缩放;若强制,则在 <align> 与 SVG 视口宽高比不匹配时决定对齐方式。<align> 必须是以下字符串之一:
<meetOrSlice> 参数是可选的。如果提供,它与 <align> 值之间由一个或多个空格隔开,且必须是以下字符串之一
meet(默认值) - 缩放图形使得
此时,如果图形的宽高比与 SVG 视口不匹配,部分 SVG 视口会超出 ‘viewBox’ 的边界(即 ‘viewBox’ 绘制区域小于 SVG 视口)。
slice - 缩放图形使得
此时,如果 ‘viewBox’ 的宽高比与 SVG 视口不匹配,部分 ‘viewBox’ 会超出 SVG 视口的边界(即 ‘viewBox’ 绘制的区域大于 SVG 视口)。
PreserveAspectRatio 示例 展示了 ‘preserveAspectRatio’ 的各种取值。该示例通过在 最外层 svg 元素 中嵌入多个 ‘svg’ 子元素(参见 建立新的 SVG 视口)来创建若干新的 SVG 视口。
<svg width="450px" height="300px" xmlns="https://w3org.cn/2000/svg">
<desc>Example PreserveAspectRatio - illustrates preserveAspectRatio attribute</desc>
<style type="text/css">
text { font-size: 9; }
rect { fill: none; stroke: blue; }
</style>
<defs>
<g id="smile">
<rect x='.5' y='.5' width='29' height='39' style="fill:black;stroke:red"/>
<circle cx='15' cy='20' r='10' fill='yellow'/>
<circle cx='12' cy='17' r='1.5' fill='black'/>
<circle cx='17' cy='17' r='1.5' fill='black'/>
<path d='M 10 24 A 8 8 0 0 0 20 24' stroke='black' stroke-width='2'/>
</g>
</defs>
<rect x="1" y="1" width="448" height="298"/>
<text x="10" y="30">SVG to fit</text>
<g transform="translate(20,40)"><use href="#smile" /></g>
<text x="10" y="110">Viewport 1</text>
<g transform="translate(10,120)"><rect x='.5' y='.5' width='49' height='29'/></g>
<text x="10" y="180">Viewport 2</text>
<g transform="translate(20,190)"><rect x='.5' y='.5' width='29' height='59'/></g>
<g id="meet-group-1" transform="translate(100, 60)">
<text x="0" y="-30">--------------- meet ---------------</text>
<g>
<text y="-10">xMin*</text>
<rect x='.5' y='.5' width='49' height='29'/>
<svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 30 40" width="50" height="30">
<use href="#smile" />
</svg>
</g>
<g transform="translate(70,0)">
<text y="-10">xMid*</text>
<rect x='.5' y='.5' width='49' height='29'/>
<svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 30 40" width="50" height="30">
<use href="#smile" />
</svg>
</g>
<g transform="translate(0,70)">
<text y="-10">xMax*</text>
<rect x='.5' y='.5' width='49' height='29'/>
<svg preserveAspectRatio="xMaxYMax meet" viewBox="0 0 30 40" width="50" height="30">
<use href="#smile" />
</svg>
</g>
</g>
<g id="meet-group-2" transform="translate(250, 60)">
<text x="0" y="-30">---------- meet ----------</text>
<g>
<text y="-10">*YMin</text>
<rect x='.5' y='.5' width='29' height='59'/>
<svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 30 40" width="30" height="60">
<use href="#smile" />
</svg>
</g>
<g transform="translate(50, 0)">
<text y="-10">*YMid</text>
<rect x='.5' y='.5' width='29' height='59'/>
<svg preserveAspectRatio="xMidYMid meet" viewBox="0 0 30 40" width="30" height="60">
<use href="#smile" />
</svg>
</g>
<g transform="translate(100, 0)">
<text y="-10">*YMax</text>
<rect x='.5' y='.5' width='29' height='59'/>
<svg preserveAspectRatio="xMaxYMax meet" viewBox="0 0 30 40" width="30" height="60">
<use href="#smile" />
</svg>
</g>
</g>
<g id="slice-group-1" transform="translate(100, 220)">
<text x="0" y="-30">---------- slice ----------</text>
<g>
<text y="-10">xMin*</text>
<rect x='.5' y='.5' width='29' height='59'/>
<svg preserveAspectRatio="xMinYMin slice" viewBox="0 0 30 40" width="30" height="60">
<use href="#smile" />
</svg>
</g>
<g transform="translate(50,0)">
<text y="-10">xMid*</text>
<rect x='.5' y='.5' width='29' height='59'/>
<svg preserveAspectRatio="xMidYMid slice" viewBox="0 0 30 40" width="30" height="60">
<use href="#smile" />
</svg>
</g>
<g transform="translate(100,0)">
<text y="-10">xMax*</text>
<rect x='.5' y='.5' width='29' height='59'/>
<svg preserveAspectRatio="xMaxYMax slice" viewBox="0 0 30 40" width="30" height="60">
<use href="#smile" />
</svg>
</g>
</g>
<g id="slice-group-2" transform="translate(250, 220)">
<text x="0" y="-30">--------------- slice ---------------</text>
<g>
<text y="-10">*YMin</text>
<rect x='.5' y='.5' width='49' height='29'/>
<svg preserveAspectRatio="xMinYMin slice" viewBox="0 0 30 40"
width="50" height="30">
<use href="#smile" />
</svg>
</g>
<g transform="translate(70,0)">
<text y="-10">*YMid</text>
<rect x='.5' y='.5' width='49' height='29'/>
<svg preserveAspectRatio="xMidYMid slice" viewBox="0 0 30 40" width="50" height="30">
<use href="#smile" />
</svg>
</g>
<g transform="translate(140,0)">
<text y="-10">*YMax</text>
<rect x='.5' y='.5' width='49' height='29'/>
<svg preserveAspectRatio="xMaxYMax slice" viewBox="0 0 30 40" width="50" height="30">
<use href="#smile" />
</svg>
</g>
</g>
</svg>

Example PreserveAspectRatio
在 SVG 内容中包含一个 ‘svg’ 元素会创建一个新的 SVG 视口,所有包含的图形都在其中绘制;这隐式地建立了新的视口坐标系和新的用户坐标系。此外,由于已经建立了新的 SVG 视口,百分比单位在此处的含义也随之改变(参见 Units)。
新 SVG 视口的边界由建立该视口的元素(例如 ‘svg’)上的 ‘x’、‘y’、‘width’ 与 ‘height’ 属性决定。新视口坐标系和新用户坐标系的原点均位于 (‘x’, ‘y’),其中 ‘x’ 与 ‘y’ 为建立该 SVG 视口的元素的对应属性值。新视口坐标系和新用户坐标系的方向与建立该视口的元素当前的用户坐标系方向保持一致。新视口坐标系和新用户坐标系中的一个单位大小与建立该视口的元素当前用户坐标系中的一个单位大小相同。
这里是一个例子
<?xml version="1.0" standalone="no"?>
<svg width="4in" height="3in"
xmlns="https://w3org.cn/2000/svg">
<desc>This SVG drawing embeds another one,
thus establishing a new SVG viewport
</desc>
<!-- The following statement establishing a new SVG viewport
and renders SVG drawing B into that SVG viewport -->
<svg x="25%" y="25%" width="50%" height="50%">
<!-- drawing B goes here -->
</svg>
</svg>
有关创建新 SVG 视口的详细示例,请参见 PreserveAspectRatio 示例。
以下元素会建立新的 SVG 视口:
出于历史原因,‘pattern’ 与 ‘marker’ 元素即使接受 ‘viewBox’ 也不创建新视口。‘clipPath’ 与 ‘mask’ 元素同样不创建新视口。这些元素内部的百分比长度并不与图形效果区域的尺寸成比例。
‘foreignObject’ 元素会为其子内容建立一个新的 CSS 包含块。同样,‘video’、‘audio’ 与 ‘canvas’ 元素在渲染其后备内容时也会产生类似效果。要渲染位于 ‘foreignObject’ 内的 SVG 元素,需要在该 ‘svg’ 元素中再建立 SVG 文档片段和 SVG 视口。
一个 ‘image’ 或 ‘iframe’ 元素会为被引用的文档创建一个新的 文档视口。如果被引用的文档是 SVG 文件,则它自然会建立自己的 SVG 视口。
是否为新 SVG 视口额外建立剪裁路径取决于建立该视口的元素的 overflow 属性值。
SVG 对属性、表现属性以及 CSS 属性遵循 CSS 值与单位模块 [css-values] 中所描述的通用值和单位的定义。每个属性和属性必须声明其使用的组件值类型。后续或扩展的 CSS 工作组或 SVG 工作组的规范可能会扩展基本数据类型或添加新数据类型。
对于被定义为相对于 SVG 视口大小的 <percentage> 值
sqrt((width)**2 + (height)**2)/sqrt(2)。Example Units 展示了一些不同单位类型的处理规则。
<?xml version="1.0" standalone="no"?>
<svg width="400px" height="200px" viewBox="0 0 4000 2000"
xmlns="https://w3org.cn/2000/svg">
<title>Example Units</title>
<desc>Illustrates various units options</desc>
<!-- Frame the picture -->
<rect x="5" y="5" width="3990" height="1990"
fill="none" stroke="blue" stroke-width="10"/>
<g fill="blue" stroke="red" font-family="Verdana" font-size="150">
<!-- Absolute unit specifiers -->
<g transform="translate(400,0)">
<text x="-50" y="300" fill="black" stroke="none">Abs. units:</text>
<rect x="0" y="400" width="4in" height="2in" stroke-width=".4in"/>
<rect x="0" y="750" width="384" height="192" stroke-width="38.4"/>
<g transform="scale(2)">
<rect x="0" y="600" width="4in" height="2in" stroke-width=".4in"/>
</g>
</g>
<!-- Relative unit specifiers -->
<g transform="translate(1600,0)">
<text x="-50" y="300" fill="black" stroke="none">Rel. units:</text>
<rect x="0" y="400" width="2.5em" height="1.25em" stroke-width=".25em"/>
<rect x="0" y="750" width="375" height="187.5" stroke-width="37.5"/>
<g transform="scale(2)">
<rect x="0" y="600" width="2.5em" height="1.25em" stroke-width=".25em"/>
</g>
</g>
<!-- Percentages -->
<g transform="translate(2800,0)">
<text x="-50" y="300" fill="black" stroke="none">Percentages:</text>
<rect x="0" y="400" width="10%" height="10%" stroke-width="1%"/>
<rect x="0" y="750" width="400" height="200" stroke-width="31.62"/>
<g transform="scale(2)">
<rect x="0" y="600" width="10%" height="10%" stroke-width="1%"/>
</g>
</g>
</g>
</svg>

Example Units
左侧的三个矩形演示了使用绝对单位标识符 “in”(英寸)的情况。CSS 将 1 英寸定义为等于 96 像素。因此,使用英寸指定的最上方矩形的尺寸恰好与使用用户单位(每英寸对应 96 用户单位)指定的中间矩形的尺寸相同。底部矩形展示了当英寸单位的数值被缩放时会发生的情况。
中间的三个矩形演示了使用相对单位标识符 “em”。由于在最外层 ‘g’ 元素上将 font-size 设置为 150,因此每个 “em” 单位等同于 150 用户单位。最上方的矩形使用 “em” 单位,其尺寸恰好与使用用户单位(每 “em” 对应 150 用户单位)指定的中间矩形相同。底部矩形展示了当 “em” 单位的数值被缩放时的结果。
右侧的三个矩形演示了使用百分比单位。请注意,针对 SVG 视口元素(在本例中为 最外层 svg 元素)的用户坐标系,其宽度与高度分别为 4000 与 2000,因为处理 ‘viewBox’ 属性会导致用户坐标系被变换。最上方的矩形使用百分比单位,其尺寸恰好与使用等价用户单位指定的中间矩形相同。特别是,中间矩形的 stroke-width 属性被设置为 sqrt((actual-width)**2 + (actual-height)**2) / sqrt(2) 的 1 %,在本例中即 0.01 × sqrt(4000² + 2000²) / sqrt(2) ≈ 31.62。底部矩形展示了当百分比单位的数值被缩放时的效果。
元素的边界框(或称 “bbox”)是与该元素用户坐标系坐标轴对齐、能够完全包围该元素及其后代的最紧凑矩形。
可以为元素计算三种类型的边界框:
请注意,元素上的 opacity、visibility、fill、fill-opacity、fill-rule、stroke-dasharray 与 stroke-dashoffset 属性的取值对元素的边界框没有影响。
对于曲线形状,边界框必须包围曲线边缘的所有部分,而不仅仅是端点。注意,曲线的控制点如果未定义为位于生成曲线的直线上(例如 Cubic Bézier 命令的第二组坐标),则这些控制点不应计入边界框的尺寸(虽然这些点可能位于边界框内部,如果它们位于形状内部,或位于曲线附近)。例如,位于曲线外侧、距离曲线边缘更远的控制点必须从边界框中排除。
The path 'M20,50 L35,100 H120 V50 Q70,10 20,50' 用淡蓝色显示。左侧显示了该路径的正确对象边界框。请注意,它不包括曲线的最高控制点,但它包含了全部蓝色形状,即使这些部分超出了控制点的凸包。
即使元素不在 渲染树 中——例如它被设置为 'display: none'、位于 ‘defs’ 元素内部、通常不渲染的 ‘symbol’ 元素或当前未出现在文档树中——它仍然拥有边界框。对该元素调用 getBBox 将返回与该元素已渲染时相同的矩形。然而,不在 渲染树 中的元素不会对任何祖先元素的边界框产生贡献。
以下示例定义了一系列元素。每个带有 ID 的元素预期的 对象边界框 如下所示。
<svg xmlns="https://w3org.cn/2000/svg">
<title>Bounding Box Calculation</title>
<desc>Examples of elements with different bounding box results based on context.</desc>
<defs id="defs-1">
<rect id="rect-1" x="20" y="20" width="40" height="40" fill="blue" />
</defs>
<g id="group-1">
<use id="use-1" href="#rect-1" x="10" y="10" />
<g id="group-2" display="none">
<rect id="rect-2" x="10" y="10" width="100" height="100" fill="red" />
</g>
</g>
</svg>
| 元素 ID | 边界框结果 |
|---|---|
"defs-1" |
{0, 0, 0, 0} |
"rect-1" |
{20, 20, 40, 40} |
"group-1" |
{30, 30, 40, 40} |
"use-1" |
{30, 30, 40, 40} |
"group-2" |
{10, 10, 100, 100} |
"rect-2" |
{10, 10, 100, 100} |
对于 文本内容元素,在计算边界框时,必须把每个字形视为独立的图形元素。计算时必须假设所有字形占据 完整字形单元格。 完整字形单元格 的宽度等于水平前进距离,高度等于水平文本的 EM 框。对于横向排版的竖直文本,完整字形单元格 的宽度等于 EM 框,高度等于水平前进距离。对于其他竖直文本,完整字形单元格 的宽度等于 EM 框,高度等于竖直前进距离;如果字体未定义竖直前进距离,则高度等于 EM 框的高度。 例如,对于水平文本,计算时必须假设每个字形在垂直方向上延伸至字体的完整上升值和下降值。
由于声明式或脚本动画可以改变元素的形状、大小和位置,边界框是可变的。因此,边界框应反映请求该边界框时(无论是通过脚本调用还是作为声明式或链接语法的一部分)元素在特定时间点的当前值。
宽度、长度或两者均为零的元素(例如垂直或水平线,或宽度或高度为零的 ‘rect’ 元素)仍然拥有边界框,如果指定了正的尺寸,则该维度取正值;如果未指定正尺寸,则宽度和高度均为 '0'。同样,‘path’ 元素的子路径段在宽度和高度为零的情况下,也必须计入该元素的几何以计算边界框。
未指定位置的元素(例如 ‘path’ 元素的 d 属性值为 none)在计算边界框时视为位于点 (0,0)。
请注意,DOM 对象不继承自 SVGGraphicsElement(如渐变元素)的元素没有边界框,因此也没有用于请求边界框的接口。
即使 渲染树 中的元素引用了未解析的资源,它们仍然拥有边界框,由属性中指定的位置和尺寸决定;如果未提供属性值,则使用这些属性的 初始值。例如,元素 <use href="#bad" x="10" y="10"/> 将拥有 x、y 坐标均为 10、宽度和高度均为 0 的边界框。
下面的算法定义了如何为给定元素计算边界框。该算法的输入为:
根据 element 的类型,计算边界框的算法如下:
fill、fill-opacity 与 fill-rule 属性的取值不会影响 fill-shape。
stroke-opacity、stroke-dasharray 与 stroke-dashoffset 的取值不影响描边形状的计算。
值为 (0, 0, 0, 0) 且为空形状的并集 box 仍为 box。
元素的 对象边界框、描边边界框 或 装饰边界框 是使用以下参数调用上述边界框计算算法的结果:element 为元素本身;space 为元素的用户坐标系统;fill 为 true;若计算 描边边界框 或 装饰边界框 则 stroke 为 true,否则为 false;若计算 装饰边界框 则 markers 为 true,否则为 false;并且 clipped 为 false。
以下元素可通过在给定元素上将指定属性设置为 'objectBoundingBox',以对象边界框的分数(在某些情况下也可为百分比)来表达坐标值和长度。
| 元素 | 属性 | 效果 |
|---|---|---|
| ‘linearGradient’ | ‘gradientUnits’ | 表明用于指定渐变向量的属性(‘x1’、‘y1’、‘x2’、‘y2’)表示所应用元素的边界框的分数或百分比。 |
| ‘radialGradient’ | ‘gradientUnits’ | 表明用于指定中心(‘cx’、‘cy’)、半径(‘r’)以及焦点(‘fx’、‘fy’)的属性表示所应用元素的边界框的分数或百分比。 |
| ‘pattern’ | ‘patternUnits’ | 表明用于定义图案平铺方式的属性(‘x’、‘y’、‘width’、‘height’)是使用所应用元素的边界框来建立的。 |
| ‘pattern’ | ‘patternContentUnits’ | 表示图案内容的用户坐标系是使用应用该图案的元素的边界框建立的。 |
| ‘clipPath’ | ‘clipPathUnits’ | 表明 ‘clipPath’ 元素内容的用户坐标系统是使用所裁剪路径所作用的元素的边界框来建立的。 |
| ‘mask’ | ‘maskUnits’ | 表明用于定义遮罩区域的属性(‘x’、‘y’、‘width’、‘height’)是使用所应用遮罩的元素的边界框来建立的。 |
| ‘mask’ | ‘maskContentUnits’ | 表明 ‘mask’ 元素内容的用户坐标系统是使用所应用遮罩的元素的边界框来建立的。 |
| ‘filter’ | ‘filterUnits’ | 表明用于定义 滤镜效果区域 的属性(‘x’、‘y’、‘width’、‘height’)表示所应用滤镜的元素的边界框的分数或百分比。 |
| ‘filter’ | ‘primitiveUnits’ | 表示滤镜原语内的各种长度值表示应用该滤镜的元素的边界框的分数或百分比。 |
在下文的讨论中,适用元素 指给定效果所作用的元素。对于渐变和图案,适用元素是其 fill 或 stroke 属性引用该渐变或图案的 图形元素(有关 文本元素 的特殊规则,请参阅 对象边界框单位与文本元素 的讨论)。对于裁剪路径、遮罩和滤镜,适用元素可以是 容器元素 或 图形元素。
当使用关键字 objectBoundingBox 时,其效果就如同在嵌套变换矩阵列表中插入了一个补充变换矩阵,从而创建了一个新的用户坐标系。
首先,(minx,miny) 与 (maxx,maxy) 坐标由适用元素的 对象边界框 的范围决定。
然后,新用户坐标系中的坐标 (0,0) 被映射到适用元素用户坐标系内紧密边界框的 (minx,miny) 角,新用户坐标系中的坐标 (1,1) 被映射到适用元素紧密边界框的 (maxx,maxy) 角。在大多数情况下,以下变换矩阵会产生正确的效果
[ (maxx-minx) 0 0 (maxy-miny) minx miny ]
当在定义渐变向量、图案平铺、滤镜区域或遮罩区域的属性中使用百分比时,百分比值与相应的小数值等价(例如 50% 与 0.5 等价)。如果在 ‘pattern’、‘clipPath’、‘mask’ 或 ‘filter’ 元素的内容中使用百分比,这些值将按照 单位章节中定义的百分比处理规则进行处理。
对于表示为对象边界框单位的分数或百分比的值,可以指定任何数值。特别地,可以指定小于零或大于一的分数,以及小于 0% 或大于 100% 的百分比。
当适用元素的几何形状没有宽度或高度时(例如水平线或垂直线),不应使用关键字 objectBoundingBox,即使该线在查看时因非零描边宽度而具有实际厚度,因为边界框计算会忽略描边宽度。当适用元素的几何形状没有宽度或高度且指定了 objectBoundingBox 时,则给定的效果(例如渐变或滤镜)将被忽略。
为了在使用 CSS 格式化的宿主文档中包含 SVG,需要计算 具体对象尺寸。该 具体对象尺寸 必须使用 CSS Images 3 中定义的 默认尺寸算法(参见 css-images-3),并使用以下输入进行计算:
从 ‘svg’ 元素的 width 与 height 这两个尺寸属性的实际使用值确定 指定尺寸。
同时,也必须从 width 与 height 这两个尺寸属性中确定 内在尺寸。如果 width 或 height 未被指定,则使用其初始值 'auto'。'auto' 与百分比长度不得用于确定 内在宽度 或 内在高度。
对于位图图像格式,内在尺寸固定在图像文件中,宿主文档可根据需要指定尺寸以缩放图像。SVG 本身是可伸缩的,它会将 内在宽度 与 内在高度 适配为 指定尺寸 的宽度和高度。因此,当以长度形式指定时,‘svg’ 元素的 width 与 height 尺寸属性控制 SVG 图像的 内在尺寸以及在宿主文档中放置 SVG 图像时使用的 指定尺寸。
必须使用以下算法计算 内在宽高比。如果算法返回 null,则说明不存在内在宽高比。
本节定义的行为特定于 CSS,但可适配到其他宿主环境。在所有宿主环境中,内在宽高比(若可用)在为 SVG 视口设定尺寸时必须被尊重。
示例
<svg xmlns="https://w3org.cn/2000/svg"
width="10cm" height="5cm">
...
</svg>
在此示例中,SVG 视口的内在宽高比为 2:1。内在宽度为 10 cm,内在高度为 5 cm。
<svg xmlns="https://w3org.cn/2000/svg"
width="100%" height="50%" viewBox="0 0 200 200">
...
</svg>
在此示例中,最外层 SVG 视口的内在宽高比为 1:1。此情况下的宽高比计算允许在仅在一个方向受约束的包含块内以 object 方式嵌入。
<svg xmlns="https://w3org.cn/2000/svg"
width="10cm" viewBox="0 0 200 200">
...
</svg>
在这种情况下,固有长宽比为 1:1。
<svg xmlns="https://w3org.cn/2000/svg"
width="75%" height="10cm" viewBox="0 0 200 200">
...
</svg>
在此示例中,固有长宽比为 1:1。
为新出现的 auto 值添加更多示例?比如 David Vest 提供的示例。
| SVG 2 要求 | SVG 2 将基于 SVG 1.2 Tiny 引入受约束的变换。 |
|---|---|
| 决议 | 向 SVG 2 规范中加入向量效果扩展提案。 |
| 目的 | 以包含非缩放特性(对象的非缩放部分,以及整个对象的非缩放) |
| 所有者 | Satoru Takagi (ACTION-3619) |
有时希望对象的轮廓保持原始宽度,或对象的位置在任何变换下保持不变。例如,在地图中用 2 px 宽的线条表示道路时,即使用户放大地图,也希望道路保持 2 px 宽;又如在可平移的图表说明中也有类似需求。
为了提供关于特殊坐标变换和图形绘制的此类效果,SVG Tiny 1.2 引入了 vector-effect 属性。虽然 SVG Tiny 1.2 只引入了非缩放描边行为,但本版本加入了多种额外效果。而且这些效果可以组合指定,从而呈现更多样的视觉效果。未来的 SVG 语言版本也将通过该属性实现更强大的向量效果。
除 non-scaling-stroke 与 none 之外的 vector-effect 取值因缺乏实现可能在 SVG 2 中被移除。请在实现阶段反馈实现这些取值的可行性。
| 名称 | vector-effect |
|---|---|
| 值 | none | [ non-scaling-stroke | non-scaling-size | non-rotation | fixed-position ]+ [ viewport | screen ]? |
| 初始值 | none(无) |
| 应用于 | 图形元素 和 ‘use’ |
| 可继承 | 否 |
| 百分比 | 不适用 |
| 媒体 | 视觉 |
| 计算值 | 按指定值 |
| 可动画: | 是 |
这些取值可以枚举,从而可以同时指定具备这些特性的复合效果。
以下两个取值用于说明上述取值的宿主坐标空间,特别是在嵌套视口坐标系统(如嵌套内容或嵌套 ‘svg’ 元素)中的元素时有效。若未指定,初始值为 viewport。
注意:SVG 的未来版本可能会提供指定设备坐标系的方法。
本节列出了有关各种取值组合的变换公式列表,以阐明矢量效果的行为(不包括具有明确含义的 non-scaling-stroke)。
vector-effect 属性对在 3D 渲染上下文 中执行的变换没有任何影响。
<circle vector-effect="veValue" transform="translate(xo yo)" cx="xf" cy="yf" r=".."/>
当 vector-effect 如上所述添加到一个元素时,用户坐标到设备坐标的变换公式会改变如下。这里,xf 与 yf 是相应元素及其后代的用户坐标;xo 与 yo 是该元素拥有的 transform 属性中矩阵元素 e 与 f。此外,|det(CTM)| 表示 CTM 行列式的绝对值。当该值为 0 且指定了 non-scaling-size 时,vector-effect 失效,即相当于 none。
| veValue | 公式 |
|---|---|
| non-scaling-size |
|
| non-rotation |
|
| non-scaling-size non-rotation |
|
| fixed-position |
|
| fixed-position non-scaling-size |
|
| fixed-position non-rotation |
|
| fixed-position non-scaling-size non-rotation |
|
下面给出未使用矢量效果的嵌套视口坐标系的普通坐标变换公式。xviewport(UA) 与 yviewport(UA) 是受 用户代理 直接控制的坐标。CTMthis 是从目标图形的 用户坐标系 到其所属的 视口坐标系 的变换矩阵。CTMparent 是上述 视口坐标系 到其父元素的 视口坐标系 的变换矩阵。CTMroot 则是根视口坐标系(即用户代理)的 CTM。
将前一节的七个公式应用于嵌套视口坐标系时,根据 vector-effect 的附加值是 viewport 还是 screen,公式的使用方式会相应改变。
当指定 viewport 值时,用户代理 计算坐标时会结合前一章的七个公式以及以下公式。
当指定 screen 值时,用户代理 计算坐标时会结合前一章的七个公式以及以下公式。
下面示例展示了 non-scaling-stroke vector-effect 的效果。
<?xml version="1.0"?>
<svg xmlns="https://w3org.cn/2000/svg"
width="6cm" height="4cm" viewBox="0 0 600 400"
viewport-fill="rgb(255,150,200)">
<desc>Example non-scaling stroke</desc>
<rect x="1" y="1" width="598" height="398" fill="none" stroke="black"/>
<g transform="scale(9,1)">
<line stroke="black" stroke-width="5" x1="10" y1="50" x2="10" y2="350"/>
<line vector-effect="non-scaling-stroke" stroke="black" stroke-width="5"
x1="32" y1="50" x2="32" y2="350"/>
<line vector-effect="none" stroke="black" stroke-width="5"
x1="55" y1="50" x2="55" y2="350"/>
</g>
</svg>
下面示例展示了 none vector-effect(即没有矢量效果)。
| 更改 CTM 之前 | 更改 CTM 之后 |
源代码
<svg xmlns="https://w3org.cn/2000/svg" viewBox="-50,-50,500,500" height="500" width="500">
<rect x="-50" y="-50" width="500" height="500" stroke="orange" stroke-width="3" fill="none"/>
<!-- Nested user coordinate system is transformed by this transform attribute -->
<g transform="matrix(2.1169438081370817,0.3576047954311102,-0.3576047954311102,1.4700998667618626,0,0)
translate(-50,-50)">
<svg viewBox="-50,-50,500,500" height="500" width="500">
<!-- Graph paper on the this svg's base user coordinate system -->
<g stroke="green" stroke-width="1" fill="none">
<circle cx="0" cy="0" r="10"/>
<circle cx="150" cy="150" r="7"/>
<path fill="green" stroke="none" d="M0,-3 L30,-3 25,-10 50,0 25,10 30,3 0,3z"/>
<line x1="-100" y1="-100" x2="600" y2="-100" stroke-dasharray="5,5"/>
<line x1="-100" y1="000" x2="600" y2="000"/>
<line x1="-100" y1="100" x2="600" y2="100" stroke-dasharray="5,5"/>
<line x1="-100" y1="200" x2="600" y2="200" stroke-dasharray="5,5"/>
<line x1="-100" y1="300" x2="600" y2="300" stroke-dasharray="5,5"/>
<line x1="-100" y1="400" x2="600" y2="400" stroke-dasharray="5,5"/>
<line x1="-100" y1="500" x2="600" y2="500" stroke-dasharray="5,5"/>
<line y1="-100" x1="-100" y2="600" x2="-100" stroke-dasharray="5,5"/>
<line y1="-100" x1="000" y2="600" x2="000"/>
<line y1="-100" x1="100" y2="600" x2="100" stroke-dasharray="5,5"/>
<line y1="-100" x1="200" y2="600" x2="200" stroke-dasharray="5,5"/>
<line y1="-100" x1="300" y2="600" x2="300" stroke-dasharray="5,5"/>
<line y1="-100" x1="400" y2="600" x2="400" stroke-dasharray="5,5"/>
<line y1="-100" x1="500" y2="600" x2="500" stroke-dasharray="5,5"/>
</g>
<!-- Figure having vector effect -->
<!-- A thick red right arrow and small rectangle on this figure's nested
user coordinate system origin -->
<path id="ve" vector-effect="none"
stroke="red" stroke-width="3" fill="none"
transform="matrix(1,0,0,1,150,150)"
d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
</svg>
</g>
</svg>
下面示例展示了 non-scaling-size 的效果。
| 更改 CTM 之前 | 更改 CTM 之后 |
<path id="ve" vector-effect="non-scaling-size"
stroke="red" stroke-width="3" fill="none"
transform="matrix(1,0,0,1,150,150)"
d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
下面示例展示了 non-rotation 的效果。
| 更改 CTM 之前 | 更改 CTM 之后 |
<path id="ve" vector-effect="non-rotation"
stroke="red" stroke-width="3" fill="none"
transform="matrix(1,0,0,1,150,150)"
d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
下面示例展示了 non-scaling-size non-rotation 的组合效果。
| 更改 CTM 之前 | 更改 CTM 之后 |
<path id="ve" vector-effect="non-scaling-size non-rotation"
stroke="red" stroke-width="3" fill="none"
transform="matrix(1,0,0,1,150,150)"
d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
下面示例展示了 fixed-position 的效果。
| 更改 CTM 之前 | 更改 CTM 之后 |
<path id="ve" vector-effect="fixed-position"
stroke="red" stroke-width="3" fill="none"
transform="matrix(1,0,0,1,150,150)"
d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
下面示例展示了 non-scaling-size fixed-position 的组合效果。
| 更改 CTM 之前 | 更改 CTM 之后 |
<path id="ve" vector-effect="non-scaling-size fixed-position"
stroke="red" stroke-width="3" fill="none"
transform="matrix(1,0,0,1,150,150)"
d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
下面示例展示了 non-rotation fixed-position 的组合效果。
| 更改 CTM 之前 | 更改 CTM 之后 |
<path id="ve" vector-effect="non-rotation fixed-position"
stroke="red" stroke-width="3" fill="none"
transform="matrix(1,0,0,1,150,150)"
d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
下面示例展示了 non-scaling-size non-rotation fixed-position 的完整组合效果。
| 更改 CTM 之前 | 更改 CTM 之后 |
<path id="ve" vector-effect="non-scaling-size non-rotation fixed-position"
stroke="red" stroke-width="3" fill="none"
transform="matrix(1,0,0,1,150,150)"
d="M-50,-50 L50,-50 50,-100 150,0 50,100 50,50 -50,50 -50,-50z M5 0 L0 -5 -5 0 0 5z"/>
SVGTransform 接口用于表示出现在 transform 属性及其表现属性 ‘transform’、‘gradientTransform’ 和 ‘patternTransform’ 中的 <transform-function> 值。一个 SVGTransform 表示变换列表中的单个组件,例如单独的 scale(…) 或 matrix(…) 值。
一个 SVGTransform 对象可以被指定为 只读,这意味着对该对象的任何修改尝试都会抛出异常,如下所述。
一个 SVGTransform 对象可以被 关联 到特定元素。关联的元素用于决定如果对象 反映 了该属性,则应更新哪个元素的 ‘transform’ 表现属性。除非另有说明,SVGTransform 对象默认不关联任何元素。
每个 SVGTransform 对象有两种工作模式之一。它可以
一个 SVGTransform 对象内部维护一个 <transform-function> 值,称为它的 value。它还维护一个 DOMMatrix 对象,称为它的 matrix object,该对象由 matrix IDL 属性返回。SVGTransform 对象的 matrix object 始终与它的 value 同步。
[Exposed=Window]
interface SVGTransform {
// Transform Types
const unsigned short SVG_TRANSFORM_UNKNOWN = 0;
const unsigned short SVG_TRANSFORM_MATRIX = 1;
const unsigned short SVG_TRANSFORM_TRANSLATE = 2;
const unsigned short SVG_TRANSFORM_SCALE = 3;
const unsigned short SVG_TRANSFORM_ROTATE = 4;
const unsigned short SVG_TRANSFORM_SKEWX = 5;
const unsigned short SVG_TRANSFORM_SKEWY = 6;
readonly attribute unsigned short type;
[SameObject] readonly attribute DOMMatrix matrix;
readonly attribute float angle;
void setMatrix(DOMMatrixReadOnly matrix);
void setTranslate(float tx, float ty);
void setScale(float sx, float sy);
void setRotate(float angle, float cx, float cy);
void setSkewX(float angle);
void setSkewY(float angle);
};
在 SVGTransform 上定义的数值变换类型常量用于表示 SVGTransform 的 value 的类型。其含义如下:
| 常量 | 含义 |
|---|---|
| SVG_TRANSFORM_MATRIX | 一个 matrix(…) 值。 |
| SVG_TRANSFORM_TRANSLATE | 一个 translate(…) 值。 |
| SVG_TRANSFORM_SCALE | 一个 scale(…) 值。 |
| SVG_TRANSFORM_ROTATE | 一个 rotate(…) 值。 |
| SVG_TRANSFORM_SKEWX | 一个 skewX(…) 值。 |
| SVG_TRANSFORM_SKEWY | 一个 skewY(…) 值。 |
| SVG_TRANSFORM_UNKNOWN | 其他类型的值。 |
使用数值变换类型常量是一种反模式,且不会为 SVGTransform 支持的任何变换类型引入新的常量值。如果支持并使用其他类型的变换,SVGTransform 将使用 SVG_TRANSFORM_UNKNOWN 类型。下面将说明在这些非标准变换类型下 SVGTransform 的其他属性是如何工作的。
type IDL 属性表示 SVGTransform 的 value 所对应的变换项类型。获取 type 时,将执行以下步骤:
例如,对 scaleX(…) 或 translate3d(…) 这类变换,将返回 SVG_TRANSFORM_UNKNOWN。
matrix IDL 属性将变换表示为 4×4 齐次矩阵,获取时返回 SVGTransform 的 matrix object。当首次创建 matrix object 时,其数值会被设为匹配 SVGTransform 的变换函数 value,并设置为 反映 SVGTransform。
请参阅 CSS Transforms 规范,了解不同变换函数类型如何对应特定矩阵值的描述。
angle IDL 属性表示 rotate(…)、skewX(…) 或 skewY(…) 变换函数的角度参数。获取时,将执行以下步骤:
setMatrix 方法用于将 SVGTransform 设置为给定的矩阵值。当调用 setMatrix(matrix) 时,将执行以下步骤:
setTranslate、setScale、setRotate、setSkewX 与 setSkewY 方法用于将 SVGTransform 设置为新的变换函数值。调用其中任一方法时,将执行以下步骤:
本规范在 Geometry Interfaces 规范的基础上,对 DOMMatrix 对象的行为施加了额外要求,使其能够用于反映接受变换值的表现属性。
每个 DOMMatrix 对象同样有两种工作模式。它可以
可以将 DOMMatrix 指定为 只读,这意味着对该对象的任何修改尝试都会抛出异常。当对只读 DOMMatrix 的任何 IDL 属性赋值,或调用其任何可变变换方法时,都会抛出 NoModificationAllowedError,而不是更新内部值。
请注意,此限制仅适用于可读写的 DOMMatrix 接口;未用于反映 transform 的 DOMMatrixReadOnly 接口在尝试修改时已经会抛出异常。
当对可写的 DOMMatrix 的任何 IDL 属性赋值,或调用其任何可变变换方法后,在更新内部矩阵值后将执行以下步骤:
SVGTransformList 接口是一个 列表接口,其元素为 SVGTransform 对象。SVGTransformList 表示 transform 属性可以取的值,即 <transform-list> 或关键字 none。
[Exposed=Window]
interface SVGTransformList {
readonly attribute unsigned long length;
readonly attribute unsigned long numberOfItems;
void clear();
SVGTransform initialize(SVGTransform newItem);
getter SVGTransform getItem(unsigned long index);
SVGTransform insertItemBefore(SVGTransform newItem, unsigned long index);
SVGTransform replaceItem(SVGTransform newItem, unsigned long index);
SVGTransform removeItem(unsigned long index);
SVGTransform appendItem(SVGTransform newItem);
setter void (unsigned long index, SVGTransform newItem);
// Additional methods not common to other list interfaces.
SVGTransform createSVGTransformFromMatrix(DOMMatrixReadOnly matrix);
SVGTransform? consolidate();
};
createSVGTransformFromMatrix 方法用于根据矩阵对象创建一个新的 SVGTransform 对象。当调用 createSVGTransformFromMatrix(matrix) 时,按如下步骤执行:
consolidate 方法用于将变换列表合并为等价的单一变换函数。当调用 consolidate() 时,按如下步骤执行:
所有其他 SVGLengthList 接口成员的行为在 列表接口 中有定义。
一个 SVGAnimatedTransformList 对象用于 反映 transform 属性以及其对应的表现属性(根据元素不同,可能是 ‘transform’、‘gradientTransform’ 或 ‘patternTransform’)。
[Exposed=Window]
interface SVGAnimatedTransformList {
[SameObject] readonly attribute SVGTransformList baseVal;
[SameObject] readonly attribute SVGTransformList animVal;
};
baseVal 与 animVal IDL 属性表示已反映表现属性的值。获取 baseVal 或 animVal 时,会返回一个 SVGTransformList 对象,它反映相应的表现属性。
SVGPreserveAspectRatio 接口用于表示 ‘preserveAspectRatio’ 属性的取值。
一个 SVGPreserveAspectRatio 对象可以被指定为 只读,这意味着对该对象的任何修改尝试都会抛出异常,如下所述。
每个 SVGPreserveAspectRatio 对象 反映了基本值,即一个 已反映 的 ‘preserveAspectRatio’ 属性(通过 baseVal 或 animVal 成员在 SVGAnimatedPreserveAspectRatio 上公开)。
[Exposed=Window]
interface SVGPreserveAspectRatio {
// Alignment Types
const unsigned short SVG_PRESERVEASPECTRATIO_UNKNOWN = 0;
const unsigned short SVG_PRESERVEASPECTRATIO_NONE = 1;
const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMIN = 2;
const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMIN = 3;
const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMIN = 4;
const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMID = 5;
const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMID = 6;
const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMID = 7;
const unsigned short SVG_PRESERVEASPECTRATIO_XMINYMAX = 8;
const unsigned short SVG_PRESERVEASPECTRATIO_XMIDYMAX = 9;
const unsigned short SVG_PRESERVEASPECTRATIO_XMAXYMAX = 10;
// Meet-or-slice Types
const unsigned short SVG_MEETORSLICE_UNKNOWN = 0;
const unsigned short SVG_MEETORSLICE_MEET = 1;
const unsigned short SVG_MEETORSLICE_SLICE = 2;
attribute unsigned short align;
attribute unsigned short meetOrSlice;
};
在 SVGPreserveAspectRatio 上定义的数值对齐类型常量用于表示 ‘preserveAspectRatio’ 所能取的对齐关键字值。其含义如下:
| 常量 | 含义 |
|---|---|
| SVG_PRESERVEASPECTRATIO_NONE | 关键字 none。 |
| SVG_PRESERVEASPECTRATIO_XMINYMIN | 关键字 xMinYMin。 |
| SVG_PRESERVEASPECTRATIO_XMIDYMIN | 关键字 xMidYMin。 |
| SVG_PRESERVEASPECTRATIO_XMAXYMIN | 关键字 xMaxYMin。 |
| SVG_PRESERVEASPECTRATIO_XMINYMID | 关键字 xMinYMid。 |
| SVG_PRESERVEASPECTRATIO_XMIDYMID | 关键字 xMidYMid。 |
| SVG_PRESERVEASPECTRATIO_XMAXYMID | 关键字 xMaxYMid。 |
| SVG_PRESERVEASPECTRATIO_XMINYMAX | 关键字 xMinYMax。 |
| SVG_PRESERVEASPECTRATIO_XMIDYMAX | 关键字 xMidYMax。 |
| SVG_PRESERVEASPECTRATIO_XMAXYMAX | 关键字 xMaxYMax。 |
| SVG_PRESERVEASPECTRATIO_UNKNOWN | 其他类型的值。 |
同样,SVGPreserveAspectRatio 上定义的数值 meet-or-slice 类型常量用于表示 ‘preserveAspectRatio’ 可以取的 meet-or-slice 关键字值。其含义如下:
| 常量 | 含义 |
|---|---|
| SVG_MEETORSLICE_MEET | 关键字 meet。 |
| SVG_MEETORSLICE_SLICE | 关键字 slice。 |
| SVG_MEETORSLICE_UNKNOWN | 其他类型的值。 |
align IDL 属性表示 ‘preserveAspectRatio’ 值中的对齐关键字部分。获取时,执行以下步骤:
在设置 align 时,执行以下步骤:
meetOrSlice IDL 属性表示 ‘preserveAspectRatio’ 值中的 meet-or-slice 关键字部分。获取时,执行以下步骤:
在设置 meetOrSlice 时,执行以下步骤:
一个 SVGAnimatedPreserveAspectRatio 对象用于 反映 ‘preserveAspectRatio’ 属性。
[Exposed=Window]
interface SVGAnimatedPreserveAspectRatio {
[SameObject] readonly attribute SVGPreserveAspectRatio baseVal;
[SameObject] readonly attribute SVGPreserveAspectRatio animVal;
};
The baseVal 和 animVal IDL 属性表示已反映的 ‘preserveAspectRatio’ 属性的当前非动画值。获取 baseVal 或 animVal 时,会返回一个 SVGPreserveAspectRatio 对象,该对象 反映基值(即 ‘preserveAspectRatio’ 属性)位于获取该对象的 SVG 元素上,而该元素的反映 IDL 属性类型为 SVGAnimatedPreserveAspectRatio。