从技术的角度(没有隐喻),我正在努力确切地了解min-x
上的min-y
和viewBox
的工作原理。
我花了很多时间的两个有用资源:
“ viewBox”属性的值是四个数字的列表 ,,和,由空格和/或分隔 一个逗号,在用户空间中指定一个矩形,该矩形应为 映射到由给定元素建立的视口的边界, 考虑属性“ preserveAspectRatio”。
并且:
“ viewBox”属性的作用是用户代理 自动提供适当的变换矩阵以进行映射 用户空间中指定矩形的边界 地区(通常是视口)。
并且:
(注意:在某些情况下,用户代理将需要提供翻译 规模转换之外的其他转换。例如,在 最外层的svg元素,如果需要,则需要转换转换 “ viewBox”属性指定的值不为零 或。)
所以,我的期望是定义一个viewBox与以下内容相同:
min-x
和min-y
viewBox属性将其放置在视口中。如果我们看一下萨拉的两个例子,starting here,那似乎就没有发生。
在她的第一个示例(<svg width="800" height="600" viewbox="100 100 200 150">...</svg>
)中,它看起来像:
min-x
/ min-y
放置在视口中然而,在她的第二个示例(<svg width="800" height="600" viewbox="-100 -100 400 300">...</svg>
)中,顺序似乎完全不同:
min-x
min-y
所指示的方向相反。它与视口原点不一致-这与第一个示例不同因此,我认识到我并不完全理解它,因为从技术上讲,在两种情况下它应该以相同的方式工作。
最后,在Sara的示例中,我不明白为什么蓝色坐标系(用户坐标系)本身不会移动到视口坐标系中的(100,100)或(-100,-100)。我以为viewBox应该可以翻译和缩放用户坐标系?
编辑:
根据this SO answer,min-x
和min-y
确实遵循了我的第一组步骤。 viewBox原点根据min-x
和min-y
放置在视口中,然后进行翻译,以使其原点位于视口原点之上。然后(在此之前或之后)缩放以填充视口。
如果这是正确的话,我很难理解为什么Sara的示例中的蓝色用户坐标系并不总是以视口原点为起点。毕竟,viewBox应该修改用户坐标系。
答案 0 :(得分:5)
x轴上坐标viewBox
的原点的偏移量(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文档的片段已向左移动。
viewBox的原点沿两个轴的偏移量
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的部分区域。
SVG文档片段的比例取决于纵横比:viewport
和viewBox
如果viewport
/ viewBox
= 1
,则比例将为1
如果viewport
/ viewBox
与1不同,则比例将沿增大或减小的方向变化。
比例的增加如何解释下图
一个像素viewBox
延伸到两个像素viewport
缩小svg图片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图像减少了一半。
答案 1 :(得分:2)
在图片中,灰色矩形是无限的SVG canvas
。
绿色矩形是用户在其显示屏上看到的viewport
。
viewBox
区域,用户可以通过该区域查看viewport
。 viewBox
可以沿无限svg
画布的坐标轴沿正方向x-min> 0
移动; y-min> 0
并沿负面方向-x-min
; -y-min
图像处理svg
viewport
坐标系的原点。和
viewBox
图像捕获的片段被传回给
viewport
。有一个协商过程,可以在这里进行选择:
min-x = 0
和min-y = 0
,则viewport
的宽度和高度分别等于viewBox
s的宽度和高度,则片段图像不会移动或缩放。 viewBox
向右移动-min-x> 0
,则图像向左移动。显然,通过捕获viewport
右侧的图像,然后将其与原点组合,可以将图像向左移动。 viewBox
移到viewport
s-min-y> 0
以下,图像将上升。 基于此,有种想法,您可以在不使用CSS
,JavaScript
的情况下实现水平和垂直视差。为此,只需沿SVG画布移动viewBox
,如下图所示。点击开始按钮。
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="600" height="360" viewBox="0 0 600 360" >
<title> Explanation horizontal of parallax viewBox </title>
<desc> animate the horizontal parallax by modifying a coordinate of the viewBox </desc>
<defs>
<g id="canvas-svg" stroke-width="2px">
<g id="canvas-frame1">
<rect id="v-port1" x="25" y="200" width="110" height="110" stroke="skyblue" fill="yellowgreen" />
<text id="t-port1" x="75" y="255" style="font-size: 16pt;">1 </text>
<text x="26" y="303" > 0 </text>
</g>
<g id="canvas-frame2">
<rect id="v-port2" x="135" y="200" width="110" height="110" stroke="skyblue" fill="dodgerblue" />
<text id="t-port2" x="185" y="255" style="font-size: 16pt;">2 </text>
<text x="136" y="303" > 1168 </text>
</g>
<g id="canvas-frame3">
<rect id="v-port3" x="245" y="200" width="110" height="110" stroke="skyblue" fill="crimson" />
<text id="t-port3" x="295" y="255" style="font-size: 16pt;">3 </text>
<text x="246" y="303" > 2336 </text>
</g>
<g id="canvas-frame4">
<rect id="v-port4" x="355" y="200" width="110" height="110" stroke="skyblue" fill="orange" />
<text id="t-port4" x="405" y="255" style="font-size: 16pt;">4 </text>
<text x="356" y="303" > 3504 </text>
</g>
<g id="canvas-frame5">
<rect id="v-port5" x="465" y="200" width="110" height="110" stroke="skyblue" stroke-width="1px" fill="yellow" />
<text id="t-port5" x="515" y="255" style="font-size: 16pt;">5 </text>
<text x="466" y="303" > 4672 </text>
</g>
</g>
</defs>
<g id="first-rect">
<rect x="25" y="25" width="110" height="110" stroke="skyblue" stroke-width="1px" fill="yellowgreen" />
<text x="75" y="85" style="font-size: 16pt;">1 </text>
<text x="26" y="135" > 0 </text>
</g>
<desc>The SVG canvas is infinite in size. In our example, user a viewport of SVG is in the leftmost position.</desc>
<use xlink:href ="#canvas-svg" x="0" y="0"> </use>
<desc> viewBox is moved along canvas SVG</desc>
<g id="viewBox1">
<rect id="v-box" x="25" y="200" width="110" height="110" stroke="skyblue" stroke-width="5px" fill="none" />
<text id="t-port1" x="45" y="225" style="font-size: 16pt; fill:blue;">viewBox </text>
<animateTransform attributeName="transform" type="translate" begin="startButton.click+0.5s" end="stopButton.click" dur="20s" from="0 0" to="440 0" repeatCount="indefinite" restart="whenNotActive" fill="freeze"/>
</g>
<desc> The image moves to the left viewport</desc>
<use xlink:href ="#canvas-svg" x="0" y="0">
<animateTransform attributeName="transform" type="translate" begin="startButton.click+0.5s" end="stopButton.click" dur="20s" from="0 -170" to="-440 -170" repeatCount="indefinite" restart="whenNotActive" fill="freeze" />
</use>
<desc> Grey background image of the canvas SVG</desc>
<g fill="#E5E5E5" stroke="#E5E5E5">
<rect x="135" y="0" width="465" height="195" />
<rect x="0" y="0" width="25" height="195" />
<rect x="0" y="0" width="135" height="30" />
<rect x="25" y="135" width="135" height="60" />
<rect x="0" y="315" width="600" height="85" />
<rect x="0" y="195" width="25" height="120" />
<rect x="575" y="195" width="25" height="120" />
</g>
<g stroke-width="1px" stroke-dasharray = "5 5">
<line x1="25" y1="140" x2="25" y2="195" stroke="blue" />
<line x1="135" y1="140" x2="135" y2="195" stroke="blue" stroke-width="1px" />
</g>
<g style="font-size: 16pt; fill:blue;">
<text x="45" y="170" > viewport </text>
<text x="15" y="20" style="font-size: 14pt;"> display the user's </text>
<text x="230" y="90" style="font-size: 40pt; fill:#1E90FF"> canvas SVG </text>
</g>
<g id="startButton">
<rect x="520" y="325" rx="8" ry="8" width="60" height="20" fill="#58AE2A" />
<text x="550" y="340" font-size="16" font-weight="bold" font-family="Arial" text-anchor="middle"
fill="white" >Start</text>
</g>
<g id="stopButton">
<rect x="450" y="325" rx="8" ry="8" width="60" height="20" fill="#1E90FF" />
<text x="480" y="340" font-size="16" font-weight="bold" font-family="Arial" text-anchor="middle"
fill="white" >Stop</text>
</g>
</svg>
答案 2 :(得分:1)
我总是混淆 viewBox 和 viewport 。因此,我将尽量避免这种情况。我不完全了解您是否要为浏览器或SVG设置转换矩阵。因此,我也会尽量避免这种情况。
viewBox 属性向您的浏览器提供有关SVG图形的大小和坐标原点的信息。它定义了进入SVG的窗口。窗口中只有一部分可见。
所以让我们看一个例子:
<svg width="800" height="600" viewbox="100 100 200 150">
这告诉浏览器应该在浏览器的坐标系中绘制尺寸为800px x 600px的SVG图形。因此,在浏览器DOM中,SVG组件将具有该大小。
viewbox 属性然后告诉浏览器,SVG图形的相关/可见部分的大小为200pt x 150pt(在SVG坐标系中)。因此,浏览器知道它将需要应用400%的缩放比例才能将SVG坐标转换为浏览器坐标。
此外, viewbox 属性告诉浏览器,SVG坐标系中的点(100,100)将位于可见SVG图形窗口的左上角。因此浏览器将对其进行相应的翻译。
SVG坐标系中所有 x 和 y 值较小的内容都将被裁剪,即不可见,因为它在窗口之外且在浏览器创建的空间之外用于SVG。同样,SVG坐标300(100 + 200)右侧和坐标250(100 + 150)下方的所有内容都将位于窗口外部,并且不可见。