我正在努力从技术的角度(没有隐喻)准确理解 min-x
和 min-y
在 viewBox
上是如何工作的 .
我花了很多时间在两个有用的资源上:
-
SVG 1.1(官方规格) - 7.7 The ‘viewBox’ attribute
-
Understanding SVG Coordinate Systems and Transformations (Part 1) - Sara Soueidan
'viewBox'属性的值是一个由四个数字组成的列表,并用空格和/或逗号分隔,它们在用户空间中指定一个矩形,该矩形应该映射到由给定元素 Build 的视口的边界,考虑属性'preserveAspectRatio' .
和:
'viewBox'属性的作用是用户代理自动提供适当的变换矩阵,以将用户空间中的指定矩形映射到指定区域(通常是视口)的边界 .
和:
(注意:在某些情况下,除了缩放转换之外,用户代理还需要提供转换转换 . 例如,在最外层的svg元素上,如果'viewBox'属性指定的值不是零,则需要转换转换为或 . )
所以,我的期望是定义一个viewBox与:
-
首先 scaling 视图框,因此它填充视口(假设视口和viewBox具有相同的宽高比)
-
然后 translating viewBox,因此它根据
min-x
和min-y
viewBox属性放置在视口中 .
如果我们看看Sara的两个例子,那不是正在发生的事情 .
在她的第一个例子( <svg width="800" height="600" viewbox="100 100 200 150">...</svg>
)中,它看起来像:
-
viewBox根据视口中的
min-x
/min-y
放置 -
viewBox与视口大小相同 scaled
-
viewBox原点是 translated (已移动)以与视口原点重合
然而,在她的第二个例子中( <svg width="800" height="600" viewbox="-100 -100 400 300">...</svg>
),它看起来像一个完全不同的顺序:
-
viewBox的大小与视口大小相同 scaled
-
viewBox原点是 translated (移动)以某种方式与viewBox
min-x
min-y
指示的方向相反 . 它与视口原点不一致 - 这与第一个示例不同
因此,我认识到我并不完全理解它,因为从技术上讲,它在两种情况下应该以相同的方式工作 .
最后,在Sara的例子中,我不明白为什么蓝色坐标系(用户坐标系)本身不会在视口坐标系中移动到(100,100)或(-100,-100) . 我认为viewBox应该翻译和缩放用户坐标系?
EDIT:
根据this SO answer, min-x
和 min-y
确实遵循我的第一组步骤 . viewBox原点根据 min-x
和 min-y
放置在视口中,然后进行转换,使其原点位于视口原点的顶部 . 然后(缩放之前或之后)填充视口 .
如果这是正确的,我很难理解为什么Sara示例中的蓝色用户坐标系最终不会以其原点位于视口原点之上 . 毕竟,viewBox应该修改用户坐标系 .
3 回答
在图片中,灰色矩形是无限
SVG canvas
.绿色矩形是用户在其显示屏上看到的
viewport
.黄色矩形是虚拟
viewBox
区域,用户通过该区域查看viewport
.viewBox
可沿无限svg
画布的坐标轴移动,如正方向x-min> 0
;y-min> 0
并在负方向-x-min
;-y-min
Image processing svg
接下来是捕获位于viewBox下面的SVG画布片段 .
在下一步中,viewBox的坐标系与
viewport
坐标系的原点对齐 . 并且viewBox
图像捕获的片段将传回viewport
.这里有一个谈判过程和选项:
如果
min-x = 0
和min-y = 0
,viewport
的宽度和高度分别等于viewBox
的宽度和高度,则片段图像不会移动或缩放 .如果
viewBox
向右移动 -min-x> 0
,则图像向左移动 . 很明显,通过捕获viewport
右侧的图像然后将其与原点组合,我们从而将图像向左移动 .如果
viewBox
移动到viewport
s -min-y> 0
以下,图像将会上升 .基于此,有人认为您可以在不使用
CSS
,JavaScript
的情况下实现水平和垂直视差 . 要执行此操作,只需沿SVG画布移动viewBox
,如下图所示 . 单击 Start 按钮 .The offset of the origin of the coordinates viewBox on the x-axis (
min-x=70px
)<svg width="400" height="400" viewBox="70px, 0, 400px, 400px">
在该图中,用户坐标的原点向右移动
70px
,从而移动整个矩形观察区域viewBox (400 x 400px)
沿水平轴向右 .发生这种情况时,捕获
viewBox
下的SVG文档片段的图像,然后将捕获的片段的viewBox查看区域与固定用户视口区域对齐,左上角的原点(0,0) .重新计算图形的坐标,向左移动70px . 事实证明,在应用viewBox时,在视口的固定查看区域中,SVG文档的片段已向左移动 .
Live Demo
The offset of the origin of the viewBox along two axes
min-x=70px, min-y="70px"
<svg width="400" height="400" viewBox="70px, 70px, 400px, 400px">
为清楚起见,在图片底部添加另一个红色矩形 -
6
将原点传送到viewBox后,从原点(70.70)开始的宽度和高度计数的矩形
400 × 400 px
SVG文档片段将进入viewBox .发生图像捕获 . 接下来,viewBox(70,70)的原点与视口(0,0)的原点组合在一起 . 重新计算数字的坐标 .
因此,红色矩形5和6变得完全可见 . 不属于这一领域的一切都被切断了 . 例如,彩色圆圈1,2和4的部分区域 .
Live Demo
使用viewBox缩放
SVG文档片段的比例取决于宽高比:
viewport
和viewBox
如果
viewport
/viewBox
=1
,则比例为1
如果
viewport
/viewBox
与1不同,则比例将在增加或减少的方向上改变 .规模的增加如何解释下图
一个像素
viewBox
拉伸到两个像素viewport
Live Demo
Zoom out svg image 1: 2
<svg width="400" height="400" version="1.1" viewBox="0 0 800 800">
viewport / viewBox = 1/2
viewBox
捕获一个矩形片段800 x 800 px
,即SVG视口400 x 400 px
的整个范围,以及视口右侧和底部的另一个400px
.那是
viewBox
的两个像素被压缩成viewport
的一个像素 . 因此SVG图像减少了一半 .Live Demo
我总是混淆viewBox和viewport . 所以,如果你想为浏览器或SVG设置转换矩阵,我就完全明白了 . 所以我也会尽量避免它 .
viewBox属性向浏览器提供有关SVG图形的大小和坐标原点的信息 . 它定义了进入SVG的窗口 . 只能看到窗口中的部分 .
那么让我们看一个例子:
这告诉浏览器它应该在浏览器的坐标系中绘制尺寸为800px×600px的SVG图形 . 因此,在浏览器DOM中,SVG组件将具有该大小 .
然后,viewbox属性告诉浏览器SVG图形的相关/可见部分大小为200pt×150pt(在SVG坐标系中) . 因此浏览器知道它需要应用400%的缩放比例来将SVG坐标转换为浏览器坐标 .
此外,viewbox属性告诉浏览器SVG坐标系中的点(100,100)将是可见SVG图形窗口的左上角 . 因此浏览器会相应地进行翻译 .
SVG坐标系中具有较小x和y值的所有内容都将被剪裁,即不可见,因为它在窗口之外以及浏览器为SVG创建的空间之外 . 类似地,SVG坐标300(100 200)右侧和坐标250(100 150)下方的所有内容都将位于窗口之外且不可见 .