lets suppose I have an image of dimensions 1280x720
I have some polygons that are computed by a server on top of the original sized images that need to be drawn on top of this image. They are
<polygon points="531,243,687,316,663,593,360,717,191,520" />
<polygon points="275,17,422,45,412,312,271,235" />
<polygon points="929,180,1108,248,985,707,847,676" />
<polygon points="598,70,700,101,658,531,516,436" />
Now I need to display the image and overlay these polygons on top of it. The problem however is that the image is scaled by the browser depending on the window size, which is dynamic. The image is displayed using object-fit-contain CSS so the size changes as I resize.
How do I ensure the SVG co-ordinates above auto scale?
I've read about viewBox but I'm not really looking to specify my own co-ordinates here. The issue is I don't really know how the image will be displayed/sized by the browser as it will depend on the window.
thanks
The default scaling behaviour of SVGs is the same as object-fit: contain. So all you should need to do is set the SVG's viewBox width and height to the same dimensions as the image.
So, for instance, if your image is 640x480, set your viewBox to "0 0 640 480".
div {
position: relative;
}
div > img,
div > svg {
width: 100%;
height: 200px;
}
img {
object-fit: contain;
}
svg {
position: absolute;
top: 0;
}
<div>
<img src="http://lorempixel.com/output/people-q-c-640-480-1.jpg"/>
<svg viewBox="0 0 640 480">
<circle cx="450" cy="215" r="40" fill="none" stroke="red" stroke-width="10"/>
</svg>
</div>
Could you avoid doing this with html in any way? A simple image editor seems like a better way of doing this, but I can't say because I don't know your circumstances. Otherwise you could probably use margin for the placement.
You can use <image> element inside the <svg> tag, then they will become one, you can do any scale with it.
Here is an SVG image example:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="10" y="10" height="130" width="500" style="fill: #000000"/>
<image x="20" y="20" width="300" height="80"
xlink:href="http://jenkov.com/images/layout/top-bar-logo.png" />
<line x1="25" y1="80" x2="350" y2="80"
style="stroke: #ffffff; stroke-width: 3;"/>
</svg>
Reference: SVG image element
Related
I have an SVG on my page. This SVG is a white wave that creates a nice wave effect on the hero image for the page. But the SVG's Path (drawing) crawls up the page when the screen width decreases, creating a gap between itself and the hero image.
How do I align this SVG Path so it stays on the bottom?
.wave {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
border-radius: none;
}
<svg
height="100%"
width="100%"
id="svg"
viewBox="0 0 1440 1"
xmlns="http://www.w3.org/2000/svg"
className="wave"
>
<path
d="M 0,400 C 0,400 0,200 0,200 C 153.19999999999993,213.06666666666666 306.39999999999986,226.13333333333335 449,220 C 591.6000000000001,213.86666666666665 723.6000000000001,188.53333333333333 887,182 C 1050.3999999999999,175.46666666666667 1245.1999999999998,187.73333333333335 1440,200 C 1440,200 1440,400 1440,400 Z"
stroke="none"
stroke-width="0"
fill="#ffffff"
></path>
</svg>
Here is an image of what is happening.
The size and scale of the viewbox (& graphics inside) is controlled by the preserveAspectRatio attribute on the svg.
By default, the viewbox is scaled uniformly to fit the size of the svg and centered horizontally and vertically. (Similar to how a background image would display with the following properties applied: background-position: center center; background-size: contain;)
This is why your path 'crawls up', the svg is positioned at the bottom of the hero but its contents is centered.
The preserveAspectRatio accepts two values, first is alignment, second (optional) is how it 'fits' inside the svg.
preserveAspectRatio="<align> [<meetOrSlice>]"
The mdn page about preserveAspectRatio is really helpful and gives a full list of examples. https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio
tldr:
To fix your issue, add preserveAspectRatio="xMidYMax meet" as an attribute of the SVG, EG:
<svg
height="100%"
width="100%"
id="svg"
viewBox="0 0 1440 234"
xmlns="http://www.w3.org/2000/svg"
className="wave"
preserveAspectRatio="xMidYMax meet"
>
...
</svg>
NB: The viewBox’s height needs to be big enough to contain the graphics, so has been increased. Kudos: Sphinxxx & enxaneta.
I'm trying to create an effect on an svg path with vector="non-scaling-stroke" with a drop shadow using filter: drop-shadow(...).
However, when the path is scaled to fit the screen (having this scaling is necessary) the path remains a a consistent size but the drop shadow stretches:
svg {
width: 1000px; /*just to simulate problem, these would be vw & vh units in practice*/
height: 200px;
}
path {
filter: drop-shadow(0px 0px 1px blue);
}
<svg preserveAspectRatio="none" viewBox="0 0 100 100">
<path fill="none" stroke="black" stroke-width="5" vector-effect="non-scaling-stroke" d="M0,30 h50 v70"></path>
</svg>
As you can see, the shadow is closely fitted around the horizontal section of the line but more spread on the vertical section. This is expected really but I'm wondering if there's any trick I'm missing to have the shadow be a consistent size around the line for the entire path.
As well as using css filter I've tried:
using svg filters drop shadow on the path.
placing a dummy path behind the line with a gaussian blur to simulate a shadow.
Both produce the same result.
I also understand I can resize the svg viewBox to fit the screen with js to avoid the scaling issues altogether but this is really a last resort if there are no other solutions.
Thanks!
I think, that this could work!
svg {
width: 1000px;
/*just to simulate problem, these would be vw & vh units in practice*/
height: 200px;
}
<svg preserveAspectRatio="none" viewBox="0 0 100 100">
<path fill="none" stroke="black" stroke-width="5" vector-effect="non-scaling-stroke" d="M0,30 h50 v70"></path>
<rect x="0" y="29" width="50" height="2" style="fill:blue;filter: blur(2px);" />
<rect x="49.8" y="29" width=".5" height="70" style="fill:blue;filter: blur(.5px);" />
</svg>
I seem to not understand svg. I would like someone to explain to me where I am going wrong. So I have an inline svg:
<div style="width:1000px; height:auto; background-color:blue;">
<svg class="_image"><use xlink:href="#myId" />
<symbol id="myId" viewBox="0 0 1000 700">
<ellipse cx="200" cy="80" rx="100" ry="50"
style="fill:yellow;stroke:purple;stroke-width:2" />
</symbol>
</svg>
</div>
The width of the div is set to 1000px. The svg is set to a 100% width. It has a viewBox. I would now expect the svg to scale 100% in width, which means 1000px in width, and then adjust the height accordingly since it is set to auto both for the div and for the svg itself. I expect this, since I provided a viewbox. Where am I going wrong?
Here is the css:
._image {
width: 100%;
height: auto;
}
...and everything put together as a fiddle: https://jsfiddle.net/hv6ejn98/2/
The svg is set to a 100% width. It has a viewBox.
No it doesn't. Only your <symbol> does. Without a viewBox your SVG won't scale. If you add a viewBox to the SVG, everything works as you expect.
<div style="width:1000px; height:auto; background-color:blue;">
<svg class="_image" viewBox="0 0 1000 700"><use xlink:href="#myId" />
<symbol id="myId" viewBox="0 0 1000 700">
<ellipse cx="200" cy="80" rx="100" ry="50"
style="fill:yellow;stroke:purple;stroke-width:2" />
</symbol>
</svg>
</div>
How can I resize my SVG Logo for responsiveness on Mobile?
Here's my Fiddle and my code is below:
body {
background:black;
}
#media screen and (max-width: 500px) {
svg {
width:50%;
}
}
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<svg version="1.1" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<title>Logo</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Your-Score" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
<g id="Desktop-Your-Score" sketch:type="MSLayerGroup" transform="translate(-23.000000, -24.000000)" font-weight="normal" font-family="Gill Sans" letter-spacing="1.16666663" font-size="28" sketch:alignment="middle" fill="#FFFFFF">
<g id="Header" sketch:type="MSTextLayer">
<g id="Primary-Nav-[home]-Copy">
<g id="Logo" transform="translate(23.000000, 18.000000)">
<text id="TOMORROW’S">
<tspan x="0.0328778028" y="27">TOMORROW’S</tspan>
<tspan x="36.2975262" y="58">SCORE</tspan>
</text>
</g>
</g>
</g>
</g>
</g>
</svg>
For scaling via the img element to work, the SVG image needs to have its width, height and viewBox attributes set inside it. Here is how that looks:
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="70px" height="70px" viewBox="0 0 70 70">
<circle cx="40" cy="40" r="24" style="stroke:#006600; fill:#00cc00"/>
</svg>
When setting the width, height and viewBox property, you tell the browser what part of the virtual canvas to draw. The view box tells the upper left and lower right corner of the virtual canvas. Thus, if the image is scaled to a size bigger than that, the whole image is scaled up, instead of just making the virtual canvas bigger (resulting in white space next to the SVG shapes in the image).
For more clarification search for viewBox property related to SVG.
Always Set Image Width Via CSS Properties
Do not use the width and height attributes of the img element. It will not give the desired effect. The browsers treat these attributes differently than the corresponding CSS properties.
Use your SVG inside of an <img> tag, for example:
<img src="my_SVG_file.svg" alt="" />
Then you can use standard CSS to affect the <img> tag & make it mobile responsive.
img {
max-width: 100%;
}
CODEPEN DEMO
I've got an svg image which I want to autoresize to 100% width.
The problem is, that I've placed an Image (100px x 100px) on the left side of that svg and that picture has to keep its proportions.
I tried it with viewBox, but with this method the whole svg, and not only the path, gets resized.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 600 100" preserveAspectRatio="none" style="-webkit-user-select: auto;">
<g>
<title>title</title>
<image x="0" y="1.00001" width="100" height="100" id="svg_1" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3goUDAEUe/ATzgAAAkNJREFUeNrtnetugkAQRr8hJH3/tzWt7PRHxQuyN4qw6DlJo7GK7Jy9zdBQkxS0DJPkl0e44ZPYVMVo/AA0QkcIEAIIQQggBCGAEIQAQhAypvtk7A0wVzqhPtWYENiRnhBU4QWdu/SREVIQ7Np4eIGU1Pe4bpc/XJL39O6H33kigKnjWOYYc8d0SYOks6Sfy0/oF/aCIwW89HWfPO9merMSvT62IYq9dv/8W9JJ0qkvbKQ1OLXkgloiJLXLnLbdIlNTbrqyzDIRJH2N0o+2hnjlSPbKxVcrvL+2PePUNUgajiLEC4OlfwZsrxzsOuW1LGTt3khiCPVQXEQIIAQhgJA3oala1t2Wb0mhb6tTbG7b65mEzUoacF9XeHpT12kIYdgwwLaXgP8IydV8Hhpgk8bEsrtoRMw0uJ8nyWG4TLNBZdcdUh3FWhCwVEhp0c5iMnKtjUXHzRTcBy274FMS9FaqAP7XDZfP075WDyupj/h660nT5RhKJ2x7ASEIAYQgBBDyASytZXks+atJ/GqTHIRUxCn2dzmGhKdsXIniRd/KWb5RwEsmClt7yio+C4+MljcdDVYzGmIHoHTCLgsQghBACEIAIQgBhCAEEAIIQQggBCGAEIQAQhACCAGEIAQQghBACEIAIQgBhABCEAIIQQggBCGAEIQAQgAhCAGEHBT+bd4LuNyNwTPvud7ZwZ8/CxvxcCvYuVuNvFRI6sYf0MAagowd1hBbWYR9mOBNpixGRiNCgDwEIYAQhABCEAIIAYS0zy9dWbdrK07bIAAAAABJRU5ErkJggg=="/>
<path style="-webkit-user-select: auto;" stroke="#000000" fill="#FF0000" stroke-width="0" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" d="m98.66982,67.61566c0,0 136.5026,-1.32306 303.78312,-30.42615c167.28064,-29.10306 238.87799,-14.55161 238.20886,-14.55161c-0.66913,0 1.33826,79.37253 1.33826,79.37253c0,0 -543.33026,1.32291 -543.99939,1.32291c-0.66912,0 0.66915,-35.71768 0.66915,-35.71768z" id="svg_10"/>
</g>
</svg>
For using the svg I've got
<div class="svg">
<p>tesygst</p>
</div>
and
.svg {
background: url(pathToSvg.svg) no-repeat bottom left;
position : fixed;
bottom : 0;
left : 0;
height : 100px;
width : 100%;
}
The img has to be placed at the left bottom corner, while the path has to extend itself to 100% width starting at the end of that pic.
Hope somebody can help me :/
You can't put an image inside an SVG, stretch the SVG and have the image not stretch also. That's just how things work. You have to think of the contents of the SVG just the same as if you were talking about an <img> rather than an SVG. You stretch the img, the whole thing stretches.
I take it you are trying to keep the image at 100x100px?
You will need to move the image out of the SVG and into the HTML. Then position it in the right place with CSS. For example:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 600 100" preserveAspectRatio="none" style="-webkit-user-select: auto;">
<g>
<title>title</title>
<path style="-webkit-user-select: auto;" stroke="#000000" fill="#FF0000" stroke-width="0" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" d="m98.66982,67.61566c0,0 136.5026,-1.32306 303.78312,-30.42615c167.28064,-29.10306 238.87799,-14.55161 238.20886,-14.55161c-0.66913,0 1.33826,79.37253 1.33826,79.37253c0,0 -543.33026,1.32291 -543.99939,1.32291c-0.66912,0 0.66915,-35.71768 0.66915,-35.71768z" id="svg_10"/>
</g>
</svg>
<img width="100" height="100" src="data:image/png;base64,..."/>
CSS:
IMG {
position: relative;
top: -100px;
}
Demo here