I've been having issues scaling the inline SVG, in order to clip-path it in CSS, in the example to the container of the image that I'm trying to show.
I've seen the other similar questions with solutions but they still don't work as intended:
<style>
.cutR{
clip-path: url(#cutR)
}
.blogMainArticleMedia{
float:left;
width:100%
}
.image{
float:left;
display:block;
width:100%
}
</style>
<div class="blogMainArticleMedia cutR">
<img src="https://images.pexels.com/photos/459225/pexels-photo-459225.jpeg" alt="image" class="image">
</div>
<svg width="0" height="0" preserveAspectRatio="none">
<defs>
<clipPath id="cutR" clipPathUnits="objectBoundingBox">
<path d="M0,0c1.45,81.4 320,80 320,80l320,0l320,0c0,0 320,0.62 320,80c0,105.84 0,400 0,400c-1.45,81.4 -320,80 -320,80l-640,0c-171.919,0.239 -319.7,-0.491 -320,80l0,-720Z"
style="fill:none;" />
</clipPath>
</defs>
</svg>
https://codepen.io/thepra/pen/wNdpXW
They suggest to scale the coordinates of the path to a range between 0 and 1, but I can't find any software option(Affinity Designer) or online tool to do such thing.
Did anyone solved this scaling issue?
ps: here's the shape of the path
You don't need to do anything to the coordinates of the path. Instead, just transform the scale of the <clipPath>.
The path you want to use as your clipPath is 1280 x 670, so just apply the equivalent scale (1/1280, 1/670). This gives:
transform="scale(0.00078125, 0.001492537313433)"
This along with clipPathUnits="objectBoundingBox" means that you can use this shape to clip at any size or aspect ratio.
.cutR {
clip-path: url(#cutR)
}
.blogMainArticleMedia {
float: left;
width: 100%
}
.image {
float: left;
display: block;
width: 100%
}
<div class="blogMainArticleMedia cutR">
<img src="https://images.pexels.com/photos/459225/pexels-photo-459225.jpeg" alt="image" class="image">
</div>
<!-- Viewbox has no effect -->
<svg viewBox="0 0 1280 670">
<defs>
<clipPath transform="scale(0.00078125, 0.001492537313433)" id="cutR" clipPathUnits="objectBoundingBox">
<path d="M0 0C1.45 75.8834 320 74.5783 320 74.5783H960C960 74.5783 1280 75.1563 1280 149.157V522.048C1278.55 597.932 960 596.627 960 596.627H320C148.081 596.849 0.3 596.169 0 671.205V0Z"/>
</clipPath>
</defs>
</svg>
Codepen
Related
I've got little problem resizing my svg clip-path to fit the image size.
I've got code like this:
<svg id="image-svg" class="clip">
<img class="main-img" src="http://25.media.tumblr.com/tumblr_m5nre6cxkQ1qbs7p5o1_r1_500.jpg" alt="" />
</svg>
<svg class="clip">
<clipPath id="clipPolygon">
<polygon points="52 0,100 45,50 100,0 50">
</polygon>
</clipPath>
</svg>
And then i'm using css like this:
#image-svg {
left:0;
top:0;
}
.main-img {
clip-path: url('#clipPolygon');
width:90%;
}
Everything works fine, except the clip-path is much smaller then image itself. How to fix this? Here is my working fiddle:
https://jsfiddle.net/7egbccpw/
A solution is to specify the path directly with CSS and use % for the values
.main-img {
clip-path: polygon(50% 0%, 100% 45%, 50% 100%, 0 50%);
}
<img class="main-img" src="https://lorempixel.com/200/200/" alt="" />
<img class="main-img" src="https://lorempixel.com/100/100/" alt="" />
<img class="main-img" src="https://lorempixel.com/50/50/" alt="" />
Firstly, your example is broken because there is no <img> element in SVGs. You want the <image> element.
#image-svg {
left:0;
top:0;
}
.main-img {
clip-path: url('#clipPolygon');
width:90%;
}
<svg id="image-svg" class="clip">
<image class="main-img" xlink:href="http://25.media.tumblr.com/tumblr_m5nre6cxkQ1qbs7p5o1_r1_500.jpg" alt="" />
</svg>
<svg class="clip">
<clipPath id="clipPolygon">
<polygon points="52 0,100 45,50 100,0 50"></polygon>
</clipPath>
</svg>
Now I presume you mean you want the clip path to automatically fit the image size. Otherwise I am guessing you would have just made the clip path coordinates bigger.
The way you do that in SVG is to use objectBoundingBox coordinates. When objectBoundingBox coordinate mode in in effect, coordinates are scaled so that (0,0) represents the top left of the target element, and (1,1) represents the bottom right of the target element. In this case, the target element is the image.
For use this mode for clip paths, you need to set clipPathUnits="objectBoundingBox". Then you just need to scale all your polygon coordinate values so that the are between 0 and 1.
#image-svg {
width: 500px;
height: 500px;
}
.main-img {
clip-path: url('#clipPolygon');
width:90%;
height: 90%;
}
<svg id="image-svg" class="clip">
<image class="main-img" xlink:href="http://25.media.tumblr.com/tumblr_m5nre6cxkQ1qbs7p5o1_r1_500.jpg" alt="" />
</svg>
<svg class="clip">
<clipPath id="clipPolygon" clipPathUnits="objectBoundingBox">
<polygon points="0.52 0 1 0.45 0.5 1 0 0.5"></polygon>
</clipPath>
</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>
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
The task
I'm trying to have an image which is the full height of the screen, and clipped with an SVG mask, which is also full height.
The problem
Although the image is full height, the SVG clipping is always the same size and will not resize to the full height of the image.
I've read about using: clipPathUnits="objectBoundingBox"
on the clipPath, but this seems to break it further.
CSS:
img {
position: absolute;
clip-path: url(#path);
-webkit-clip-path: url(#path);
width: 100%;
height: 100%;
}
HTML:
<div>
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg" version="1.1" preserveAspectRatio="xMidYMid meet" viewBox="0 0 200 440">
<defs>
<clipPath id="path">
<path d="m54.3,1c64,1 89.3,85 89.8,85.6c1,0.4 7,37 19,53.7c11.8,16.6 30.7,28.5 35,33.8c4.3,6 9,8 4.8,17s-18.8,7 -24.8,20c-6,13.7 7.5,11 8.6,22c1,11 -31.2,14 -29.6,27c1.4,13 22.4,12 24,23c1.5,11.6 -9,10 -13,18c-3.8,8 15.6,20 5,38c-11,18.5 -57.7,7 -84,32.5c-26.4,25.3 -35.5,70 -34.4,70.4c1,0.4 -64,3 -61.8,-1c2.1,-4 -4.9,-440 2.1,-440s-4.6,-1 59.4,0l-0.1,0z"/>
</clipPath>
</defs>
<img src="https://upload.wikimedia.org/wikipedia/commons/0/05/20100726_Kalamitsi_Beach_Ionian_Sea_Lefkada_island_Greece.jpg">
</svg>
</div>
jsFiddle showing problem - https://jsfiddle.net/kjnovege/1/
Is there any way to achieve this?
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