clip-path url fails to find id - css

I have an SVG that I am trying to use to clip a div, but the id I give to the <clipPath> tag does not work.
I have tried changing the ID, and have made sure that the SVG does indeed exist in the same file, and the ID is visible.
The svg is like so:
<svg id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 149.559">
<defs>
<clipPath id="clipper">
<g id="svgg" stroke="none" fill-rule="evenodd">
<path id="path0" d= .../>
<path id="path1" d= .../>
<path id="path2" d= .../>
<path id="path3" d= .../>
<path id="path4" d= .../>
</g>
</clipPath>
</defs>
</svg>
I added the <defs> and <clipPath> tag so I could use the svg I had as a clipping mask.
The html element being used is:
<div class="logo-bg" style="clipPath: url(#clipper)"></div>
the div does have a width and height.
Within developer tools, the css property of the div I am trying to clip with clip-path: url(#clip-id) shows "could not load the image". Ideally I would be able to clip the div with the SVG.
here's the code I am working with: https://jsfiddle.net/mzLtsqva/6/
I am new to working with SVGs and so would appreciate any help to solve this issue.

Inside the <clipPath> don't wrap the paths in a group element.
In the next example I'm using a clipping path that is not working: #no and one that is working: #yes. In the one that is not working I'm wrapping the elements inside in a <g> element.
svg{border:1px solid;}
<svg width="250" height="250" viewBox="0 0 250 250" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<rect id="rect" x ="0" y ="0" height ="150" width ="70" style ="stroke:#000;" transform="translate(90, 50)"/>
<clipPath id="no">
<g>
<use xlink:href="#rect" fill="none"></use>
<use xlink:href="#rect" fill="none" transform="rotate(60 125 125)"></use>
<use xlink:href="#rect" fill="none" transform="rotate(-60 125 125)"></use>
</g>
</clipPath>
</defs>
<image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg" height="250" width="250" x="-15" y ="50" clip-path="url(#no)"></image>
</svg>
<svg width="250" height="250" viewBox="0 0 250 250" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<clipPath id="yes">
<use xlink:href="#rect" fill="none"></use>
<use xlink:href="#rect" fill="none" transform="rotate(60 125 125)"></use>
<use xlink:href="#rect" fill="none" transform="rotate(-60 125 125)"></use>
</clipPath>
</defs>
<image xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/beagle400.jpg" height="250" width="250" x="-15" y ="50" clip-path="url(#yes)"></image>
</svg>

Related

Center SVG in its viewport

I have the following SVG:
<svg width="15px" height="18px" viewBox="0 0 15 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Shape</title>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="question-controls" transform="translate(-52.000000, -1.000000)" fill="#72758D" fill-rule="nonzero">
<path d="M62,1 L54,1 C52.9,1 52,1.9 52,3 L52,13 L54,13 L54,3 L62,3 L62,1 Z M65,5 L58,5 C56.9,5 56,5.9 56,7 L56,17 C56,18.1 56.9,19 58,19 L65,19 C66.1,19 67,18.1 67,17 L67,7 C67,5.9 66.1,5 65,5 Z M65,17 L58,17 L58,7 L65,7 L65,17 Z" id="Shape"></path>
</g>
</g>
</svg>
It is a "Duplicate Icon" from Material IO.
https://material.io/resources/icons/?search=duplicat&icon=content_copy&style=baseline
However, as can you see it is not centered in its view port.
I tried by giving the same viewBox value like viewBox="0 0 100 100" with little success.

Get left and top of a text element inside an SVG?

I want to get the (top, left) coordinate of the text element relative to the svg element, expressed in the same unit/greatness as the y and x attributes of the text element.
I think that the example below is close, but there is a problem. getBoundingClientRect returns different values for top, left as the view port size changes, while of course the y, x attribute values of the text element are always the same. Thus the unit/greatness of top, left and y, x does not match.
I tried setting display: flex on the body to force the svg to not scale, but then it got the size 0 x 0.
const svgRect = document.querySelector("svg").getBoundingClientRect()
const textRect = document.querySelector("text").getBoundingClientRect()
const textBoxPosRelativeToSvgExpressedInSvgCoordinates = {top: textRect.y - svgRect.y, left: textRect.x - svgRect.x}
console.log(textBoxPosRelativeToSvgExpressedInSvgCoordinates)
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 400">
<g id="main">
<line x1="10" y1="10" x2="100" y2="200" stroke="#00c" stroke-width="5" stroke-linecap="round"/>
<polyline points="580,10 560,390 540,200 520,390 400,390" stroke="#c00" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
<polygon points="350,75 379,161 469,161 397,215 423,301 350,250 277,301 303,215 231,161 321,161" stroke="#ff0" stroke-width="10" fill="#ffc"/>
<rect x="100" y="10" width="150" height="100" rx="10" ry="20" stroke="#060" stroke-width="8" fill="#0f0"/>
<circle cx="100" cy="300" r="80" stroke="#909" stroke-width="10" fill="#f6f"/>
<ellipse cx="450" cy="50" rx="80" ry="30" stroke="#0cc" stroke-width="10" fill="#0ff"/>
<text x="240" y="390" font-family="sans-serif" font-size="50" fill="#00f">SVG</text>
</g>
</svg>
</body>

Fill SVG path with colour but on hover fade-in pattern

I am trying to add an SVG image (in this case a flag of Belgium) as the fill of an SVG path (actually an ellipse). On hover, the ellipse's fill has to transition into red. In other words, the fill SVG has to 'fade out'. I tried it in a way I'd do it with CSS, but neither the SVG pattern nor the transition seem to work. I tried on Chrome and Firefox.
svg ellipse {
fill: url(#img1);
transition: fill 400ms;
}
svg:hover ellipse {
fill: red;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" version="1.1" height="480" width="640" viewBox="0 0 640 480">
<defs>
<pattern x="0" y="0" id="img1" height="480" width="640" viewBox="0 0 640 480">
<g fill-rule="evenodd" stroke-width="1pt">
<path d="M0 0h213.335v479.997H0z" />
<path fill="#ffd90c" d="M213.335 0H426.67v479.997H213.335z" />
<path fill="#f31830" d="M426.67 0h213.335v479.997H426.67z" />
</g>
</pattern>
</defs>
<rect fill="none" stroke="blue" x="1" y="1" width="640" height="480"/>
<ellipse stroke="black" stroke-width="5" cx="400" cy="200" rx="350" ry="150" />
</svg>
You can't transition fill like that because the two fills are not something that can be interpolated smoothly between.
What you need to do is have two versions of the ellipse, one on top of the other. Then either fade in or out the top one.
.visible-on-hover {
transition: opacity 400ms;
opacity: 0;
}
.visible-on-hover:hover {
opacity: 1;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" version="1.1" height="480" width="640" viewBox="0 0 640 480">
<defs>
<pattern x="0" y="0" id="img1" height="1" width="1"
viewBox="0 0 640 480" preserveAspectRatio="xMidYMid slice">
<g fill-rule="evenodd" stroke-width="1pt">
<path d="M0 0h213.335v479.997H0z" />
<path fill="#ffd90c" d="M213.335 0H426.67v479.997H213.335z" />
<path fill="#f31830" d="M426.67 0h213.335v479.997H426.67z" />
</g>
</pattern>
</defs>
<rect fill="none" stroke="blue" x="1" y="1" width="640" height="480"/>
<ellipse stroke="black" stroke-width="5" cx="400" cy="200" rx="350" ry="150" fill="url(#img1)"/>
<ellipse stroke="black" stroke-width="5" cx="400" cy="200" rx="350" ry="150" fill="red" class="visible-on-hover"/>
</svg>

How to resize SVG clip-path?

I am using an SVG as a mask for an image and I'm trying to resize it. I tried indicating the width & height (to 100) but it still doesn't scale. Just remains the same size.
Codepen Demo
This is the SVG code:
<svg height="100" width="100">
<defs>
<clipPath id="svgPath">
<path fill="#EDEBEA" d="M468.855,234.292H244.117V9.439L468.855,234.292z" />
<path fill="#EDEBEA" d="M6.864,8.939h224.73v224.733L6.864,8.939z" />
<path fill="#EDEBEA" d="M244.118,469.73V245.005h224.737L244.118,469.73z" />
<path fill="#EDEBEA" d="M231.594,245.005V469.73H6.863L231.594,245.005z" />
</clipPath>
</defs>
</svg>
Firts, when you set the width and height attributes to 100, it makes the svg 100px high and wide. If you want the svg to be full width, you need to give it 100% width.
Second, as commented by #Paulie_D you need to give a value to the viewbox attribute to provide a scale and coordinate system for the elements in your svg. Here is an example with viewbox="0 0 500 500" and width="30%" :
<svg viewbox="0 0 500 500" width="30%" >
<defs>
<clipPath id="svgPath">
<path fill="#EDEBEA" d="M468.855,234.292H244.117V9.439L468.855,234.292z" />
<path fill="#EDEBEA" d="M6.864,8.939h224.73v224.733L6.864,8.939z" />
<path fill="#EDEBEA" d="M244.118,469.73V245.005h224.737L244.118,469.73z" />
<path fill="#EDEBEA" d="M231.594,245.005V469.73H6.863L231.594,245.005z" />
</clipPath>
</defs>
<image xlink:href="http://i.stack.imgur.com/3DR2G.jpg" x="0" y="0" height="500" width="500" style="clip-path: url(#svgPath);"/>
</svg>
Output :

Change color of SVG

I have some svg image like this
circles.svg
<svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" stroke="#fff">
<g fill="none" fill-rule="evenodd">
<g transform="translate(1 1)" stroke-width="2">
<circle stroke-opacity=".5" cx="18" cy="18" r="18"/>
<path d="M36 18c0-9.94-8.06-18-18-18">
<animateTransform
attributeName="transform"
type="rotate"
from="0 18 18"
to="360 18 18"
dur="1s"
repeatCount="indefinite"/>
</path>
</g>
</g>
</svg>
And use it like this
<img src="circles.svg" width="50" alt=""/>
But i dont know how to change color
I have tried
.color{
fill:red;
}
<img src="circles.svg" width="50" alt="" class="color"/>
But it does not work, i dont want to change SVG i want only to change color by html, is that possible, not to edit primary SVG?
CSS does not apply across document boundaries. Since your SVG is in a different document, you cannot affect it's style using CSS in your HTML.
You would need to inline the SVG in your HTML file.
Try this Link
HTML
<div>
<svg width="38" height="38" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" stroke="#fff">
<g fill="none" fill-rule="evenodd">
<g transform="translate(1 1)" stroke-width="2">
<circle stroke-opacity=".5" cx="18" cy="18" r="18"/>
<path d="M36 18c0-9.94-8.06-18-18-18">
<animateTransform
attributeName="transform"
type="rotate"
from="0 18 18"
to="360 18 18"
dur="1s"
repeatCount="indefinite"/>
</path>
</g>
</g>
</svg>
</div>
css
div {
color: blue;
}
div svg {
fill: currentColor;
}

Resources