SVG prevent scaling when zooming page - reactjs

I wanna know, is there any way to prevent scaling my SVG when zooming page in a browser?
Let's just say my SVG image is a measuring image and I want to keep the same size of my SVG independently from zoom in or zoom out page.
I'm using React
Style
svg: {
height: 150,
width: 150,
},
Example Code
<svg className={classes.svg} viewBox="0 0 150 150">
<g>
<circle cx={70} cy={70} r={32} fill="white" stroke="black"/>
<circle cx={70} cy={70} r={8} fill="black"/>
</g>
</svg>

You might use a viewport related unit like vw, vh.
<svg viewBox="0 0 150 150" style="width:5vw">
<g>
<circle cx="70" cy="70" r="32" fill="white" stroke="black"/>
<circle cx="70" cy="70" r="8" fill="black"/>
</g>
</svg>
Your svg element will keep it's initial size of 5vw.

Related

Does a svg compute outside of viewbox? [duplicate]

This question already has answers here:
svg out of screen, is rendered?
(2 answers)
Closed 1 year ago.
I have several objects moving outside of the viewbox of a svg in react. For the sake of optimisation, I would like to conditionally render it. So the objects outside would not be rendered. But I'm asking myself if it's really needed. Does an SVG compute what is outside of a viewbox?
Yes, the browser computes everything outside the viewport for rendering. Calculates but does not display in the viewbox. Therefore, the question is relevant only in terms of rendering performance. If a part of a very large svg file with a lot of small details is outside the viewBox then rendering will be difficult. Although this will only show the visible part of the SVG.
comments of the author of the question:
I just do a 2.5d effect, so I have a prop for the pixels parcoured in
the x axis. I know where is everything that way, and just need some
calculation regarding the width of the viewbox
Calculating the width of the viewport
Below is an example with two SVG shapes. One figure is inside the svg viewBox, the second is outside
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="600" height="300" viewBox="0 0 600 300" style="border:1px solid" >
<g>
<rect x="20" y="50" width="200" height="200" rx="5%" fill="purple" />
<!-- Circle cx = "800" outside viewBox = "0 0 600 300" -->
<circle cx="800" cy="150" r="140" fill="greenyellow" />
</g>
</svg>
The circle is outside the svg of the canvas so it is not rendered in the browser
This is how it looks in the vector editor
In order for both figures to be inside the svg canvas, you need to calculate the parameters of the viewBox.
To do this, put both shapes in the group tag <g> and calculate the parameters of the viewBox
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="600" height="300" viewBox="0 0 600 300" style="border:1px solid" >
<g id="group">
<rect x="20" y="50" width="200" height="200" rx="5%" fill="purple" />
<!-- Circle cx = "800" outside viewBox = "0 0 600 300" -->
<circle cx="800" cy="150" r="140" fill="greenyellow" />
</g>
</svg>
<script>
console.log(group.getBBox())
</script>
Setting the computed viewBox attributes
It was: viewBox="0 0 600 300"
Now: viewBox = "20 10 920 280"
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="600" height="300" viewBox="20 10 920 280" style="border:1px solid" >
<g id="group">
<rect x="20" y="50" width="200" height="200" rx="5%" fill="purple" />
<!-- Circle cx = "800" inside viewBox = "0 0 920 280" -->
<circle cx="800" cy="150" r="140" fill="greenyellow" />
</g>
</svg>

How to generate an svg image from multiple small svg components?

