Centering image inside SVG - html

Is there some easy solution to center image on X and Y inside SVG? I have to keep svg element with percentage.
svg {
width: 20%;
}
<svg version="1.1" id="Izolovaný_režim" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 294.7 320.3" xml:space="preserve">
<pattern id="img" patternUnits="userSpaceOnUse" width="100%" height="100%">
<image xlink:href="https://cdn-mf0.heartyhosting.com/sites/mensfitness.com/files/styles/wide_videos/public/1280-fit-man-work-desk.jpg?itok=xpQGNXMI" x />
</pattern>
<g>
<polygon points="147.4,320.3 294.7,235.2 294.7,85.1 147.4,0 0,85.1 0,235.2 " fill="url(#img)"/>
</g>
</svg>
Thank you. ;)

To center you image pattern in the polygon you can use the x and y attributes of the pattern to set the origin of the image.
So in your case you could set it to x="50%" y="50%"
svg {
width: 20%;
}
<svg version="1.1" id="Izolovaný_režim" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 294.7 320.3" xml:space="preserve">
<pattern id="img" patternUnits="userSpaceOnUse" width="100%" height="100%" x="50%" y="50%">
<image xlink:href="https://cdn-mf0.heartyhosting.com/sites/mensfitness.com/files/styles/wide_videos/public/1280-fit-man-work-desk.jpg?itok=xpQGNXMI" x />
</pattern>
<g>
<polygon points="147.4,320.3 294.7,235.2 294.7,85.1 147.4,0 0,85.1 0,235.2 " fill="url(#img)"/>
</g>
</svg>

Related

How do you scale an immutable SVG?

If I have a regular SVG element like this, but it is immutable as in you cannot clone, or change any parameters such as height and width. Is there any way to scale it?
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" height="42" width="350">
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg2" xml:space="preserve" x="30" y="0" width="80" height="65" viewBox="-200 400 1600 900">
<metadata>
...
</metadata>
<g>
...
</g>
</svg>
</svg>
If you have an SVG like this:
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" fill="orange"/>
</svg>
You can wrap it in another SVG element where the viewBox matches the size of the original SVG. Now, you can specify a size (width and/or height) or leave it out to make it fill the available space.
<svg xmlns="http://www.w3.org/2000/svg" width="200" viewBox="0 0 50 50">
<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" fill="orange"/>
</svg>
</svg>
You can do the same with the SVG as an external resource (here a data URI for the example) where the width and the height attributes of the image element matches the viewBox of the parent SVG element.
<svg xmlns="http://www.w3.org/2000/svg" width="200" viewBox="0 0 100 100">
<image width="100" height="100" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MCIgaGVpZ2h0PSI1MCIgdmlld0JveD0iMCAwIDEwMCAxMDAiPgogIDxjaXJjbGUgY3g9IjUwIiBjeT0iNTAiIHI9IjUwIiBmaWxsPSJvcmFuZ2UiLz4KPC9zdmc+" />
</svg>

In a svg shape divider fill with a background image

https://jsfiddle.net/4n7j5a1t/
I'm using a svg shape divider but how I can change the background color to a background image in the fill CSS property ?
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 120" preserveAspectRatio="none">
<path d="M600,112.77C268.63,112.77,0,65.52,0,7.23V120H1200V7.23C1200,65.52,931.37,112.77,600,112.77Z" class="shape-fill"></path>
</svg>
This is what I have tried so far but it does not keep the svg shape in place (wave):
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 120" preserveAspectRatio="none">
<defs>
<pattern id="imgpattern" x="0" y="0" width="1" height="1">
<image width="120" height="250"
xlink:href="https://example.com/slider-bg.png"/>
</pattern>
</defs>
<path d="M600,112.77C268.63,112.77,0,65.52,0,7.23V120H1200V7.23C1200,65.52,931.37,112.77,600,112.77Z" class="shape-fill" fill="url(#imgpattern)"></path>
</svg>
Thanks.
EDIT
You have to define the image and then add it as a fill.
You can read more about this here
I'm not sure if this is what you wanted but I hope it helps. If not try to explain a little more and I might be able to help you.
Cheers!
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 120" preserveAspectRatio="none">
<defs>
<pattern id="img1" patternUnits="userSpaceOnUse" width="600" height="450">
<image xlink:href="https://image.api.playstation.com/vulcan/img/rnd/202011/0714/vuF88yWPSnDfmFJVTyNJpVwW.png" x="0" y="0"
width="600" height="450" /><!-- Image from http://silviahartmann.com/background-tile/6-grass-meadow-tile.php-->
</pattern>
</defs>
<path fill="url(#img1")" d="M600,112.77C268.63,112.77,0,65.52,0,7.23V120H1200V7.23C1200,65.52,931.37,112.77,600,112.77Z" class="shape-fill"></path>
</svg>

How to draw svg on image?

