理解 svg 的 viewBox 属性(二)
本帖最后由 马黑黑 于 2023-10-31 11:38 编辑 <br /><br /><style>.ma p { margin: 10px 0; }
.ma > pre { padding: 16px; background: #efefef; font: normal 16px monospace; white-space: pre-wrap; word-wrap: break-word; tab-size: 4; }
.rred { color: red; }
</style>
<div class="ma">
<p>preserveAspectRatio 属性指定被缩放的图像相对 svg 视口即 svg 实际宽高尺寸的对齐方式,具体来说,它决定如何将 viewBox 塞进 svg 画布里:当 svg 或其相应子元素设置了 viewBox,通过 preserveAspectRatio 属性可以指定 viewBox 的 ① 位置 和 ② 伸缩方式(处理边缘问题)。
</p><p>不设置 preserveAspectRatio 属性,并不等于 preserveAspectRatio="none",换言之,preserveAspectRatio 属性缺省时其值并不是无(none)。preserveAspectRatio="none" 表示,不保留坐标的宽高比而是完全按 svg 视口比例缩放坐标,具体是,viewBox 所设定(选定)的区域,遵照 viewBox 的 x 和 y 参数值决定对齐方式,并依照 svg 的实际宽高尺寸对 viewBox 规范的区域(x→width、y→height)进行水平和垂直方向的伸缩,为此,最终映射出来的图形可能会变形。之前我们发布的 <a href="https://www.huachaowang.com/forum.php?mod=viewthread&tid=72103&extra=page%3D1">svg viewBox 属性在线演示</a> 就设置了 preserveAspectRatio="none",大家可以调整 viewBox 宽高不同的参数来感受图形变形的情形。
</p><p>选择 preserveAspectRatio 为 none 时,图形可能会变形,除非各个比例正好合适。变形可能不是我们所需要的,为此,svg 为 preserveAspectRatio 提供了另外一种足够复杂的解决方案:首先是对齐方式,就是映射图像位置如何摆放。这是配合 viewBox 属性工作的 preserveAspectRatio 属性值的第一个参数,名为 alignment(对齐方式),共有九种方式:
</p><pre> xMinYMin
xMinYMid
xMinYMax
xMidYMin
xMidYMid
xMidYMax
xMaxYMin
xMaxYMid
xMaxYMax
</pre>
<p>不要被这些长字符吓倒,它们的组合有规律:x、Y 分别表示水平、垂直方向,分别对应 viewBox 的 x 参数、y 参数,然后 x 和 Y 都会分别跟 Min、Mid 和 Max 进行组合,其中,Min、Mid、Max 的本意是小、中、大,这里呢,Min 表示往坐标小的方向(向左)、Mid 表示往坐标的中间(居中)、Max 表示往坐标大的方向(向右)对齐。注意,水平方向用小写 x 、垂直方向用大写 Y 分别跟 3M(三个大写美眉)组词,x和Y要配套使用才能规定对齐的方式。以 xMinYMin 为例,它表示,viewBox 在画布上的映射的对齐方式是,X轴往小的方向对齐、Y轴往小的方向对齐,就是讲,这个时候,映射在svg画布上的图案向左、上靠齐,相当于左对齐、上对齐;再以 xMaxYMax 为例,它表示X和Y轴方向都往大的方向对齐,即右对齐、下对齐。其他各值依此类推。</p>
<p class="rred">【提示】注意 x、Y 跟 Min、Mid、Max 组词时的大小写问题,x 小写,Y 大写!还有,3个大 MM 的 M 大写!</p>
<p>preserveAspectRatio 若使用了上述对齐方式的任何一种,则它还需要配套使用另一个参数,即处理边缘的伸缩方式,共两个值可选,要么是 meet,要么是 slice ——</p>
<p>meet :viewBox保持等比例缩放,整个viewBox在viewport中都是可见的。在满足2个约束的条件基础上,尽可能的放大viewBox,当viewBox的宽高比和viewport的宽高比不匹配的时候,取宽高比中最小的那个。简言之,meet参数将按照 viewBox 短边比例来缩放图像。</p>
<p>slice :修剪viewBox以保持等比例缩放,整个 viewport 区域会被 viewBox 覆盖。在满足2个约束的条件基础上,尽可能的缩小 viewBox,当 viewport 的宽高比和 viewBox 的宽高比不匹配时,取宽高缩放比例中较大的那个。简言之,slice 按照 viewBox 长边比例来缩放图像。</p>
<p>最后给出代码样式:</p>
<pre><svg width="200" height="130" <span class="rred">viewBox="0 0 126 82" preserveAspectRatio="xMinYMin slice"</span>>
<!-- 其他代码 -->
</svg>
</pre>
</div> 纯理论篇。抽象,难懂,先懂个大概吧,稍后会给出一个演示实例 这个是讲述的viewBox等比例投射吧,不知preserveAspectRatio 属性缺省时的值是什么{:4_173:} 大中小的xy组合给出了9种对齐方式,xy的大小写的规定有点怪。 这个和background:的设置有相似之处,而且伸缩方式的内容也让我想到cover和contain的区别{:4_204:} 完全看不懂,都是高深知识吖,掩面飘过{:6_245:} 红影 发表于 2023-10-31 13:39
大中小的xy组合给出了9种对齐方式,xy的大小写的规定有点怪。
对,从常理上讲,两个都小写就好 红影 发表于 2023-10-31 13:35
这个是讲述的viewBox等比例投射吧,不知preserveAspectRatio 属性缺省时的值是什么
缺省时,alignment 是 xMidYmid,边缘处理方式是 meet:
preserveAspectRatio=“xMidYMid meet" 幸运草 发表于 2023-10-31 16:34
完全看不懂,都是高深知识吖,掩面飘过
基础是 svg ,有一定了解的就可以弄懂 马黑黑 发表于 2023-10-31 16:50
对,从常理上讲,两个都小写就好
既然这样规定了,就是照着规定的执行吧。 马黑黑 发表于 2023-10-31 16:51
缺省时,alignment 是 xMidYmid,边缘处理方式是 meet:
preserveAspectRatio=“xMidYMid meet"
哦,默认是居中、按短边比例缩放图像。知道了,谢谢黑黑解答{:4_187:} 红影 发表于 2023-10-31 19:36
哦,默认是居中、按短边比例缩放图像。知道了,谢谢黑黑解答
meet是针对短边,slice是针对长边 红影 发表于 2023-10-31 19:34
既然这样规定了,就是照着规定的执行吧。
大概最好酱紫
马黑黑 发表于 2023-10-31 22:17
meet是针对短边,slice是针对长边
slice放到了更大。 马黑黑 发表于 2023-10-31 22:17
大概最好酱紫
也只能这样子啊{:4_173:} 红影 发表于 2023-10-31 23:09
也只能这样子啊
没有BCD选项? 红影 发表于 2023-10-31 23:09
slice放到了更大。
meet 和 slice 行为模式不一样 马黑黑 发表于 2023-10-31 16:52
基础是 svg ,有一定了解的就可以弄懂
不懂{:6_225:} 马黑黑 发表于 2023-11-1 07:08
没有BCD选项?
去搜了一下,BCD是二进制编码的十进制,不知道这个啊{:4_173:} 马黑黑 发表于 2023-11-1 07:08
meet 和 slice 行为模式不一样
是的,得到的效果也不同。