I have the below svg component. I want to stack multiple same svg components horizontally and vertically, to generate a bigger svg image in a grid.
I can stack them together but how do I convert it to an svg?
Please suggest, and if there is any package I can use. Thanks.
SVG Component
import React from "react";
import "./styles.css";
export default function MySVG() {
return (
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink" width="40" height="40" viewBox="0 0 40 40">
<defs/>
<g/>
<g transform="scale(1,1)">
<g transform="scale(1,1)">
<rect id="cell" fill="rgb(16,28,138)" stroke="none" x="0" y="0" width="40" height="40" fill-opacity="0.40784313725490196"/>
</g>
<path fill="none" stroke="rgb(163,127,18)" paint-order="fill stroke markers" d=" M 0 0 L 0 40" stroke-opacity="0.7294117647058823" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2"/>
<path fill="none" stroke="rgb(163,127,18)" paint-order="fill stroke markers" d=" M 40 0 L 40 40" stroke-opacity="0.7294117647058823" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2"/>
<path fill="none" stroke="rgb(163,127,18)" paint-order="fill stroke markers" d=" M 0 0 L 40 0" stroke-opacity="0.7294117647058823" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2"/>
<path fill="none" stroke="rgb(163,127,18)" paint-order="fill stroke markers" d=" M 0 40 L 40 40" stroke-opacity="0.7294117647058823" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2"/>
</g>
</svg>
);
}
App Component
import React from "react";
import MySVG from "./MySVG";
import "./styles.css";
export default function App() {
return [...Array(5).keys()].map((i) => <MySVG key={i} />);
}
CodeSandBox Link

Arrow marker in IE are not rendered correct [duplicate]

