简体   繁体   English

如何使用其父容器制作 svg 比例尺?

[英]How can I make an svg scale with its parent container?

I want to have an inline svg element's contents scale when size is non-native.当大小不是本机时,我希望有一个内联 svg 元素的内容缩放。 Of course I could have it as a separate file and scale it like that.当然,我可以将它作为一个单独的文件并像这样缩放它。

index.html: <img src="foo.svg" style="width: 100%;" /> index.html: <img src="foo.svg" style="width: 100%;" /> <img src="foo.svg" style="width: 100%;" />

foo.svg: <svg width="123" height="456"></svg> foo.svg: <svg width="123" height="456"></svg>

However, I want to add additional styles to the SVG thru CSS, so linking an external one is not an option.但是,我想通过 CSS 向 SVG 添加其他样式,因此不能选择链接外部样式。 How do I make an inline SVG scale?如何制作内联 SVG 比例?

To specify the coordinates within the SVG image independently of the scaled size of the image, use the viewBox attribute on the SVG element to define what the bounding box of the image is in the coordinate system of the image, and use the width and height attributes to define what the width or height are with respect to the containing page.要指定 SVG 图像内的坐标而与图像的缩放大小无关,请使用 SVG 元素上的viewBox属性来定义图像的边界框在图像坐标系中的位置,并使用widthheight属性定义相对于包含页面的宽度或高度。

For instance, if you have the following:例如,如果您有以下情况:

<svg>
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

It will render as a 10px by 20px triangle:它将呈现为 10 像素 x 20 像素的三角形:

10x20 三角形

Now, if you set only the width and height, that will change the size of the SVG element, but not scale the triangle:现在,如果您只设置宽度和高度,这将改变 SVG 元素的大小,但不会缩放三角形:

<svg width=100 height=50>
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

10x20 三角形

If you set the view box, that causes it to transform the image such that the given box (in the coordinate system of the image) is scaled up to fit within the given width and height (in the coordinate system of the page).如果您设置视图框,这会导致它转换图像,使得给定的框(在图像的坐标系中)被放大以适应给定的宽度和高度(在页面的坐标系中)。 For instance, to scale up the triangle to be 100px by 50px:例如,将三角形放大为 100 像素 x 50 像素:

<svg width=100 height=50 viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

100x50 三角形

If you want to scale it up to the width of the HTML viewport:如果要将其放大到 HTML 视口的宽度:

<svg width="100%" viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

300x150 三角形

Note that by default, the aspect ratio is preserved.请注意,默认情况下,会保留纵横比。 So if you specify that the element should have a width of 100%, but a height of 50px, it will actually only scale up to the height of 50px (unless you have a very narrow window):因此,如果您指定元素的宽度应为 100%,但高度为 50px,它实际上只会放大到 50px 的高度(除非您的窗口非常窄):

<svg width="100%" height="50px" viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

100x50 三角形

If you actually want it to stretch horizontally, disable aspect ratio preservation with preserveAspectRatio=none :如果您确实希望它水平拉伸,请使用preserveAspectRatio=none禁用纵横比保留:

<svg width="100%" height="50px" viewBox="0 0 20 10" preserveAspectRatio="none">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

300x50 三角形

(note that while in my examples I use syntax that works for HTML embedding, to include the examples as an image in StackOverflow I am instead embedding within another SVG, so I need to use valid XML syntax) (请注意,虽然在我的示例中我使用了适用于 HTML 嵌入的语法,但为了将示例作为图像包含在 StackOverflow 中,我改为嵌入到另一个 SVG 中,因此我需要使用有效的 XML 语法)

After like 48 hours of research, I ended up doing this to get proportional scaling:经过 48 小时的研究后,我最终这样做以获得比例缩放:

NOTE: This sample is written with React.注意:这个示例是用 React 编写的。 If you aren't using that, change the camel case stuff back to hyphens (ie: change backgroundColor to background-color and change the style Object back to a String ).如果您不使用它,请将驼峰式的东西改回连字符(即:将backgroundColor更改为background-color并将样式Object更改回String )。

<div
  style={{
    backgroundColor: 'lightpink',
    resize: 'horizontal',
    overflow: 'hidden',
    width: '1000px',
    height: 'auto',
  }}
>
  <svg
    width="100%"
    viewBox="113 128 972 600"
    preserveAspectRatio="xMidYMid meet"
  >
    <g> ... </g>
  </svg>
</div>

