I have created a svg heart with an image as a pattern inside. I am trying to make it so the image fits the whole heart but I am not having much luck.
Any help would be great and hugely appreciated.
svg {
width: 300px;
border: 1px solid grey;
margin: 1em auto;
display: block;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 315 345">
<!-- START SVG RULES -->
<defs>
<!-- DEFINE IMAGE INSIDE PATTERN -->
<pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
<image xlink:href="https://images.pexels.com/photos/325185/pexels-photo-325185.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
x="0" y="0" width="100" height="100" />
</pattern>
<!-- SVG SHAPE CREATION -->
<g id="heart">
<path d="M0 200 v-200 h200
a100,100 90 0,1 0,200
a100,100 90 0,1 -200,0
z" />
</g>
</defs>
<use xlink:href="#heart" class="outline" fill="url(#img1)" />
</svg>
The simplest solution is to use patternContentUnits="objectBoundingBox" and set the image width and height to "1".
Then to make the image fill the pattern, set preserveAspectRatio="xMidYMid slice". This is equivalent to the CSS's background-size: cover
svg {
width: 300px;
border: 1px solid grey;
margin: 1em auto;
display: block;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 315 345">
<!-- START SVG RULES -->
<defs>
<!-- DEFINE IMAGE INSIDE PATTERN -->
<pattern id="img1" patternContentUnits="objectBoundingBox" width="100%" height="100%">
<image xlink:href="https://images.pexels.com/photos/325185/pexels-photo-325185.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260"
x="0" y="0" width="1" height="1" preserveAspectRatio="xMidYMid slice" />
</pattern>
<!-- SVG SHAPE CREATION -->
<g id="heart">
<path
d="M0 200 v-200 h200
a100,100 90 0,1 0,200
a100,100 90 0,1 -200,0
z" />
</g>
</defs>
<use xlink:href="#heart" class="outline" fill="url(#img1)" />
</svg>
Related
I am trying to change the mobile hamburger menu icon to fit the color of my logo when the mouse is over -
.menu-hamburger:hover {
fill: #FFB400!important;
}
<a href="#">
<svg class="menu-hamburger">
<use xlink:href="#menu-hamburger"></use>
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="menu-hamburger" class="menu-hamburger" viewBox="0 0 16 16" style="width: 16px; height: 16px; color:#FFF;">
<rect y="1" width="16" height="2"></rect>
<rect y="7" width="16" height="2"></rect>
<rect y="13" width="16" height="2"></rect>
</symbol>
</defs>
</svg>
</a>
but still no luck
When using <use xlink:href="#" , the SVG content falls into the DOM shadow and the styling result depends on the style hierarchy of the external, internal CSS style sheet, SVG presentation styles
What will be the result of the struggle of these styles is not always easy to foresee..
Therefore, in the adjacent answer, the rule fill: #FFB400!important;
But this is a very bad practice that can break the rest of the layout.
The style hierarchy can be seen in the image below from the article: By Sara Soueidan Styling SVG Content with CSS
Computed Styles has the biggest weight.
Therefore, it is most reliable to use CSS variables for CSS styling.
.menu-hamburger {
margin:1em;
}
#u1,#u2 {
fill:black;
}
#u1:hover {
--primary-color: red;
cursor:pointer;
}
#u2:hover {
--primary-color: green;
}
<a href="#">
<svg class="menu-hamburger" width="64" height="64" viewBox="0 0 16 16" >
<use id="u1" xlink:href="#menu-hamburger" ></use>
</svg>
<svg class="menu-hamburger" width="64" height="64" viewBox="0 0 16 16" >
<use id="u2" xlink:href="#menu-hamburger" ></use>
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="0" height="0" viewBox="0 0 16 16">
<symbol class="menu-hamburger">
<g id="menu-hamburger" style="fill: var(--primary-color, black)">
<rect width="100%" height="100%" fill="transparent" />
<rect y="1" width="16" height="2"></rect>
<rect y="7" width="16" height="2"></rect>
<rect y="13" width="16" height="2"></rect>
</g>
</symbol>
</svg>
UPDATE
By applying CSS variables you can implement multi-color icons
.menu-hamburger {
margin:1em;
}
#u1,#u2 {
fill:black;
}
#u1:hover {
--primary-color: green;
--second-color: gold;
--third-color: red;
cursor:pointer;
}
#u2:hover {
--primary-color: purple;
--second-color: greenyellow;
--third-color: dodgerblue;
}
<a href="#">
<svg class="menu-hamburger" width="96" height="96" viewBox="0 0 16 16">
<use id="u1" xlink:href="#menu-hamburger" ></use>
</svg>
</a>
<a href="#">
<svg class="menu-hamburger" width="64" height="64" viewBox="0 0 16 16" >
<use id="u2" xlink:href="#menu-hamburger" ></use>
</svg>
</a>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="0" height="0" viewBox="0 0 16 16">
<defs>
<symbol class="menu-hamburger">
<g id="menu-hamburger" style="fill: var(--primary-color, black)">
<rect width="100%" height="100%" fill="transparent" />
<rect y="1" width="16" height="2" style="fill: var(--primary-color)"></rect>
<rect y="7" width="16" height="2" style="fill: var(--second-color)"></rect>
<rect y="13" width="16" height="2" style="fill: var(--third-color)"></rect>
</g>
</symbol>
</defs>
</svg>
Try this.
svg.menu-hamburger :hover {
fill: #FFB400!important;
}
<a href="#">
<svg class="menu-hamburger">
<use xlink:href="#menu-hamburger"></use>
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="menu-hamburger" class="menu-hamburger" viewBox="0 0 16 16" style="width: 16px; height: 16px; color:#FFF;">
<rect y="1" width="16" height="2"></rect>
<rect y="7" width="16" height="2"></rect>
<rect y="13" width="16" height="2"></rect>
</symbol>
</defs>
</svg>
</a>
In this example I changed the <a> to a <button> because the action of clicking it is not navigating somewhere but opening a menu. It has the same properties. Controlling the width and the height of the menu is done using the button#menu-hamburger svg selector together with the fill color. So, now using a similar selector (button#menu-hamburger:hover svg) for hover the menu changes color without problem. I added the hover to the button so that you also "hover" when the pointer is in between the bars in the hamburger menu.
button#menu-hamburger {
display: block;
border: none;
background: transparent;
}
button#menu-hamburger svg {
fill: #000;
width: 16px;
height: 16px;
}
button#menu-hamburger:hover svg {
fill: #FFB400;
}
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0" display="none">
<defs>
<symbol id="menu-hamburger" viewBox="0 0 16 16">
<rect y="1" width="16" height="2"></rect>
<rect y="7" width="16" height="2"></rect>
<rect y="13" width="16" height="2"></rect>
</symbol>
</defs>
</svg>
<button id="menu-hamburger">
<svg xmlns="http://www.w3.org/2000/svg">
<use href="#menu-hamburger"/>
</svg>
</button>
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>
I have a nested SVG with 3 elements. 2 triangles that are positioned at the right-left sides and one line in the middle. I would like to obtain a responsive line (line should only have the width available between the triangles), both when resizing horizontally and vertically. I have tried setting the width in percentage but in only works when resizing horizontally. When I am resizing vertically it doesn't work because the width of the triangles changes. Here is a codepen link: https://codepen.io/roppazvan/pen/dyyPKKL?editors=1100
<svg
class='input-source'
stroke='black'
stroke-width='0'
fill="black">
<rect x="20" y="20%" width="100%" height="60%"
stroke='black'
stroke-width='0'
>
</rect>
<!-- The right head -->
<svg class='head input-source' id='right'
height="100%"
width='100%'
viewBox="0 0 20 40"
preserveAspectRatio="xMaxYMid"
>
<rect width="100%" height="100%"/>
</svg>
<!-- The left head -->
<svg class='head input-source' id='left'
height="100%"
width='100%'
viewBox="0 0 15 30"
preserveAspectRatio="xMinYMid"
>
<rect width="100%" height="100%"/>
</svg>
</svg>
</svg>
<svg width="110px" height="40px" version="1.0" state='normal'>
<svg
class='input-source'
stroke='black'
stroke-width='0'
fill="black">
<rect x="20" y="20%" width="100%" height="60%"
stroke='black'
stroke-width='0'
>
</rect>
<!-- The right head -->
<svg class='head input-source' id='right'
height="100%"
width='100%'
viewBox="0 0 20 40"
preserveAspectRatio="xMaxYMid"
>
<rect width="100%" height="100%"/>
</svg>
<!-- The left head -->
<svg class='head input-source' id='left'
height="100%"
width='100%'
viewBox="0 0 15 30"
preserveAspectRatio="xMinYMid"
>
<rect width="100%" height="100%"/>
</svg>
</svg>
</svg>
The simplest and easiest approach to implement and understand, is probably to just use flex-box.
#svg-container {
margin-top: 100px;
width: 100%;
border: 1px solid #bada55;
display: flex;
flex-direction: row;
}
svg {
height: 10vh;
}
/* stretch the middle box */
svg:nth-child(2) {
flex: 1;
}
<div id="svg-container">
<!-- left head -->
<svg viewBox="0 0 14 14" preserveAspectRatio="xMinYMid" opacity="0.5">
<polygon points="0,7 14,0 14,14 " />
</svg>
<!-- line -->
<svg viewBox="0 0 14 14" preserveAspectRatio="none">
<rect y="30%" width="100%" height="40%" />
</svg>
<!-- right head -->
<svg viewBox="0 0 14 14" preserveAspectRatio="xMaxYMid" opacity="0.5">
<polygon points="14,7 0,0 0,14 "/>
</svg>
</div>
I have the following system:
<html>
<head>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3000 3000">
<defs>
<symbol id="triangle" viewBox="0 0 100 100">
<polygon points="0,100 50,0 100,100" class="triangle" />
</symbol>
<symbol id="tree" viewBox="0 0 100 100">
<use href="#triangle" width="100" height="100" />
</symbol>
</defs>
<use href="#tree" width="200" height="400" x="1000" />
<use href="#tree" width="100" height="100" x="1100" />
</svg>
</body>
</html>
For the following:
<use href="#tree" width="200" height="400" x="1000" />
I would expect it to be a triangle that's twice the height as the width (200x400). But it just ends up being a random size that is proportional to the original 100x100 triangle.
Wondering how to get this to scale/squish the image so I can use use in multiple times and have it show different height trees all with the same width.
Same with making a #rect symbol that you can size with any width/height and it creates an appropriately shaped rectangle. If I try the following it just shows a square.
<symbol id="rect" viewBox="0 0 100 100">
<rect width='100' height='100' />
</symbol>
<use href="#rect" width="400" height="300" x="1300" y="1000" />
Add preserveAspectRatio="none" to your symbol elements.
<html>
<head>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3000 3000">
<defs>
<symbol id="triangle" viewBox="0 0 100 100" preserveAspectRatio="none">
<polygon points="0,100 50,0 100,100" class="triangle" />
</symbol>
<symbol id="tree" viewBox="0 0 100 100" preserveAspectRatio="none">
<use href="#triangle" width="100" height="100" />
</symbol>
<symbol id="rect" viewBox="0 0 100 100" preserveAspectRatio="none">
<rect width='100' height='100' />
</symbol>
</defs>
<use href="#tree" width="200" height="400" x="1000" />
<use href="#tree" width="100" height="100" x="1100" />
<use href="#rect" width="400" height="300" x="1300" y="1000" />
</svg>
</body>
</html>
I have created an svg heart with a background image inside.
I'm trying to make the svg larger, but changing the width and height on both the pattern and the svg itself does not work.
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" height="315" width="345" >
<!-- START SVG RULES -->
<defs>
<!-- DEFINE IMAGE INSIDE PATTERN -->
<pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
<image xlink:href="https://images.pexels.com/photos/325185/pexels-photo-325185.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260" x="0" y="0" width="100" height="100" /></pattern>
<!-- SVG SHAPE CREATION -->
<g id="heart">
<path
d="M0 200 v-200 h200
a100,100 90 0,1 0,200
a100,100 90 0,1 -200,0
z" />
</g>
</defs>
<use xlink:href="#heart" class="outline" fill="url(#img1)" />
</svg>
For a resizable SVG use viewBox="0 0 315 345"instead height="315" width="345"
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" viewBox="0 0 315 345" >
<!-- START SVG RULES -->
<defs>
<!-- DEFINE IMAGE INSIDE PATTERN -->
<pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
<image xlink:href="https://images.pexels.com/photos/325185/pexels-photo-325185.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260" x="0" y="0" width="100" height="100" /></pattern>
<!-- SVG SHAPE CREATION -->
<g id="heart">
<path
d="M0 200 v-200 h200
a100,100 90 0,1 0,200
a100,100 90 0,1 -200,0
z" />
</g>
</defs>
<use xlink:href="#heart" class="outline" fill="url(#img1)" />
</svg>
Click the resize button to see if this is what you need.
https://jsfiddle.net/gbxquc05/29/
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="100%" height="100%" preserveAspectRatio="none" viewBox="0 0 400 400">
Drawing paths in SVG is unfortunately limitted to absolute units. This is a workaround using viewBox to create coordinate system that transforms to percentage.