Related
I have a set of .svg icons with different colors for different paths. Currently I'm using react-svg package to render them and it looks something like this:
<span>
<ReactSVG
src="/icons/setting.svg"
beforeInjection={svg => {
svg.classList.add("svg-classname");
}}
/>
</span>
This works fine. Now I want to change all path colors to gray and bring all original colors back by user hover, Which I am trying to achieve in my scss by doing:
.svg-classname {
path,
rect,
circle {
fill: #888;
color: #888;
}
&:hover {
path,
rect,
circle {
fill: initial;
color: initial;
}
}
}
This clearly doesn't work! Im not an expert with svgs so any suggestion (even outside of using react-svg) are truly welcome.
A simple D3 work-around for your problem:
d3.selectAll('.my-svg-icon path')
.each(function() {
const path = d3.select(this);
const originalColor = path.attr('fill');
path.attr('fill', 'gray')
.on('mouseenter', () => path.attr('fill', originalColor))
.on('mouseleave', () => path.attr('fill', 'gray'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg class="my-svg-icon">
<path d="M 10,10 H 50 V 50 H 10 Z" fill="red"/>
</svg>
<svg class="my-svg-icon">
<path d="M 10,10 H 50 V 50 H 10 Z" fill="blue"/>
</svg>
CodeSandbox with example:
https://codesandbox.io/s/floral-surf-l7m0x
I'm trying to rotate 180ยบ a circle element inside an SVG. I'm being able to do it with the regular <circle> tag, but I'm not being able to do it with the styled component styled.circle
LS.Svg_SVG = styled.svg`
border: 1px dotted silver;
width: 100px;
height: 100px;
`;
LS.Circle_CIRCLE = styled.circle`
stroke-dasharray: 289.0272;
stroke-dashoffset: -144.5136;
transform: rotate(180 50 50); /* <------------ IT DOES NOT WORK */
`;
export default function App() {
return (
<React.Fragment>
<LS.Container_DIV>
<LS.Svg_SVG viewBox="100 100">
<circle /* USING REGULAR <circle> */
cx="50"
cy="50"
r="46"
stroke="black"
strokeWidth="8px"
fill="none"
strokeDasharray="289.0272"
strokeDashoffset="-144.5136"
transform="rotate(180 50 50)" /* <----------------- IT WORKS */
/>
</LS.Svg_SVG>
</LS.Container_DIV>
<LS.Container_DIV>
<LS.Svg_SVG viewBox="100 100">
<LS.Circle_CIRCLE /* USING STYLED COMPONENTS */
cx="50"
cy="50"
r="46"
stroke="black"
strokeWidth="8px"
fill="none"
/>
</LS.Svg_SVG>
</LS.Container_DIV>
</React.Fragment>
);
}
The result I'm getting:
They both should be the same. The first one is rotated (using regular <circle>). The second one is not rotated (using styled-components). Even though I'm setting transform: rotate(-180 50 50); in the styled component.
In CSS, units are required (ie. 180deg, 50px)
The SVG-specific version of rotate: rotate(angle, cx, cy), is not supported in the CSS version of transform. You'll need to use transform-origin.
LS.Circle_CIRCLE = styled.circle`
stroke-dasharray: 289.0272;
stroke-dashoffset: -144.5136;
transform: rotate(180deg);
transform-origin: 50px 50px;
`;
I using vue-simple-svg package and Vue.
I sending icon and color to component:
<IconComponent name="comment.svg" color="#ffffff" />
In IconComponent I get props:
<simple-svg
:src="image"
fill-class-name="fill-to-change"
:fill="color"
stroke-class-name="stroke-to-change"
:stroke="color"
custom-id="my-id"
custom-class-name="my-class"
/>
props: {
image: {
type: String,
required: true,
},
color: {
type: String,
required: true,
},
},
But color not change to #ffffff.
So I trying change color using CSS:
I have structure svg file with color:
svg => g => g
I have class .my-class, and I write code:
.my-class g g {
fill: #ffffff;
stroke: #ffffff;
}
I tryimg using:
.fill-to-change {
fill: #ffffff;
}
.stroke-to-change {
stroke: #ffffff;
}
but color not change to white.
File SVG:
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: sketchtool 59.1 (101010) - https://sketch.com -->
<title>afb3c770-9343-4219-b68b-48905c19ec63#1.00x</title>
<desc>Created with sketchtool.</desc>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" fill-opacity="0.6">
<g id="Icons-/-Interfaces-/-user-plus" fill="#000000">
<path d="M17,19 L17,16.5 C17,16.2238576 17.2238576,16 17.5,16 C17.7761424,16 18,16.2238576 18,16.5 L18,19 L20.5,19 C20.7761424,19 21,19.2238576 21,19.5 C21,19.7761424 20.7761424,20 20.5,20 L18,20 L18,22.5 C18,22.7761424 17.7761424,23 17.5,23 C17.2238576,23 17,22.7761424 17,22.5 L17,20 L14.5,20 C14.2238576,20 14,19.7761424 14,19.5 C14,19.2238576 14.2238576,19 14.5,19 L17,19 Z M14.0425135,13.5651442 C13.4188979,13.8445863 12.7275984,14 12,14 C11.2738711,14 10.5838946,13.8452135 9.96126583,13.5668358 L5.87929558,15.4222768 C5.34380416,15.665682 5,16.1996113 5,16.7878265 L5,17.5 C5,18.3284271 5.67157288,19 6.5,19 L11.5,19 C11.7761424,19 12,19.2238576 12,19.5 C12,19.7761424 11.7761424,20 11.5,20 L6.5,20 C5.11928813,20 4,18.8807119 4,17.5 L4,16.7878265 C4,15.8074678 4.57300693,14.9175857 5.46549264,14.5119103 L8.92215823,12.9406987 C7.75209123,12.0255364 7,10.6005984 7,9 C7,6.23857625 9.23857625,4 12,4 C14.7614237,4 17,6.23857625 17,9 C17,10.5929224 16.2551051,12.0118652 15.0946468,12.927497 L17.6966094,14.0402775 C17.9505071,14.1488619 18.0683068,14.4427117 17.9597225,14.6966094 C17.8511381,14.9505071 17.5572883,15.0683068 17.3033906,14.9597225 L14.0425135,13.5651442 L14.0425135,13.5651442 Z M12,13 C14.209139,13 16,11.209139 16,9 C16,6.790861 14.209139,5 12,5 C9.790861,5 8,6.790861 8,9 C8,11.209139 9.790861,13 12,13 Z" id="Combined-Shape"></path>
</g>
</g>
</svg>
I have other solution. I added to scss file filter for example:
&__image {
filter: invert(35%) sepia(36%) saturate(7009%) hue-rotate(2deg) brightness(104%) contrast(88%);
}
To convert the color to the filter format (for example: #ef4f10) use CSS filter generator to convert from black to target hex color.
The best effest is when default color in SVG file is black: fill="#000000".
Use CSS On SVG
svg{
fill: #fff;
stroke: #fff;
}
Hope it will work for you
add !important at the end of style.
eg
.class g g{
fill:#fff!important;
}
#michal
Remove 'fill=""' property from all tag inside svg tag, then you will get result.
The best thing you can do is to bind to attribute
<path v-bind:fill="this.skinColorContent"
export default {
data() {
return {
skinColorContent: 'red',
}
},
}
I need to change SVG fill property by adding up a class. Say from #fff to #000. I tried fiddling with two different methods. I got successful with one of either method. Rather I don't prefer the method to use which I was successful.
Method 1: - Succesful.
I just added a class on the body tag and over-ride the svg fill property. Take a look at the code below
var button = document.getElementById("btn");
var body = document.body
var count = false;
button.onclick = changeBackground;
function changeBackground() {
body.classList.toggle('toggle');
}
body {
background: #3d3d3d;
}
.sheetListWhite {
fill: #fff;
}
.slBGColor {
fill: #3d3d3d;
}
.toggle {
background: #fff;
}
.toggle .sheetListWhite {
fill: #3d3d3d;
}
.toggle .slBGColor {
fill: #fff;
}
<svg width="18px" height="18px" viewBox="-2 -2 13 13">
<use xlink:href="#sharedByMe" class="sheetListWhite"></use>
</svg>
<button id="btn"> Change background</button>
<svg style="display:none;">
<symbol id="sharedByMe">
<g id="user-(5)">
<path d="M5.76735992,5.07170748 C6.58617985,4.59194553 7.12018634,3.73525063 7.12018634,2.74147173 C7.12020298,1.23365988 5.8385508,0 4.27211846,0 C2.70568612,0 1.42403394,1.23365988 1.42403394,2.74147173 C1.42403394,3.73525063 1.95804042,4.59196155 2.77686035,5.07170748 C1.35282642,5.58574044 0.284796801,6.78512932 0,8.22439918 L0.712025292,8.22439918 C1.06802962,6.64806134 2.52768396,5.48292744 4.27211846,5.48292744 C6.01655296,5.48292744 7.47620731,6.64804532 7.83221163,8.22439918 L8.54423692,8.22439918 C8.25944012,6.75085832 7.19141051,5.55146944 5.76735992,5.07170748 Z M2.13605923,2.74147173 C2.13605923,1.61062486 3.09729421,0.685371939 4.27211846,0.685371939 C5.44694272,0.685371939 6.40817769,1.61062486 6.40817769,2.74147173 C6.40817769,3.87231861 5.44694272,4.79757153 4.27211846,4.79757153 C3.09729421,4.79757153 2.13605923,3.87231861 2.13605923,2.74147173 Z" id="Shape"></path>
</g>
<g id="shared-folder" transform="translate(6.111111, 5.294118)">
<ellipse id="Oval-6" class="slBGColor" cx="2.44444444" cy="2.35294118" rx="2.44444444" ry="2.35294118"></ellipse>
<path d="M3.54444101,1.45883032 C3.94870693,1.45883032 4.27777778,1.13170727 4.27777778,0.729415161 C4.27777778,0.327123049 3.94870693,0 3.54444101,0 C3.14017508,0 2.81110424,0.327140144 2.81110424,0.729415161 C2.81110424,0.781778783 2.81720578,0.832655093 2.82779325,0.881924423 L1.89436023,1.34613656 C1.7598169,1.19301186 1.56441282,1.09413129 1.34443069,1.09413129 C0.940181958,1.09411419 0.611111111,1.42125434 0.611111111,1.82352936 C0.611111111,2.22580437 0.940181958,2.55294452 1.34444788,2.55294452 C1.56439563,2.55294452 1.75974815,2.45413233 1.89429148,2.30105891 L2.82781043,2.76516848 C2.81720578,2.81442071 2.81110424,2.86527993 2.81110424,2.91764355 C2.81110424,3.31991857 3.14017508,3.64705871 3.54444101,3.64705871 C3.94870693,3.64705871 4.27777778,3.31993566 4.27777778,2.91764355 C4.27777778,2.51536853 3.94870693,2.18822839 3.54444101,2.18822839 C3.32445888,2.18822839 3.12903762,2.28710896 2.99449429,2.44025076 L2.06104408,1.97615829 C2.07164873,1.92685476 2.07778465,1.87594426 2.07778465,1.82352936 C2.07778465,1.77116573 2.07168311,1.72028942 2.06109564,1.67102009 L2.99452866,1.20680796 C3.12905481,1.35994975 3.32444169,1.45883032 3.54444101,1.45883032 Z" id="Shape"></path>
</g>
</symbol>
</svg>
See the fiddle HERE
Method 2 - Failed
Instead of adding the class directly to the body tag i added it on a div.
var button = document.getElementById("btn");
var body = document.getElementById("check");
var count = false;
button.onclick = changeBackground;
function changeBackground() {
body.classList.toggle('toggle');
}
div {
height: 300px;
width: 100%;
background: #3d3d3d
}
.sheetListWhite {
fill: #fff;
}
.slBGColor {
fill: #3d3d3d;
}
.toggle {
background: #fff;
}
.toggle .sheetListWhite {
background: #3d3d3d
}
.toggle .slBGColor {
fill: #fff;
}
<div id="check">
<svg width="18px" height="18px" viewBox="-2 -2 13 13">
<use xlink:href="#sharedByMe" class="sheetListWhite"></use>
</svg>
<button id="btn"> Change background</button>
</div>
<svg style="display:none;">
<symbol id="sharedByMe">
<g id="user-(5)">
<path d="M5.76735992,5.07170748 C6.58617985,4.59194553 7.12018634,3.73525063 7.12018634,2.74147173 C7.12020298,1.23365988 5.8385508,0 4.27211846,0 C2.70568612,0 1.42403394,1.23365988 1.42403394,2.74147173 C1.42403394,3.73525063 1.95804042,4.59196155 2.77686035,5.07170748 C1.35282642,5.58574044 0.284796801,6.78512932 0,8.22439918 L0.712025292,8.22439918 C1.06802962,6.64806134 2.52768396,5.48292744 4.27211846,5.48292744 C6.01655296,5.48292744 7.47620731,6.64804532 7.83221163,8.22439918 L8.54423692,8.22439918 C8.25944012,6.75085832 7.19141051,5.55146944 5.76735992,5.07170748 Z M2.13605923,2.74147173 C2.13605923,1.61062486 3.09729421,0.685371939 4.27211846,0.685371939 C5.44694272,0.685371939 6.40817769,1.61062486 6.40817769,2.74147173 C6.40817769,3.87231861 5.44694272,4.79757153 4.27211846,4.79757153 C3.09729421,4.79757153 2.13605923,3.87231861 2.13605923,2.74147173 Z" id="Shape"></path>
</g>
<g id="shared-folder" transform="translate(6.111111, 5.294118)">
<ellipse id="Oval-6" class="slBGColor" cx="2.44444444" cy="2.35294118" rx="2.44444444" ry="2.35294118"></ellipse>
<path d="M3.54444101,1.45883032 C3.94870693,1.45883032 4.27777778,1.13170727 4.27777778,0.729415161 C4.27777778,0.327123049 3.94870693,0 3.54444101,0 C3.14017508,0 2.81110424,0.327140144 2.81110424,0.729415161 C2.81110424,0.781778783 2.81720578,0.832655093 2.82779325,0.881924423 L1.89436023,1.34613656 C1.7598169,1.19301186 1.56441282,1.09413129 1.34443069,1.09413129 C0.940181958,1.09411419 0.611111111,1.42125434 0.611111111,1.82352936 C0.611111111,2.22580437 0.940181958,2.55294452 1.34444788,2.55294452 C1.56439563,2.55294452 1.75974815,2.45413233 1.89429148,2.30105891 L2.82781043,2.76516848 C2.81720578,2.81442071 2.81110424,2.86527993 2.81110424,2.91764355 C2.81110424,3.31991857 3.14017508,3.64705871 3.54444101,3.64705871 C3.94870693,3.64705871 4.27777778,3.31993566 4.27777778,2.91764355 C4.27777778,2.51536853 3.94870693,2.18822839 3.54444101,2.18822839 C3.32445888,2.18822839 3.12903762,2.28710896 2.99449429,2.44025076 L2.06104408,1.97615829 C2.07164873,1.92685476 2.07778465,1.87594426 2.07778465,1.82352936 C2.07778465,1.77116573 2.07168311,1.72028942 2.06109564,1.67102009 L2.99452866,1.20680796 C3.12905481,1.35994975 3.32444169,1.45883032 3.54444101,1.45883032 Z" id="Shape"></path>
</g>
</symbol>
</svg>
Fiddle it HERE
Now you can see I can't override the following classes .slBGColor, .sheetListWhite
How can I get rid of this bug? Any Idea. I don't want to use the svg tag directly instead of use tag. I mean I would like to use all of my SVG from an external resource. Any Help
Thanks.
The "insides" of a <use> cannot be addressed via the <use> element. It is considered opaque/private. As far as the browser is concerned, there is no class="slBGColor" inside the <div>. So .toggle .slBGColor {} does nothing.
You can make it work by restyling the symbol definition itself.
For example, if I make the following two changes to your example, the ellipse in the symbol changes colour based on whether the "toggle" class is set or not.
var body = document.body;
.toggle div {
background: red;
}
https://jsfiddle.net/nuorcj0a/4/
However, be aware that will also change any other references to that symbol on the page.
Problem
I'm trying to simply move an svg element using transform=matrix(a,b,c,d,e,f)
The element is moving fine but when I apply a css transition it has no effect.
Question
Is this possible on svg elements without an external library like d3?
Code I'm trying
html:
<svg width="100%" height="100%" viewbox="0 0 200 200">
<rect x="20" y="20" width="50" height="50"
style="fill: #3333cc"
transform="matrix(1,0,0,1,1,1)"
id="blueBox"
/>
</svg>
<button id="boxMover">
Move it
</button>
jQuery
$(function(){
$('#boxMover').click(function(){
var blueBox = $('#blueBox');
if(blueBox.attr('transform')=='matrix(1,0,0,1,1,1)'){
blueBox.attr('transform', 'matrix(1,0,0,1,100,30)');
} else {
blueBox.attr('transform', 'matrix(1,0,0,1,1,1)');
}
})
})
CSS
svg {
display: block
}
#boxMover {
position: absolute;
left: 20px;
top: 20px;
transition: transform .5s ease;
}
Here's a fiddle I created to test it
A simpler solution:
Create the following class:
.boxEase {
transform: matrix(1,0,0,1,100,30);
transition: all .5s ease;
}
Change your jQuery code to just attach the above class to your box when the button is clicked:
$(function(){
$('#boxMover').click(function(){
var blueBox = $('#blueBox');
blueBox.attr('class', 'boxEase');
})
})
Added dynamic case with variable ending (starting) positions
Use the following jQuery code where transform and transition properties are added to the box conditionally. I imagine you can adjust the conditional to something else but I have used your original example for this case:
`$(function(){
$('#boxMover').click(function(){
var startPos = 'matrix(1,0,0,1,1,1)',
endPos = 'matrix(1,0,0,1,100,30)';
var blueBox = $('#blueBox');
if(blueBox.attr('transform') == startPos){
blueBox.attr('transform', endPos);
blueBox.css({'transform': endPos, 'transition': 'all 0.5s ease'});
} else {
blueBox.attr('transform', startPos);
blueBox.css({'transform': startPos, 'transition': 'all 0.5s ease'});
}
})
}); `
There's a horrible grey area between the CSS and SVG namespaces where things like this happen all the time.
However, you can fix your problem as follows:
Move the transform CSS statement out of the #boxMover rules and put it somewhere it can actually affect the behaviour of your #blueBox SVG element.
Changing the transform attributes of the SVG element directly still won't work because you're talking to the SVG namespace, and the CSS rules aren't having any say in the matter. Instead, set up CSS classes containing the required transform attributes, and switch between those instead. There is no class attribute in the SVG namespace, so the CSS rules will come to life.
Also note that you can't use JQuery's addClass() and removeClass() methods to change the class of an SVG element, so use attr('class') instead
This should work:
$(function() {
$('#boxMover').click(function() {
var blueBox = $('#blueBox');
if (blueBox.attr('class') == 'overHere') {
blueBox.attr('class', 'overThere');
} else {
blueBox.attr('class', 'overHere');
}
})
})
svg {
display: block
}
#boxMover {
position: absolute;
left: 20px;
top: 20px;
}
#blueBox {
transition: transform .5s ease;
}
.overHere {
transform: matrix(1, 0, 0, 1, 1, 1);
}
.overThere {
transform: matrix(1, 0, 0, 1, 100, 30);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="100%" height="100%" viewbox="0 0 200 200">
<rect x="20" y="20" width="50" height="50"
style="fill: #3333cc" class="overHere" id="blueBox" />
</svg>
<button id="boxMover">
Move it
</button>