SVG not scaling with page resize React - css
I have an animated SVG in react that is supposed to draw some lines down the screen starting from the top to the bottom relative to 100vh adn 100vw. the problem is it works on my native resolution but not when the window is resized (i made the svg in gimp in respect to my native res). I have tried every single css combination i can think of but i just cant get it to work as needed.
(images at the bottom for an idea of what it should look like vs what happens when resized)
thanks in advance :)
SVG:
<svg className="line_svg" xmlns="http://www.w3.org/2000/svg"
width="auto" height="100%"
viewBox="0 0 2560 1440">
<path id="Selection"
fill="none" stroke="green" stroke-width="2"
d="M 1279.00,0.00
C 1280.66,5.65 1283.93,7.93 1288.00,12.00
1288.00,12.00 1306.00,30.00 1306.00,30.00
1306.00,30.00 1374.00,98.00 1374.00,98.00
1374.00,98.00 1548.00,271.00 1548.00,271.00
1548.00,271.00 1606.00,329.00 1606.00,329.00
1612.96,335.96 1631.41,355.28 1638.00,360.00
1638.00,360.00 1610.91,389.00 1610.91,389.00
1610.91,389.00 1576.91,425.00 1576.91,425.00
1576.91,425.00 1549.09,454.00 1549.09,454.00
1549.09,454.00 1457.91,551.00 1457.91,551.00
1457.91,551.00 1396.09,616.00 1396.09,616.00
1396.09,616.00 1151.91,875.00 1151.91,875.00
1151.91,875.00 1124.09,904.00 1124.09,904.00
1124.09,904.00 1014.91,1020.00 1014.91,1020.00
1014.91,1020.00 989.04,1047.00 989.04,1047.00
989.04,1047.00 978.00,1059.00 978.00,1059.00
978.00,1059.00 965.83,1072.00 965.83,1072.00
964.29,1073.71 960.88,1076.96 960.17,1079.00
959.20,1081.77 961.03,1083.93 962.63,1086.00
962.63,1086.00 976.00,1101.00 976.00,1101.00
976.00,1101.00 1030.58,1162.00 1030.58,1162.00
1030.58,1162.00 1087.83,1226.00 1087.83,1226.00
1087.83,1226.00 1213.83,1367.00 1213.83,1367.00
1213.83,1367.00 1261.07,1420.00 1261.07,1420.00
1266.18,1425.63 1275.10,1437.95 1282.00,1440.00
1280.25,1433.86 1276.28,1430.56 1272.08,1426.00
1272.08,1426.00 1256.07,1408.00 1256.07,1408.00
1256.07,1408.00 1196.16,1341.00 1196.16,1341.00
1196.16,1341.00 1044.16,1171.00 1044.16,1171.00
1044.16,1171.00 993.17,1114.00 993.17,1114.00
993.17,1114.00 963.00,1081.00 963.00,1081.00
963.00,1081.00 975.04,1068.00 975.04,1068.00
975.04,1068.00 1024.09,1016.00 1024.09,1016.00
1024.09,1016.00 1052.91,986.00 1052.91,986.00
1052.91,986.00 1144.09,889.00 1144.09,889.00
1144.09,889.00 1205.91,824.00 1205.91,824.00
1205.91,824.00 1450.09,565.00 1450.09,565.00
1450.09,565.00 1477.91,536.00 1477.91,536.00
1477.91,536.00 1586.09,421.00 1586.09,421.00
1586.09,421.00 1612.96,393.00 1612.96,393.00
1612.96,393.00 1623.00,382.00 1623.00,382.00
1623.00,382.00 1635.28,369.00 1635.28,369.00
1636.74,367.34 1640.17,363.91 1640.83,362.00
1641.84,359.07 1639.76,357.00 1637.94,355.00
1637.94,355.00 1623.00,340.00 1623.00,340.00
1623.00,340.00 1560.00,277.00 1560.00,277.00
1560.00,277.00 1359.00,77.00 1359.00,77.00
1359.00,77.00 1304.00,22.00 1304.00,22.00
1298.18,16.18 1286.24,2.12 1279.00,0.00 Z" />
</svg>
CSS:
.front_page_parent{
width: 100vw;
height: 100vh;
display: block;
margin: 0 auto;
padding: 0;
}
.line_svg{
display: block;
margin: 0 auto;
max-width: 100vw;
max-height: 100vh;
stroke-dasharray: 6000;
animation: draw 2s ease-in;
fill: green;
overflow: hidden;
}
Structure of App
export const App = () => {
return (
<div className="app">
<FrontPage />
</div>
)
}
export const FrontPage = () => {
return (
<div className="font_page_parent" style={BackgroundImageStyle}>
<svg className="line_svg" xmlns="http://www.w3.org/2000/svg"
width="auto" height="100%"
viewBox="0 0 2560 1440">
<path id="Selection"
fill="none" stroke="green" stroke-width="2"
d="......."- />
</svg>
</div>
working full screen
not working resized
Related
SVG line ROTATE transform animation takes a wierd path before reaching destination angle [ Works differently between laptop and extended monitors ]
I'm trying to recreate a meter in SVG. When trying to rotate a <line> or a <path> using transform and a transition, the line / path takes a wierd route before reaching the destination angle. Observed that it works differently between laptop and extended monitors. How to fix this ? CODEPEN : https://codepen.io/sparkeplug/pen/zYWZxvX BEHAVIOR IN DIFFERENT MONITORS : EXTENDED MONITOR BEHAVIOR : LAPTOP MONITOR BEHAVIOR : Im expecting the line to rotate with the lines bottom coordinates as transform origin ( like a typical meter ). EXPECTED BEHAVIOR SAMPLE IMAGE :
Move the centre of rotation coords out of the transform and set them with a transform-origin property instead. const btn = document.getElementById("btn"); const meter = document.getElementById("idMeter"); let flag = false; btn.addEventListener("click", function () { console.log("test"); const angle1 = "79"; const angle2 = "-48"; meter.setAttribute("transform", `rotate(${flag ? angle1 : angle2})`); flag = !flag; }); .container { display: flex; position: relative; flex-direction: column; justify-content: center; align-items: flex-start; height: 20rem; width: 100%; } .svg { border: 1px solid red; } .meter { transition: all 0.2s ease-in-out; transform-origin: 250px 350px; } <main class="container"> <svg class="svg" viewbox="0 0 500 500"> <g class="meter" id="idMeter"> <line x1="250" y1="350" x2="250" y2="100" stroke="black" stroke-width="3"></line> </g> </svg> <button id="btn">Animate</button> </main>
How do I target each circle within svg using css?
I have this <svg class="wheel" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" transform="scale(1.022,1.022)" viewBox="0 0 1024 1024" height="100%" width="100%"> <circle fill="#ffffff" cx="512" cy="512" r="110"></circle> <circle stroke="#ffffff" r="456" fill="transparent" stroke-width="33" cx="512" cy="512"></circle> </svg> How can I style each circle using css? Thank you.
If you know that the SVG markup won't change, then this will suffice: .wheel * { // CSS here } Otherwise, give the circles a class and write like: .wheel .wheel-circle { // CSS here } If you mean each circle needs different styles then simply: .wheel #wheel-circle-1 { // CSS here } .wheel #wheel-circle-2 { // CSS here }
Method 1: The best way would be to add an id to each circle: <svg class="wheel" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" transform="scale(1.022,1.022)" viewBox="0 0 1024 1024" height="100%" width="100%"> <circle id="innerCircle" fill="#ffffff" cx="512" cy="512" r="110"></circle> <circle id="outerCircle" stroke="#ffffff" r="456" fill="transparent" stroke-width="33" cx="512" cy="512"></circle> </svg> And then just target that. #innerCircle { fill: red; } #outerCircle { stroke: blue; } Method 2: But if this is not desirable, try using the nth-child selector on the parent: .wheel:nth-child(1) { fill: red; } .wheel:nth-child(2) { stroke: blue; } I hope this helps!
How to change the size of svg icon in React?
I wanted to display an svg icon and a text in a same line in React and Next.js. Now I have found how to do it. Though I still don't know how to control the size of the svg icon in the context. I want the svg icon to be same size as each character of the text. I put the browser display here. And I put my code bellow, please point out what is wrong about my code. //mysvg.js import styles from '../styles/svg.module.css' export function CircleBottomIcon(props) { return (<span class={styles['svg-image']}> <svg width="30" height="30" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg" {...props} > <title>circle-bottom</title> <path d="M27.5 15c0 6.893-5.608 12.5-12.5 12.5-6.893 0-12.5-5.608-12.5-12.5C2.5 8.107 8.108 2.5 15 2.5c6.893 0 12.5 5.608 12.5 12.5zm2.5 0c0-8.284-6.716-15-15-15C6.716 0 0 6.716 0 15c0 8.284 6.716 15 15 15 8.284 0 15-6.716 15-15zm-15 2.5l-5.625-5.625-1.875 1.91L15 21.25l7.5-7.466-1.875-1.91L15 17.5z" fill-rule="evenodd" /> </svg></span> ); } //index.js import {CircleBottomIcon} from '../components/mysvg' export default function Home() { return ( <span> 1234<CircleBottomIcon></CircleBottomIcon>567890 </span> ) } //svg.module.css .svg-image { display: inline-block; width: 16px; height: 16px; }
I'd suggest you keep constant values for viewbox param and accept props for height and width. Add a default values for these as 30 and 30. Part of code looks like: const { height, width } = props; <svg width={width} height={height} viewBox="0 0 30 30" ... Then you can use any values for width and height when you use the svg component.
your .svg-image selector should target the svg element: .svg-image { display: inline-block; svg { width: 16px; height: 16px; } }
Trying to "transform: rotate()" a <circle> element using styled-components
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; `;
Cannot override class properties inside use Tag
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.