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 :)
Related
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.
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>
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. :(
Angular 1.6
I want to make the following SVG element clickable:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 30.2 34.1"
style="enable-background:new 0 0 30.2 34.1;" xml:space="preserve">
<rect x="19.4" y="0" width="10.8" height="5.4"/>
<rect x="19.4" y="14.3" width="10.8" height="5.4"/>
<rect x="19.4" y="28.7" width="10.8" height="5.4"/>
<rect x="0.2" y="0" width="10.8" height="5.4"/>
<rect x="0.2" y="14.3" width="10.8" height="5.4"/>
<rect x="0.2" y="28.7" width="10.8" height="5.4"/>
</svg>
If not Angular it works by simply enclosing it like this <svg>...</svg>. But the svg graphics simply dissapears if I do the same in Angular.
Also I tried <use> with no success:
<svg ...>
<use xlink:href="" ng-attr-xlink:href="{{$ctrl.menu.channels}}" />
...
</svg>
How to make my svg element clickable attaching a link to it?
Your first approach was OK, you just need a bit of additional CSS:
<a href="#" class="svg">
<svg version="1.1" id="Layer_1">...</svg>
</a>
And in your css:
a.svg:after {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
I am using c3.js and my components are using CSS Modules. I wanted to modify the fill of points in the line chart with an image. For that in the render method I had added defs-pattern -
render(){
return (
<div>
<defs>
<pattern id="image" x="0" y="0" patternUnits="userSpaceOnUse" height="1" width="1">
<image x="0" y="0" src="http://dummyimage.com/20x20/faf2fa/0011ff.png&text=x" />
</pattern>
</defs>
<C3Chart {...this.getConfig()}/>
</div>
);
}
In the styles css file I had added -
container :global(.c3-target-subscriber .c3-circle-5) {
fill: url(#image) !important;
}
But nothing happens. I just want to show an image inside the point of the line chart.
Any help is highly appreciated.
A <defs> element must have a parent that is a SVG element and not a HTML element. You need something like this:
<svg>
<defs>
<pattern id="image" x="0" y="0" patternUnits="userSpaceOnUse" height="1" width="1">
<image x="0" y="0" src="http://dummyimage.com/20x20/faf2fa/0011ff.png&text=x" />
</pattern>
</defs>
<svg>
Also your CSS points to something with a id of gradient but your pattern's id is image.