Newbie to working with SVGs and I've run into a problem. Basically I'm using the Noun Project API pro version ( https://api.thenounproject.com/ ) to scrape icons as SVGs. Right now, I save the SVGs in a local folder. I want to be able to change the color of the icon (right now they download as black, and I want to change the color). I am loading the SVGs via the tag with a reference to the folder where the SVGs are being saved. I know it's fairly simple to change the color using vanilla JS (using document.getElementById('svgObject').contentDocument, and then accessing the inner document using a unique id). The problem is that the SVGs I save don't have any ID, and I don't know how to give them an ID. Right now, I'm looping through the folder and displaying the folder contents in a webpage. That's all working fine, but I can't manage to figure out how to change the color.
Basically, I just want all the icons in the folder to be set to a different color (for example, they could all be set to "red." They don't need to each have a different color). How do I do that without specifying the actual ID (since the SVG doesn't include an ID upon download), or else how do I add an ID to the SVG tag itself?
Assuming you have a bunch of svgs on your page and you'd like to change the color of each to the same color, you could do the following:
function changeSvgColors() {
const svgs = document.getElementsByTagName('svg')
for (let i = 0; i < svgs.length; i++) {
svgs[i].setAttribute('fill', 'red')
}
}
This will loop through every svg on your page and set their fill attribute to red.
Essentially, this is equivalent to doing this:
<svg viewBox="0 0 512 512" fill="red">
...
</svg>
Here's a quick demo:
JSFiddle
Alternatively, if you're using something like the img tag to load your svgs onto your page, using object instead would let you do the same thing as above.
Assuming your html looks like the following:
<div>
<object
data="http://localhost:5000/image.svg"
type="image/svg+xml"
></object>
</div>
Then,
function changeSvgColors() {
const objects = document.getElementsByTagName('object')
for (let i = 0; i < objects.length; i++) {
const object = objects[i]
const svg = object.contentDocument.rootElement
svg.setAttribute('fill', 'red')
}
}
One option would be using the svg as an image (or as an object if you prefer) and filters to change the color.
#theImage{filter: invert(27%) sepia(51%) saturate(2878%) hue-rotate(346deg) brightness(104%) contrast(97%);}
<img id="theImage" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/bone300.svg" >
Please read this article: Solved with CSS! Colorizing SVG Backgrounds
Yet another option is using the svg as a mask. Keep in mind that the support for mask is not that good.
#theDiv{
display: inline-block;
width:300px;
height:134px;
-webkit-mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/bone300.svg);
mask: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/222579/bone300.svg);
mask-size: cover;
background:red;
}
<div id="theDiv"></div>
But the best option would be to use the svg inline. You may save all your icons in a root svg element with width="0"; height="0"; position="absolute". Next you can use the icons with <use> and you change the color using the fill attribute <use fill="red" xlink:href="..... or styling it in CSS
You can give the SVGs a class instead of an id & set the color using javascript's getElementsByClassName
This Mozilla article explains:
https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
Your best shot in achiveing this is to make use of the fill attibute for svg elements. Now, you can work this out two ways
Method 1:
Using img tag like this <img src="your_file.svg" />. In this case, you will need to edit the file directly, and that's it, it should reflect everywhere you reference the svg.
Method 2:
You can use svg as inline like below. The advantage in this approach is that if you have varying instance of the same svg, then this is the way to go. On the other side, if your svg stays same throughout the app, this goes against the DRY principle.
svg {
max-width: 200px;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path d="M25,7l28,36l40-18l-36,25l19,44l-27-37l-41,17l36-26z" fill="#cfc"/>
<ellipse cx="50" cy="50" rx="32" ry="30" stroke="#fc0" fill="none" stroke-width="11"/>
<path d="M63,2l-7,43l42,17l-45-6l-16,42l7,-45l-42-16l45,6z" fill="#3cc"/>
</svg>
If you don't mind having the svg all one color, you could set the fill attribute of the svg to currentcolor. Then it will take on the color of the element that it is in.
#span1 {
color: red;
}
#span2 {
color: blue;
}
#span3 {
color: green;
}
<body>
<span id=span1>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="150" height="150" fill-rule="evenodd" fill="currentcolor">
<title>HTML5 Logo</title>
<path d="M12,0 188,0 172,180 100,200 28,180Z M45,37 156,37 154,59 69,59 71,81 152,81 146,149 100,162 54,149 52,114 74,114 76,132 100,139 124,132 127,103 51,103Z"/>
</svg>
</span>
<span id=span2>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="150" height="150" fill-rule="evenodd" fill="currentcolor">
<title>HTML5 Logo</title>
<path d="M12,0 188,0 172,180 100,200 28,180Z M45,37 156,37 154,59 69,59 71,81 152,81 146,149 100,162 54,149 52,114 74,114 76,132 100,139 124,132 127,103 51,103Z"/>
</svg>
</span>
<span id=span3>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="150" height="150" fill-rule="evenodd" fill="currentcolor">
<title>HTML5 Logo</title>
<path d="M12,0 188,0 172,180 100,200 28,180Z M45,37 156,37 154,59 69,59 71,81 152,81 146,149 100,162 54,149 52,114 74,114 76,132 100,139 124,132 127,103 51,103Z"/>
</svg>
</span>
</body>
Essentially I needed to make the center "cut-out" keep a fixed shape and size regardless of vector scale. Is there a way to achieve this?
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="none" style="fill-rule:evenodd;" viewBox="0 0 2802 2657">
<path d="M290 4c-95,733 -191,1466 -286,2200 760,150 1520,300 2279,450 172,-223 343,-446 515,-669 -114,-572 -229,-1144 -343,-1716 -722,-88 -1444,-176 -2165,-264zm696 1027c-103,111 -205,222 -308,333 94,111 188,222 282,333 342,-205 684,-410 1026,-616 -333,-17 -667,-34 -1000,-51z"/>
</svg>
So I managed to do something after some editing to your SVG.
To achieve what you're asking you'll need to use / have :
- the SVG mask attribute
- A very large shape for the mask ( as much large as the max scale you want to use on the visible shape )
- The shape that you want to resize
- Resize the shape with transforms
Your SVG should looks like the following
<svg>
<defs>
<mask id="theMask">
<path fill="#ffffff" d=""/>
</mask>
</defs>
<g mask="url(#theMask)">
<path fill="#ffffff" id="shapetoresize" d=""/>
</g>
</svg>
I posted a pen as a "Proof of concept"
Feel free to fork it and use it to achieve what you're trying to do.
Codepen
note: as pointed out by #thioutp , The JS is only for demo purposes, you don't need GSAP to achieve this.
Can somebody help me with css and javascript?
I need to create a page with scroll animation.
https://meetlima.com/how-it-works.php?lang=en
The 1,2,3 must be filled with color.
<div class="container">
<div class="een">
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<g>
<title>Layer 1</title>
<text
stroke="#000000" transform="matrix(9.676384925842285,0,0,9.676384925842285,-1584.9315026253462,-1064.0772700458765) "
xml:space="preserve"
text-anchor="middle"
font-family="Fantasy"
font-size="24"
id="svg_1"
y="129.86676"
x="174.14887"
stroke-width="0"
fill="#bfbfbf">1</text>
</g>
</svg>
</div>
</div>
In fact on page you've shared as exapmle the svg numbers have transparent color.
Initially you see grey background of div.how-it-works__step__bg__inner.
On backface there is a div.how-it-works__faker which has fixed position and lowest z-index. Also has inner element div.how-it-works__faker__inner with blue background
And when you scrolling down you may see the part of div.how-it-works__faker__inner under svg image.
to make it more clear check this screen just to understand what would happens in case you set higher z-index for div.how-it-works__faker
screenshot
I have an SVG file that looks like below:
Is there a way to make the text transparent? That is, instead of a fill color I want to cut out the layers and show what's in the background (of the SVG i.e. whatever lies underneath the SVG). In other words, make the intersection of the path & text to be transparent?
Contents of the SVG file:
<svg width="36.087" height="34.314" viewBox="0 0 36.087 34.313999" x="1190.56" y="753.5780000000001">
<path fill="#63a95c" d="M36.087 13.107l-13.305-.66L18.047 0l-4.742 12.446L0 13.106l10.377 8.352L6.89 34.314l11.157-7.285 11.14 7.284-3.475-12.856" fill-rule="evenodd"/>
<text font-size="10px" x="10.498" y="23.484" fill="#ffffff" fill-opacity="1" font-family="OpenSans-Bold">8.5</text>
</svg>
I tried changing the transparency of the text element, but that only affects the text. The text inside the SVG is variable is populated dynamically so I can't "pre-process" the SVG file. Is there a way perhaps using evenodd fill or something similar to create an "exclusion" for intersection? Is it possible using one of the SVG JS libraries such as snap.svg or svg.js?
Edit:
The final SVG should look like this:
The SVG code posted above is for the star and the text. The final SVG should have the background color showing through the text while retaining the outer shape of the star.
Create a mask, put the text in it via a text element and then use the mask on the shape you want to clip a hole in. Something like this...
head, body {
width:100%;
height:100%;
}
<svg width="100%" height="100%" viewBox="0 0 200 200">
<defs>
<mask id="sample" maskUnits="userSpaceOnUse">
<rect width="100%" height="100%" fill="white"/>
<text x="12" y="23" font-size="10" font-family="Impact">9.0</text>
</mask>
</defs>
<path fill="#63a95c" d="M36.087 13.107l-13.305-.66L18.047 0l-4.742 12.446L0 13.106l10.377 8.352L6.89 34.314l11.157-7.285 11.14 7.284-3.475-12.856" fill-rule="evenodd" mask="url(#sample)"/>
Good afternoon everyone,
I'm defining an SVG on my page with the following defs.
<svg width="0" height="0">
<defs>
<g id="stroke-hexagon">
<polygon fill="#002663" stroke="#FFFFFF" stroke-width="6" stroke-miterlimit="12" points="57.8,185 5.8,95 57.8,5 161.8,5 213.8,95 161.8,185 "/>
</g>
<g id="hexagon">
<polygon fill="#006890" points="52,180 0,90 52,0 156,0 208,90 156,180 "/>
</g>
</defs>
</svg>
...and implementing it later in the HTML using this:
<svg width="208px" height="180px" viewBox="0 0 208 180" >
<use xlink:href="#hexagon"></use>
<text class="faicon" x="50%" y="70px" fill="white" font-size="80px" text-anchor="middle"></text>
<text text-anchor="middle" x="50%" y="70%" fill="white">Logo Here</text>
</svg>
Works totally fine. I am also able to style the polygon's fill with simple CSS. Looks like this:
#hexagon:hover polygon {
fill:#990000;
}
The hover effect fails, however, whenever the mouse leaves the polygon and instead hovers over either of the 'text' elements within the svg. Is there a way to define a CSS rule that prevents this behavior. Or, would it be better (easier) to change the attribute using JS / jQuery?
Thanks!
Your texts are rendered on top of your polygon and are therefore intercepting mouse events. You should set up a css rule like
text {
pointer-events: none;
}
This will prevent the text from becoming a target of mouse events which should give you the desired hover effect for the polygon.