裁剪以适合svg图案

问题描述 投票:20回答:1

我有模式,每个模式都有一个图像。我需要将图像缩放到容器的整个宽度或高度,这些容器是路径,同时保留它们的比例。基本上,如果你设置min-width:100%; min-height:100%;,他们需要表现得像html图像

我以前没有使用过很多svgs,也不知道要改变哪些属性来获得这种行为。我一直在尝试viewBoxpreserveAspectRatiopatternUnits等各种组合,但我似乎无法得到我想要的东西。

svg image-scaling
1个回答
58
投票

为了实现这一点,您需要了解objectBoundingBox单元在SVG中的工作方式,以及preserveAspectRatio的工作原理。

Object Bounding Box Units

渐变,模式和许多其他SVG特征的大小和内容可以通过指定path作为单位绘制的对象大小(rectcircleobjectBoundingBox)来指定。相反的是userSpaceOnUse,它使用绘制形状的坐标系。

对象边界框单元通常是声明图形填充元素的大小和位置的默认值;你可以通过在patternUnits元素上设置<pattern>属性来改变它。但是,用户空间单位通常是内容图形中使用的任何单位的默认值;要更改此项,请设置patternContentUnits属性。

所以第一步:要创建一个完全填充形状的图案,您需要:

  • 将模式的高度和宽度声明为100%(或1);默认情况下,这些将相对于边界框进行解释)。
  • 宣布patternContentUnits="objectBoundingBox"
  • 调整内容(图像)的大小,使其高度和宽度为1。

您不能将100%用作模式内容本身内的1个对象边界框单元的同义词(即图像尺寸);百分比是相对于SVG大小而不是objectBoundingBox解释的。*

我应该提一下,因为你说你的形状是<path>元素,对象边界框是垂直于绘制路径的坐标系的最小矩形,包含所有路径的点。它不包括中风。例如,水平直线具有零高度边界框;有角度的线具有边界框矩形,使得该线是框的对角线。如果您的路径形状笨拙和/或与坐标系不完全对齐,则边界框可能比路径大得多。

Preserving Aspect Ratio

preserveAspectRatio属性适用于图像和任何可以具有viewBox属性的元素:父级<svg>,嵌套<svg><symbol><marker><pattern>。对于图像,纵横比是根据图像的固有宽度:高度比计算的,对于所有其他图像,它是根据viewBox attribute中的宽度:高度数计算的。

对于任一类型的元素,如果声明元素的高度或宽度与宽高比不匹配,则preserveAspectRatio属性确定是否将拉伸内容以适合(none),大小适合一个维度并在其他(slice)或缩小以适应两个尺寸与额外的空间(meet);对于meetslice选项,您还可以指定如何对齐空间中的内容。

但是,重要的是要注意可用空间的宽高比是在当前坐标系中计算的,而不是在屏幕像素中计算的。因此,如果更高级别的viewBox或转换已经改变了宽高比,即使在当前元素上设置了preserveAspectRatio属性,事情仍然可能会失真。

另一件要知道的是,默认值通常不是none。对于<image><pattern>元素,默认值为xMidYMid meet - 即缩小到适合和居中。当然,如果模式元素具有viewBox属性,则此默认值仅对模式元素产生影响(否则,假设它没有保留的宽高比)。

您想要用于preserveAspectRatio的价值取决于图像和设计:

  • 是应该拉伸图像以适应形状preserveAspectRatio="none"
  • 是否应保持图像纵横比,但尺寸完全适合或覆盖形状?

在第一种情况下(拉伸),您不需要对<pattern>元素执行任何操作(没有viewBox表示没有宽高比控制),但您需要专门关闭图像上的宽高比控制。

相反,如果你想避免图像失真,你需要:

  • viewBox元素上设置preserveAspectRatio<pattern>属性;
  • 如果你想要一些不同于默认值的东西,请在preserveAspectRatio上设置<image>属性。

工作实例

This fiddle shows three ways of getting a pattern image to fill a shape

  • 顶行已禁用方面控制。 <!-- pattern1 - no aspect ratio control --> <pattern id="pattern1" height="100%" width="100%" patternContentUnits="objectBoundingBox"> <image height="1" width="1" preserveAspectRatio="none" xlink:href="/*url*/" /> </pattern>
  • 中间行对<image>元素进行宽高比控制,因此图片被裁剪以适合图案,但是当在矩形中绘制图案时图片仍然会扭曲,因为定义坐标系的objectBoundingBox单位的高度与宽度不同。 (圆圈中的图像不会扭曲,因为圆圈的边界框是正方形。) <!-- pattern2 - aspect ratio control on the image only --> <pattern id="pattern2" height="100%" width="100%" patternContentUnits="objectBoundingBox"> <image height="1" width="1" preserveAspectRatio="xMidYMid slice" xlink:href="/*url*/" /> </pattern>
  • 底行在图像和图案上都设置了preserveAspectRatio(还有在图案上设置的viewBox)。图像被裁剪但未拉伸。 <!-- pattern3 - aspect ratio control on both image and pattern --> <pattern id="pattern3" height="100%" width="100%" patternContentUnits="objectBoundingBox" viewBox="0 0 1 1" preserveAspectRatio="xMidYMid slice"> <image height="1" width="1" preserveAspectRatio="xMidYMid slice" xlink:href="/*url*/" /> </pattern>

来源图片by Stefan Krause, from Wikimedia Commons。原始宽高比为4:6纵向模式。

* 2015-04-03更正

© www.soinside.com 2019 - 2024. All rights reserved.