问题
最近在写 svg 时发现,当我需要一个全屏的 svg 动画效果时,基于 viewBox 中的数字写了动画,需要从屏幕正中间向两侧展开的这么个动画效果,但是到了浏览器中永远到不了边上,总是留下一片空白。
开始以为是 padding 之类的属性,后来发现 svg 本身并不包含这些属性啊,奇了怪了。上 MDN 翻了一下,发现有一个 preserveAspectRatio
属性,突然豁然开朗,原来是宽高比的问题,原谅我 div 写多了确实比较少考虑宽高比这样的问题了。
解决方案
在 MDN 中就写的很清楚:
有时候,通常我们使用 viewBox 属性时,希望图形拉伸占据整个视口。在其他情况下,为了保持图形的长宽比,必须使用统一的缩放比例。
这完全符合我全屏动画的效果。
添加一个最暴力的方案:preserveAspectRatio="none"
,直接解决问题,它会忽略宽高比,直接按照视口宽高拉伸。
这样就填满了。
preserveAspectRatio
再来探究一些 preserveAspectRatio
属性的构成。
preserveAspectRatio="<align> [<meetOrSlice>]"
其中:
- align 属性值表示是否强制统一缩放,当 SVG 的 viewbox 属性与视图属性宽高比不一致时使用
- meetOrSlice 是可选的,如果提供的话,与
align
间隔一个或多个的空格,但只能是 meet | slice
align
属性通常需要根据实际需求去考虑编写,它用于定义对齐方式,默认为 xMidYMid
,也就是居中对齐。其他值还有包括 xMinYMin
、xMidYMin
、xMaxYMin
、xMinYMid
等,用于定义具体的对其方式。更多详细属性具体可以参考:MDN文档
meetOrSlice
属性则只可以写 meet
或 slice
。它们分别表示:
-
meet 尽可能放大 viewBox,但是整个 svg 是可见的。简单理解,就是拉伸 svg 图形到可视区域最大值。这种情况下仍然可能出现短边空白的情况。
-
slice 整个视口将会被 svg 覆盖。简单理解,就是拉伸 svg 图形将可视区域完全覆盖,其中 svg 可能会有显示不全的情况,但会根据
align
属性去匹配覆盖情况。这种情况会完全覆盖可视区域,不会出现留白的情况,但是 svg 图形超出视口的部分会被裁剪掉。
无论如何,上面两个参数,都是基于固定宽高比的情况下操作的。
preserveAspectRatio="none"
还有一种情况,align
可以直接填写 none
。它的意思就是完全不用考虑宽高比,内部 viewBox 会直接拉伸 svg 图形到完美匹配视口的宽高。
小结
无论那种情况,基本上只有无法确定视口宽高的情况下,我们才会用到这个属性。但是,我们仍然需要首先知道 svg 的内容,以保证展现时避免出现过度拉伸导致图形扭曲变形的情况。对于 none
这种特殊属性,一定是要慎用,尽量用更多的细节考虑,去完善一个优雅地界面。
文章评论