Here's what is happening in the above sample code:以下是上述示例代码中发生的情况:

VIEWBOX视图框

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox MDN: https ://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox

min-x, min-y, width and height min-x, min-y, 宽度和高度

ie: viewbox="0 0 1000 1000"即:viewbox="0 0 1000 1000"

Viewbox is an important attribute because it basically tells the SVG what size to draw and where. Viewbox 是一个重要的属性,因为它基本上告诉 SVG 要绘制什么尺寸以及在哪里绘制。 If you used CSS to make the SVG 1000x1000 px but your viewbox was 2000x2000, you would see the top-left quarter of your SVG.如果您使用 CSS 制作 1000x1000 像素的 SVG,但您的 viewbox 是 2000x2000,您会看到 SVG的左上角四分之一

The first two numbers, min-x and min-y, determine if the SVG should be offset inside the viewbox.前两个数字 min-x 和 min-y 确定 SVG 是否应该在视图框内偏移。

My SVG needs to shift up/down or left/right我的 SVG 需要向上/向下或向左/向右移动

Examine this: viewbox="50 50 450 450"检查这个:viewbox="50 50 450 450"

The first two numbers will shift your SVG left 50px and up 50px, and the second two numbers are the viewbox size: 450x450 px.前两个数字会将您的 SVG 向左移动 50 像素并向上移动 50 像素,后两个数字是视图框大小:450x450 像素。 If your SVG is 500x500 but it has some extra padding on it, you can manipulate those numbers to move it around inside the "viewbox".如果您的 SVG 是 500x500 但上面有一些额外的填充,您可以操纵这些数字在“视图框”内移动它。

Your goal at this point is to change one of those numbers and see what happens.您此时的目标是更改其中一个数字,看看会发生什么。

You can also completely omit the viewbox, but then your milage will vary depending on every other setting you have at the time.您也可以完全省略视图框,但是您的里程数将根据您当时的所有其他设置而有所不同。 In my experience, you will encounter issues with preserving aspect ratio because the viewbox helps define the aspect ratio.根据我的经验,您会遇到保留纵横比的问题,因为视图框有助于定义纵横比。

PRESERVE ASPECT RATIO保留纵横比

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio MDN: https ://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio

Based on my research, there are lots of different aspect ratio settings, but the default one is called xMidYMid meet .根据我的研究,有很多不同的纵横比设置,但默认设置称为xMidYMid meet I put it on mine to explicitly remind myself.我把它放在我的身上是为了明确地提醒自己。 xMidYMid meet makes it scale proportionately based on the midpoint X and Y. This means it stays centered in the viewbox. xMidYMid meet使它根据中点 X 和 Y 按比例缩放。这意味着它保持在 viewbox 的中心。

WIDTH宽度

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/width MDN: https ://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/width

Look at my example code above.看看我上面的示例代码。 Notice how I set only width, no height.请注意我如何只设置宽度,不设置高度。 I set it to 100% so it fills the container it is in. This is what is probably contributing the most to answering this Stack Overflow question.我将它设置为 100%,这样它就可以填满它所在的容器。这可能是回答这个 Stack Overflow 问题的最大贡献。

You can change it to whatever pixel value you want, but I'd recommend using 100% like I did to blow it up to max size and then control it with CSS via the parent container.您可以将其更改为您想要的任何像素值,但我建议像我所做的那样使用 100% 将其放大到最大尺寸,然后通过父容器使用 CSS 控制它。 I recommend this because you will get "proper" control.我推荐这个,因为你会得到“适当的”控制。 You can use media queries and you can control the size without crazy JavaScript.您可以使用媒体查询,并且无需疯狂的 JavaScript 即可控制大小。

SCALING WITH CSS使用 CSS 缩放

Look at my example code above again.再次查看我上面的示例代码。 Notice how I have these properties:注意我是如何拥有这些属性的:

resize: 'horizontal', // you can safely omit this
overflow: 'hidden',   // if you use resize, use this to fix weird scrollbar appearance
width: '1000px',
height: 'auto',

This is additional, but it shows you how to allow the user to resize the SVG while maintaining the proper aspect ratio.这是附加的,但它向您展示了如何允许用户调整 SVG 的大小,同时保持适当的纵横比。 Because the SVG maintains its own aspect ratio, you only need to make width resizable on the parent container, and it will resize as desired.因为 SVG 保持自己的纵横比,您只需在父容器上调整宽度,它会根据需要调整大小。