I have a image, and i have cordinates (x1,y1),(x2,y2),(x3,y3),(x4,y4) to draw a svg/rectagle on image, how to draw?
I have tried using svg tag in img tag, but it does not work, the main thing is how to set width and height of svg(rect svg) using those cordinates.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" height="100%" viewBox="0 0 1055 717" preserveAspectRatio="xMinYMin meet" >
<rect x="540" y="134" width="150" height="100" fill="none" stroke="red" stroke-width="2" />
</svg>
If I understand correctly OP then so and look at the comments in the code.
<style>
.container {
width:100vw;
height:100vh;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 1055 717" preserveAspectRatio="xMinYMin meet" >
<!-- Add image -->
<image xlink:href="https://i.stack.imgur.com/ORJ3b.jpg" width="100%" height="100%" />
<!-- Add a red rectangle over the image. -->
<rect x="540" y="134" width="150" height="100" fill="none" stroke="red" stroke-width="2" />
<!-- Add text -->
<text x="550" y="200" font-size="48px" font-family="sans-serif" font-weight="700" fill="white" >TEST </text>
</svg>
</div>
UPDATE
If a square over the image is needed to focus on one or more fragments of the image, then
you can use it repeatedly but add individual tooltips <tooltip>
A tooltip pops up when you hover and hold the cursor on the red square
.container {
width:100vw;
height:100vh;
}
.rect {
fill:transparent;
stroke:red;
stroke-width:2;
}
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 1024 768" preserveAspectRatio="xMinYMin meet" >
<!-- Add image -->
<image xlink:href="https://i.stack.imgur.com/uOg10.jpg" width="100%" height="100%" />
<!-- Add a red rectangles over the image. -->
<g>
<!-- Tooltip pops up on hover -->
<title> Young lioness </title>
<rect class="rect" x="160" y="220" width="170" height="170" rx="15" />
</g>
<g>
<title> Young lion </title>
<rect class="rect" x="475" y="200" width="200" height="220" rx="15"/>
</g>
</svg>
</div>
You can consider using calc() and some CSS variables to find the width/height:
:root {
--x1:200;
--x2:100;
--x3:150;
--x4:200;
}
rect {
x:calc(var(--x1)*1px);
y:calc(var(--x2)*1px);
width:calc((var(--x1) + var(--x2))*1px);
height:calc((var(--x3) + var(--x4))*1px);
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" height="100%" viewBox="0 0 1055 717" preserveAspectRatio="xMinYMin meet" >
<rect fill="none" stroke="red" stroke-width="2" />
</svg>

fill SVG path with pattern without stretching

I'm trying to use edit this example and fill the wave with a pattern
<svg id="shape-overlays" class="shape-overlays" viewBox="0 0 100 100" preserveAspectRatio="none">
<defs>
<pattern id="img4" patternUnits="userSpaceOnUse" width="180" height="180">
<image xlink:href="./pattern/menu-3.png" x="0" y="0" width="180" height="180" />
</pattern>
</defs>
<path class="shape-overlays__path"></path>
<path class="shape-overlays__path"></path>
<path class="shape-overlays__path"></path>
<path class="shape-overlays__path"></path>
</svg>
CSS
.shape-overlays__path:nth-of-type(4) {
fill: url(#img4);
stroke: red;
stroke-width: 1;
}
the SVG path is filled with pattern image but isn't repeated and is also stretched
I would like to have it repeated as a pattern, if is not possible I would like to use a big image as cover but keeping proportion
to solve the issue I changed preserveAspectRatio to "xMidYMid slice" instead of "none"
<svg id="shape-overlays" class="shape-overlays" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice" >

Animate height of SVG without changing proportions of background image

I'm trying to create an accordion using SVG shapes, I am using SVGs because my sections do not have regular shapes.
I created this shape using SVG clipPath
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1276.4 270" style="enable-background:new 0 0 1276.4 270;">
<style type="text/css">
.st0{display:none;clip-path:url(#XMLID_111_);}
.st1{display:inline;}
</style>
<g id="XMLID_5_">
<defs>
<path id="XMLID_1_" d="M414.5,2.2c-27.6,1.7-55.2,2.9-82.7,0.9c-10.7,0.4-21.4,0.9-32.1,1.5c-33.9,1.8-67.8,5-101.7,5.8
C163.7,11.2,129.3,10.1,95,9c-31.7-1-63.3-2.1-95-1.6v126.3l0.2,121.8c160.1-23.4,321.4-2.1,482.2,4.8c86.7,3.7,173.1,0,259.5-7.6
c42.7-3.7,85.1-9.3,128-7.3c44.5,2.1,88.7,8.5,132.8,14.5c25,3.3,50,6.4,75.2,8.3c27.5,2,55,2,82.6,1.5c39-0.7,78-2.6,116.9-6.1
V137.8l-0.2-126.1c-7.6,0.2-15.3,0.1-23-0.3c-20.8-1-41.6-3-62.5-3.6c-43.4-1.3-86.8-0.8-130.2-2c-43.7-1.1-87.3-3.1-131-2.3
c-43.1,0.8-86.1,3.2-129.2,4.7c-43.6,1.5-87.1,1.8-130.7-0.1c-43.7-1.9-87.2-5-130.9-6.9C521.9,0.4,504.1,0,486.4,0
C462.5,0,438.5,0.7,414.5,2.2"/>
</defs>
<use xlink:href="#XMLID_1_" style="overflow:visible;fill:#525252;"/>
<clipPath id="shape_1">
<use xlink:href="#XMLID_1_" style="overflow:visible;"/>
</clipPath>
</g>
<image clip-path="url(#shape_1)" width="2000" height="1700" xlink:href="dummy_url.jpg" preserveAspectRatio="xMidYMin slice"></image>
</svg>
When you click on a section it should expand in height. My problem is that I can't change the height of the SVG without ruining the background image's proportions. If there is an alternative to using SVGs in this situation I would be open to it, thank you very much.
Have you thought of using the image(s) as fill for your svg elements instead of image?
Some junk code for this type of pattern would look something like this:
<rect x="-50" width="100%" height="100%" style="max-width=950px" fill="url(#your-id)" rx="6" ry="6" id="background-panel"/>
<defs>
<pattern id="your-id" patternUnits="userSpaceOnUse" x="120" y="170" width="650" height="547">
<image xlink:href="dummy_url.jpg" width="650" height="547" opacity="1"/>
</pattern>
</defs>
that way you can change the size of the path (in this case, the rect) and it won't change the size/proportions of the image, it will just reveal more of it.
I managed to do it by creating one svg:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 2315.2 989" style="enable-background:new 0 0 2315.2 989;" xml:space="preserve">
<style type="text/css">
.st0{clip-path:url(#XMLID_45_);fill-rule:evenodd;clip-rule:evenodd;fill:#913B58;}
</style>
<g id="XMLID_30_">
<g id="XMLID_31_">
<defs>
<rect id="XMLID_2_" x="1.5" width="2313.9" height="987.8"/>
</defs>
<clipPath id="shape_1">
<use xlink:href="#XMLID_1_" style="overflow:visible;"/>
</clipPath>
<path id="XMLID_1_" class="st0" d="M875.1,970.2c157.1,6.7,313.5-0.1,470-13.8c77.3-6.8,154.1-16.8,231.8-13.2
c80.6,3.7,160.6,15.5,240.5,26.3c45.2,6,90.6,11.7,136.1,15c49.8,3.7,99.7,3.7,149.6,2.8c70.8-1.3,141.6-4.7,212.1-11.1l-0.4-955
c-13.8,0.3-27.7,0.1-41.7-0.5c-37.7-1.8-75.4-5.5-113.1-6.6c-78.6-2.3-157.3-1.5-235.9-3.6c-79.1-2.1-158.2-5.6-237.3-4.2
c-78,1.4-155.9,5.7-233.9,8.5c-78.9,2.8-157.7,3.2-236.6-0.2c-79.1-3.4-158-9.1-237-12.5c-75.9-3.3-151-2.8-226.8,1.9
c-50,3.1-100.1,5.2-149.8,1.6c-19.4,0.8-38.7,1.7-58.1,2.7c-61.4,3.3-122.8,9-184.2,10.5c-119.7,2.9-239.3-7.3-359-5.4l0.4,948.1
C291.8,919.2,583.9,957.8,875.1,970.2"/>
</g>
</g>
</svg>
I created a div for each year containing an image container
<div class="year">
<div class="image-container" style="background-image: url(<?php the_sub_field('image') ?>);"></div>
</div>
Then I specified the svg to the clip-path property of the image container in CSS
.image-container{
clip-path: url(#shape_1);
background-size: cover;
background-repeat: no-repeat;
padding-top: 40%;
background-position-y: 27%;
position: relative;
}
I partially overlapped the years so instead of trying to expand the year containers I just slide down all the years after the one clicked by using margin-top:
$('.year').each(function(){
var pYearIndex = $(this).index();
if(pYearIndex>1){
$(this).addClass('not-first');
}
var begin = 0;
var translated = (pYearIndex*(-3))+begin;
});
$('.year').on('click',function() {
var nYears = $('.year').length;
var thisYear = $(this).index();
if($(this).hasClass('to_show')){
$(this).removeClass('to_show');
$('.expanded').removeClass('expanded');
$('footer').css('margin-top', '-22%');
}
else{
$('.expanded').removeClass('expanded');
$('.to_show').removeClass('to_show');
$(this).addClass('to_show');
if(thisYear<nYears){
$('.year').eq(thisYear).addClass('expanded');
$('footer').css('margin-top', '-22%');
}
else{
$('footer').css('margin-top','-2%');
}
}
});