This svg code displays an arrow in firefox and chrome, but is broken in internet explorer 11:
<svg viewBox="0 0 100 100">
<defs>
<marker id="arrow" markerWidth="5" markerHeight="6" refx="5" refy="2" orient="auto">
<path d="M0,0 L0,4 L5,2.5 L5,1.5 L0,0" style="fill:red;" ></path>
</marker>
</defs>
<path d="M0,0 L50,50"
style="stroke:red; stroke-width: 10px; fill: none;
marker-end: url(#arrow);"
></path>
</svg>
See it yourself at
https://jsfiddle.net/ns3qfau5/6/
Add the stroke: none; in tour path style. Like this:
<svg viewBox="0 0 100 100">
<defs>
<marker id="arrow" markerWidth="5" markerHeight="6" refx="5" refy="2" orient="auto">
<path d="M0,0 L0,4 L5,2.5 L5,1.5 L0,0" style="fill:red; stroke: none;" ></path>
</marker>
</defs>
<path d="M0,0 L50,50"
style="stroke:red; stroke-width: 10px; fill: none;
marker-end: url(#arrow);"
></path>
</svg>
It's working in IE-11.
IE has a bug where it doesn't support markers that are defined with markerUnits="strokeWidth". It always has, and it didn't get fixed until Edge.
This is a real pain because "strokeWidth" is the default setting for the markerUnits attribute.
In fact IEs support of markers is pretty bad in general. There are other bugs with markers also (eg. see below).
The only workaround is to use markerUnits="userSpaceOnUse" instead. To convert your particular marker definition to that form, you have to multiply all your marker values by 10, because that is the stroke width your line has.
<svg viewBox="0 0 100 100">
<defs>
<marker id="arrow" markerWidth="50" markerHeight="60" refx="50" refy="20" orient="auto" markerUnits="userSpaceOnUse">
<path d="M0,0 L0,40 L50,25 L50,15 L0,0" style="fill:red;" ></path>
</marker>
</defs>
<path d="M0,0 L50,50"
style="stroke:red; stroke-width: 10px; fill: none;
marker-end: url(#arrow);"
></path>
</svg>
Even converted, the marker still isn't perfect - which is what I meant by other marker bugs in IE. :(

SVG image is escaping the SVG boundary

I am using SVG to display profile picture of the user in one of the Ionic applications. The image sometimes escapes the SVG boundary when I navigate to the screen. I also have attached the screenshots of the same.Not working....
Correct or intended working
<svg viewBox="0 0 120 100" style="width: 200px; height: 200px; overflow: hidden" ng-click="openProfileModal()">
<defs>
<clipPath id="hexagon_clip">
<path id="hexagon" d="M38,2
L82,2
A12,12 0 0,1 94,10
L112,44
A12,12 0 0,1 112,56
L94,90
A12,12 0 0,1 82,98
L38,98
A12,12 0 0,1 26,90
L8,56
A12,12 0 0,1 8,44
L26,10
A12,12 0 0,1 38,2" />
</clipPath>
</defs>
<image ng-href="{{ userPics.photo1 }}" xlink:href="" x="0" y="0" width="100%" height="100%" clip-path="url(#hexagon_clip)" preserveAspectRatio="xMinYMin slice"/>
<use xlink:href="#hexagon" x="0" y="0" stroke="gray" stroke-width="1" fill="transparent" />
</svg>
note: userPics.photo1 -> it is url of the image which I am loading using AngularJS.
I tried applying the style overflow: hidden to SVG, but image still exit the boundary of SVG. I am new to using SVG. Thanks in advance guys :)

SVG clipping mask disappear when changing angular states (Safari / Chrome)

I'm making a logo out of an SVG. Below is the code I am using to construct that logo. It works well and good, with three stacked rectangles and a clipping mask I define.
What is super strange is that whenever I change states in my angular app the clipping mask disappears and I am left with just the rectangles. In Chrome the clipping mask disappears when I zoom also.
Any input appreciated.
<svg style="display:none;" class="gp-ui">
<defs>
<g id="gp_logo-text">
<g class="gp_logo-global">
<path fill="#fff" d="M568.7,485.5c4.6,19.3,23.5,28.5,41.7,28.5c12.9,0,24.8-4.2,34.1-13.5c10-10.2,10.9-20.8,10.9-34.5v-58.2h11.3v-19h-29.6v13c-6.5-10.3-17.3-14.5-29.1-14.5c-24.2,0-44.3,21.3-44.3,45.8c0,24.8,19.3,46,44.1,46c11.8,0,21.7-4.5,27.9-14.8v3.3c0,8.4-0.5,14-6,20.7c-4.4,5.2-11.6,8.2-18.5,8.2c-7.7,0-16.2-3.5-19.6-11L568.7,485.5L568.7,485.5L568.7,485.5z M584.2,433c0-14.8,11.9-27,26.5-27c14.5,0,26.6,12,26.6,26.8c0,15-11.4,27.5-26.5,27.5C596,460.4,584.2,448.2,584.2,433L584.2,433z" />
<polygon fill="#fff" points="694.6,358.8 663.5,358.8 663.5,377.8 674.7,377.8 674.7,458.9 662.6,458.9 662.6,477.9 705.9,477.9 705.9,458.9 694.6,458.9 " />
<path fill="#fff" d="M749.9,480.2c25.6,0,45.9-21.3,45.9-47.4c0-25.3-20.3-46.7-45.4-46.7c-25.3,0-46.1,20.8-46.1,46.9C704.3,458.7,724.4,480.2,749.9,480.2L749.9,480.2z M749.9,460.2c-14.9,0-26-12.7-26-27.4c0-14.8,12.1-26.7,26.5-26.7c14.5,0,25.8,12.7,25.8,27.2C776.1,448.2,764.4,460.2,749.9,460.2L749.9,460.2z" />
<path fill="#fff" d="M824.5,358.8h-31.2v19h11.3v81h-11.3v19h31.2v-13.3c6.7,9.7,17.6,14.7,29.2,14.7c11.4,0,23.2-5.8,30.9-14.5c7.7-8.5,11.8-19.8,11.8-31.3c0-25.2-20.3-45.9-44.9-45.9c-11.1,0-20.7,4.8-26.9,14.2L824.5,358.8L824.5,358.8L824.5,358.8zM850.1,406c14.5,0,26.4,12.2,26.4,27c0,14.5-11.3,27.3-26,27.3c-15,0-26.9-12-26.9-27.5C823.7,418,835.6,406,850.1,406L850.1,406z" />
<path fill="#fff" d="M973.1,477.9h31.2v-19h-10.9v-51h10.9v-19h-31.2v12.7c-6-9.7-15.8-15-27.1-15c-25.5,0-45.7,21.5-45.7,47.4c0,25.2,19.8,46.3,44.8,46.3c11.4,0,21.7-4.5,28.1-14.3L973.1,477.9L973.1,477.9z M946.8,460.4c-14.1,0-26-12-26-26.5c0-15,11.4-27.5,26.3-27.5c14.4,0,26.3,11.8,26.3,26.5C973.4,448,961.8,460.4,946.8,460.4L946.8,460.4z" />
<polygon fill="#fff" points="1040.9,358.8 1009.7,358.8 1009.7,377.8 1020.9,377.8 1020.9,458.9 1008.8,458.9 1008.8,477.9 1052.1,477.9 1052.1,458.9 1040.9,458.9 " />
</g>
<g class="gp_logo-post">
<path fill="#E62100" d="M1072.2,491.4h-11.1v19h42.5v-19h-11.3v-26c7,9.3,18.1,13.8,29.6,13.8c24.2,0,43.4-21.2,43.4-45.5c0-25.2-19.8-45.9-44.4-45.9c-11.8,0-22.2,4.8-28.6,15v-14h-31.2v19h11.1L1072.2,491.4L1072.2,491.4L1072.2,491.4z M1118.4,460.4c-14.5,0-26.3-12-26.3-26.8c0-15.3,12.1-27,26.8-27c14.5,0,25.8,12.7,25.8,27.2C1144.7,448.4,1132.8,460.4,1118.4,460.4L1118.4,460.4z" />
<path fill="#E62100" d="M1213.7,480.2c25.7,0,45.9-21.3,45.9-47.4c0-25.3-20.2-46.7-45.4-46.7c-25.3,0-46.1,20.8-46.1,46.9C1168.1,458.7,1188.2,480.2,1213.7,480.2L1213.7,480.2z M1213.7,460.2c-14.9,0-26-12.7-26-27.4c0-14.8,12.1-26.7,26.5-26.7c14.5,0,25.8,12.7,25.8,27.2C1240,448.2,1228.2,460.2,1213.7,460.2L1213.7,460.2z" />
<path fill="#E62100" d="M1263.3,452v25.8h15.2v-7.3c5.7,6.8,13.7,9.7,22.5,9.7c16.3,0,31.2-10,31.2-28c0-20-16.8-25-32.5-28.7c-6.4-1.5-14.4-3.3-14.4-11.7c0-6.2,5.7-9.3,11.1-9.3c6.2,0,11,4.2,11.3,10.5h19.3v-24.2h-14.7v6.2c-4.9-6.3-11.9-8-19.8-8c-15.5,0-29.6,9.8-29.6,26.8c0,19.5,16.7,24.4,31.8,28.4c6.7,1.8,14.9,3.3,14.9,12.2c0,6.7-5.9,11-11.9,11c-8.2,0-13.4-5.3-14.1-13.3L1263.3,452L1263.3,452L1263.3,452z" />
<polygon fill="#E62100" points="1368.3,407.8 1383.2,407.8 1383.2,388.8 1368.3,388.8 1368.3,358.8 1348.4,358.8 1348.4,388.8 1334.7,388.8 1334.7,407.8 1348.4,407.8 1348.4,477.9 1384.2,477.9 1384.2,458.9 1368.3,458.9 " />
</g>
</g>
<path id="gp_logo-swoosh-path" d="M565.9,316v21c64.4-24.4,147.2-39.3,237.5-39.2c90.2,0,173,14.8,237.5,39.2v-21
c-66-23.9-148.2-38-237.5-38C714.1,278,631.9,292.1,565.9,316" />
</defs>
</svg>
<svg id="globalpost_logo" width="100%" height="100%" viewBox="563.8 277.9 820.4 236.1" xml:space="preserve">
<g id="gp_logo-swoosh" ng-class="{'gp_logo-loading': uiCtrl.loadingState}" clip-path="url(#gp_logo-clip-path)">
<clipPath id="gp_logo-clip-path" >
<use xlink:href="#gp_logo-swoosh-path" />
</clipPath>
<g id="gp_logo-swoosh">
<rect id="gp_logo-swoosh-lead-rect" class="active" x="565.9" y="277.9" fill=" rgba(69, 125, 222, 0)" width="1em" height="59" />
<rect id="gp_logo-swoosh-fill-rect" x="565.9" y="277.9" fill=" rgba(69, 125, 222, 0)" width="1em" height="59" />
<rect id="gp_logo-swoosh-full-rect" x="565.9" y="277.9" fill=" rgba(69, 125, 222, 1)" width="1em" height="59" />
</g>
</g>
<use xlink:href="#gp_logo-text" />
</svg>

Resources