We leave height alone and/or set it to auto, and we control the resizing with width.我们不理会高度和/或将其设置为自动,我们用宽度控制调整大小。 I picked width because it is often more meaningful due to responsive designs.我选择宽度是因为响应式设计通常更有意义。

Here is an image of these settings being used:这是正在使用的这些设置的图像:

在此处输入图像描述

If you read every solution in this question and are still confused or don't quite see what you need, check out this link here.如果您阅读了此问题中的每个解决方案,但仍然感到困惑或不太明白您需要什么,请在此处查看此链接。 I found it very helpful:我发现它很有帮助:

https://css-tricks.com/scale-svg/ https://css-tricks.com/scale-svg/

It's a massive article, but it breaks down pretty much every possible way to manipulate an SVG, with or without CSS.这是一篇庞大的文章,但它几乎分解了所有可能的操作 SVG 的方法,无论是否使用 CSS。 I recommend reading it while casually drinking a coffee or your choice of select liquids.我建议在随便喝杯咖啡或您选择的液体时阅读它。

You'll want to do a transform as such:你会想要做一个这样的转换:

with JavaScript:使用 JavaScript:

document.getElementById(yourtarget).setAttribute("transform", "scale(2.0)");

With CSS:使用 CSS:

#yourtarget {
  transform:scale(2.0);
  -webkit-transform:scale(2.0);
}

Wrap your SVG Page in a Group tag as such and target it to manipulate the whole page:将您的 SVG 页面包装在 Group 标记中,并将其定位为操作整个页面:

<svg>
  <g id="yourtarget">
    your svg page
  </g>
</svg>

Note : Scale 1.0 is 100%:比例 1.0 为 100%

Messing around & found this CSS seems to contain the SVG in Chrome browser up to the point where the container is larger than the image:乱搞并发现这个 CSS 似乎包含 Chrome 浏览器中的 SVG,直到容器大于图像:

div.inserted-svg-logo svg { max-width:100%; }

Also seems to be working in FF + IE 11.似乎也在 FF + IE 11 中工作。

Here's an easy way:这是一个简单的方法:

Type 1: Most SVGs have a viewbox, like so:类型 1:大多数 SVG 都有一个视图框,如下所示:

<svg viewBox="0 0 24 30" ...>

And you can easily control their size in css:您可以在 css 中轻松控制它们的大小:

svg {
  height: 20px;
}

Type 2: If the svg has width and height, but doesn't have a viewport, like so:类型 2:如果 svg 有宽度和高度,但没有视口,如下所示:

<svg width="810" height="540">

Then you can just manually add a viewbox that's exactly the same as its width and hegith, like so:然后您可以手动添加一个与其宽度和高度完全相同的视图框,如下所示:

<svg width="810" height="540" viewBox="0 0 810 540">

Then you can do the same as type 1.然后您可以执行与类型 1 相同的操作。

另一种简单的方法是

transform: scale(1.5);

changing the SVG file was not a fair solution for me so instead, I used relative CSS units .更改 SVG 文件对我来说不是一个公平的解决方案,因此我使用了相对 CSS 单位

vh , vw , % are very handy. vhvw%非常方便。 I used a CSS like height: 2.4vh;我使用了一个 CSS,比如height: 2.4vh; to set a dynamic size to my SVG images.为我的 SVG 图像设置动态大小。

调整 currentScale 属性在 IE 中有效(我用 IE 11 测试过),但在 Chrome 中无效。

If you want to scale SVG without preserveAspectRatio attribute.如果你想在没有preserveAspectRatio属性的情况下缩放 SVG。

This way SVG will always stretch to fill both width and height , and to do so, it will resize just width or height , if necessary, was looking for this for days, so thought to share it here in case someone else is looking for this这样 SVG 将始终拉伸以填充widthheight ,并且这样做,它会调整widthheight ,如有必要,正在寻找这个几天,所以想在这里分享它以防其他人正在寻找这个

You have to remove width and height from <svg> and add viewBox attribute and add preserveAspectRatio="none"您必须从<svg>中删除widthheight并添加viewBox属性并添加preserveAspectRatio="none"

example例子

<?xml version="1.0" encoding="utf-8"?>

<svg 
version="1.1" 
xmlns="http://www.w3.org/2000/svg" 
viewBox="0 0 5.8208332 15.9"
preserveAspectRatio="none">

<polygon points="480.4,200 0,200 0,0 480.4,0 599.9,100 " fill="#E1E1E1"/>
</svg>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM