svg keep element size when adding text - css

I'm quite new and trying to combine some drawing with texts or draw more. I draw a circle with sections, I want the text to display on center of each. But my viewport doesn't have enough space for text because I draw circle first, when I increase svg width & height my circle becomes bigger which I don't want it happens. I need space to draw lines and texts. Please suggest me how can I keep the circle size (300,300) and have space. Thanks
<svg width="300" height="300" viewBox="0 0 300 300">
<g transform="translate(150,150)" fill="none" stroke-width="45">
<path stroke="#CBA135" d="M-110 0 A110 110 0 0 10-110"/>
<path stroke="#7EC34F" d="M0 -110 A110 110 0 0 1110 0"/>
<path stroke="#ABDB92" d="M110 0 A110 110 0 0 1-110 0"/>
</g>
<g transform="translate(150,150)" fill="none" stroke-width="2">
<path stroke="#fff" d="M0 -137 L0,-82"/>
<path stroke="#fff" d="M-137 0 L-82,0"/>
<path stroke="#fff" d="M137 0 L82,0"/>
<path stroke="#333" d="M117 -99 L137,-119"/>
<path stroke="#333" d="M0 147 L0,167"/>
<path stroke="#333" d="M-117 -99 L-137,-119"/>
<text x="-169" y="-140" font-family="sans-serif" font-size="18px"
fill="#438736">WORD1 WORD2</text>
Here's link to my codepen

When I increase svg width & height my circle becomes bigger which I don't want
The viewBox attribute allows you to specify that a given set of graphics stretch to fit a particular container element.
https://developer.mozilla.org/en/docs/Web/SVG/Attribute/viewBox
I would suggest to remove your ViewBox element and just set the height and width on your SVG. As much as you need.

I don't know much about making circles or anything, but maybe it would work if you make the circle position: relative and the text field position: absolute

Related

How to fit svg width/height to be the same as path width/height

I have this svg that renders an arrow
<div style="position: absolute; z-index: 0;">
<svg
width="373"
height="280"
overflow="auto"
style="position: absolute; left: 630.922px; top: -305px; pointer-events: none;"
>
<path
d="M 20 260 C 20 260, 334.74671750091653 33.15551891825835, 334.74671750091653 33.15551891825835"
stroke="CornflowerBlue"
stroke-dasharray="0 0"
stroke-width="5"
fill="transparent"
pointer-events="visibleStroke"
></path>
<g
fill="CornflowerBlue"
pointer-events="auto"
transform="translate(319.89194405571646,25.37183689162216) rotate(-35.78107386189255) scale(30)"
opacity="1"
>
<animate
dur="0.4"
attributeName="opacity"
from="0"
to="1"
begin="indefinite"
repeatCount="0"
fill="freeze"
></animate>
<path d="M 0 0 L 1 0.5 L 0 1 L 0.25 0.5 z"></path>
</g>
</svg>
</div>
This results in
As you can clearly see from the photo (it's an inspect element of the svg element though), the diagonal arrow has blue background even after the arrow's head ends. The same thing counts for the width as well, the blue background is wider than the actual arrow width. Is it possible to fit the svg width/height to be the same on as the path's? The paths looks like this:
If possible, how can I achieve this?
Draw your arrows outside the SVG by either changing the path data or by adding a viewBox to the SVG element with a x/y/width/height that shifts the arrows outside the SVG's boundaries. And then add overflow: visible to your SVG element.
In this example I have a viewBox 500 in width and 300 in height. I made a line from the left bottom corner to the top right corner. I turned the arrow into a <marker>. To hide the start and the end of the line I added a stroke-dasharray there the first segment in 0, a space of 1, a segment of 98 and a space of 1 (0 1 98 1). The path length is set to 100.
<svg viewBox="0 0 500 300" width="500">
<defs>
<marker id="arrow" viewBox="0 0 1 1" refX="1" refY=".5"
markerWidth="6" markerHeight="6"
orient="auto-start-reverse">
<path d="M 0 0 L 1 0.5 L 0 1 L 0.25 0.5 z" fill="CornflowerBlue" />
</marker>
</defs>
<rect width="500" height="300" fill="#eee"/>
<line x1="0" y1="300" x2="500" y2="0" stroke-dasharray="0 1 98 1"
pathLength="100" stroke="CornflowerBlue" stroke-width="5" marker-end="url(#arrow)" />
</svg>

How to modify the size of a <g> (SVG element)?

I can not seem to succeed at modifying the size of my element that is rendered inside a recharts graph as X axis. I want it to be 20px height and width. I couldn't even succeed by making modifications in the console css to the element. Could anyone help me out?
Here's the element:
<svg
style={{ cursor: 'pointer', }} width="20px" height="20px"
>
<g transform={`translate(10,10)`} fill="green" stroke="green">
<path
fill="current"
fillRule="evenodd"
d="M8,0 C3.58862306,0 0,3.58862306 0,8 C0,12.4113769 3.58862306,16 8,16 C12.4113769,16 16,12.4113769 16,8 C16,3.58862306 12.4113769,0 8,0 Z M12.0546875,6.3046875 L7.72131347,10.6379394 C7.59130859,10.7679443 7.42065431,10.833374 7.25,10.833374 C7.07934569,10.833374 6.90869141,10.7679443 6.77868653,10.6379394 L4.61206056,8.47131347 C4.35131837,8.21069338 4.35131837,7.78930663 4.61206056,7.52868653 C4.87268066,7.26794434 5.29394531,7.26794434 5.5546875,7.52868653 L7.25,9.22399903 L11.1120606,5.36206056 C11.3726807,5.10131837 11.7939453,5.10131837 12.0546875,5.36206056 C12.3153076,5.62268066 12.3153076,6.04394531 12.0546875,6.3046875 Z"
transform="translate(.5)"
/>
</g>
</svg>
As #enxaneta recommended, a negative viewBox offset like viewBox="-0.5 -0.5 17 17" is a straight forward solution.
Alternatively, you could scale your <g> (or your path) like so:
.svg{
display:inline-block;
width:10em;
border: 1px solid #ccc
}
<svg class="svg" viewBox="0 0 16 16">
<g transform="scale(0.94117647)" transform-origin="8 8" stroke-width="1" fill="green" stroke="green">
<path d="M8,0 C3.58862306,0 0,3.58862306 0,8 C0,12.4113769 3.58862306,16 8,16 C12.4113769,16 16,12.4113769 16,8 C16,3.58862306 12.4113769,0 8,0 Z M12.0546875,6.3046875 L7.72131347,10.6379394 C7.59130859,10.7679443 7.42065431,10.833374 7.25,10.833374 C7.07934569,10.833374 6.90869141,10.7679443 6.77868653,10.6379394 L4.61206056,8.47131347 C4.35131837,8.21069338 4.35131837,7.78930663 4.61206056,7.52868653 C4.87268066,7.26794434 5.29394531,7.26794434 5.5546875,7.52868653 L7.25,9.22399903 L11.1120606,5.36206056 C11.3726807,5.10131837 11.7939453,5.10131837 12.0546875,5.36206056 C12.3153076,5.62268066 12.3153076,6.04394531 12.0546875,6.3046875 Z" ></path>
</g>
</svg>
Edit: correct scaling value
As #Carsten Massmann has pointed out it should be:
The scaling factor 0.94117647 is the result of
16/17 (original svg width / svg width + stroke-width)
transform-origin="8 8" ensures we're scaling from the center of our viewBox.
Another workaround might be to set overflow to visible to avoid any cropping:
.svg{
display:inline-block;
width:10em;
border: 1px solid #ccc
}
<svg overflow="visible" class="svg" viewBox="0 0 16 16">
<path stroke-width="1" fill="green" stroke="green" d="M8,0 C3.58862306,0 0,3.58862306 0,8 C0,12.4113769 3.58862306,16 8,16 C12.4113769,16 16,12.4113769 16,8 C16,3.58862306 12.4113769,0 8,0 Z M12.0546875,6.3046875 L7.72131347,10.6379394 C7.59130859,10.7679443 7.42065431,10.833374 7.25,10.833374 C7.07934569,10.833374 6.90869141,10.7679443 6.77868653,10.6379394 L4.61206056,8.47131347 C4.35131837,8.21069338 4.35131837,7.78930663 4.61206056,7.52868653 C4.87268066,7.26794434 5.29394531,7.26794434 5.5546875,7.52868653 L7.25,9.22399903 L11.1120606,5.36206056 C11.3726807,5.10131837 11.7939453,5.10131837 12.0546875,5.36206056 C12.3153076,5.62268066 12.3153076,6.04394531 12.0546875,6.3046875 Z" ></path>
</svg>
Caveats: your icon will be displayed larger than your original design and might cause layout inconsistencies when used with other elements that fit the 16x16 boundaries.
If it will be useful to you, I found svg similar to yours and I demonstrated how you can add styles
svg {
background: #479840;
border-radius: 50%;
}
path {
filter: invert(99%) sepia(99%) saturate(2%) hue-rotate( 205deg)
brightness(110%) contrast(100%);
}
<svg height="44" viewbox="0 0 24 24" width="44" xmlns="http://www.w3.org/2000/svg">
<path d="m10 15.586-3.293-3.293-1.414 1.414L10 18.414l9.707-9.707-1.414-1.414z"></path></svg>

How to do transparent circle on SVG image?

I'm working on SVG game like Worms, but i don´t know how to do SVG terrain. I have created bitmap with logic ( when a bullet hits terrain, it makes crater). And now i got idea i give SVG terrain (img) on bitmap and everytime the bullet hits terrain, it draws svg circle. I know how to do svg circle, but i can´t see background, because the circle hides my background.
So my question is: How can i make transparent circle on SVG image ?
This is what i did https://imgur.com/a/bPHjthi
This is what i want
https://imgur.com/a/ZT54RxI but SVG.
Thanks for help
You can control the background of an svg circle with the fill property, see here. But I'm not sure setting fill: none or fill: transparent is going to achieve what you want, you would simply see the green background trough the circle. So to "cut" out a circle from the green part you would need to use a clipPath, see here;
For this I would use clipPath. In order to clip a circle out of the polygon you will need a path: a rectangle as big as the svg canvas with a circular hole in it:
<svg viewBox="0 0 100 100" width="300">
<path d="M0,0h100v100h-100v-100M60,50a10,10 0 0 0 -20,0a10,10 0 0 0 20,0" />
</svg>
The path is builded out of a rect: M0,0h100v100h-100v-100M60,50 drawn clockwise and a circle drawn counterclockwise. For a circle with a radius of 10 and the center in the {x:50,y:50} you would do something like this: M60,50a10,10 0 0 0 -20,0a10,10 0 0 0 20,0.
Next you use this path as a clipping path to perforate the polygon:
svg{border:1px solid;background:gold}
<svg viewBox="0 0 100 100" width="300">
<clipPath id="clip">
<path d="M0,0h100v100h-100v-100
M60,50a10,10 0 0 0 -20,0a10,10 0 0 0 20,0" />
</clipPath>
<polygon points="0,90 70,30 100,80 100,100 0,100" clip-path="url(#clip)" />
</svg>
If you need to cut several circles out of the polygon you need to change the d attribute for the clipping path by adding a new circle like so:
d="M0,0h100v100h-100v-100
M60,50a10,10 0 0 0 -20,0a10,10 0 0 0 20,0
M40,60a10,10 0 0 0 -20,0a10,10 0 0 0 20,0"
And this is a demo:
svg{border:1px solid;background:gold}
<svg viewBox="0 0 100 100" width="300">
<clipPath id="clip">
<path d="M0,0h100v100h-100v-100
M60,50a10,10 0 0 0 -20,0a10,10 0 0 0 20,0
M40,60a10,10 0 0 0 -20,0a10,10 0 0 0 20,0" />
</clipPath>
<polygon points="0,90 70,30 100,80 100,100 0,100" clip-path="url(#clip)" />
</svg>
To draw a transparent circle in svg you should use the command circle attribute fill=none like this:
<svg viewbox "0 0 200 200" width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<view id="one" viewBox="0 0 200 200" />
<circle cx="100" cy="100" r="40" stroke="red" stroke-width="5" fill=none />
<circle cx="100" cy="100" r="60" stroke="blue" stroke-width="5" fill=none />
</svg>

Removing pixelated edges from svg image

I have got an SVG image which I need to put in the header of my webpage. The edges of the image are pixelated and this bothers me. Now my question is if there is some kind of way to remove these pixelated edges from the SVG. Below is an example of my SVG.
The orange part is the SVG image I'm talking about.
Check the shape-rendering attributes of your SVG objects. The default setting should look pretty smooth, but with shape-rendering="crispEdges" it's going to look a bit jagged.
<svg width="300" height="100" viewBox="0 0 300 100">
<path d="M-10 0 C 100 70 200 50 310 40" stroke="orange" fill="transparent"
stroke-width="60" shape-rendering="auto"/>
<text x="10" y="90">(auto)</text>
</svg>
<svg width="300" height="100" viewBox="0 0 300 100">
<path d="M-10 0 C 100 70 200 50 310 40" stroke="orange" fill="transparent"
stroke-width="60" shape-rendering="crispEdges"/>
<text x="10" y="90">(crispEdges)</text>
</svg>

Turn off anti-aliasing on svg when applying CSS3:Zoom on the element?

I found that when the CSS3 Zoom is applied on small SVG icons (9px:9px with zoom: 1.5), the SVG icons could be blurry. Any idea to get a sharp and clean icon in this case? Thanks in advance.
The SVG:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"
x="0px" y="0px" width="9px" height="9px" viewBox="0 0 9 9" enable-background="new 0 0 9 9">
<g>
<g fill="none" transform="translate(0.5, 0.5)">
<g stroke="#000000" stroke-width="0.5" stroke-linecap="square" >
<line x1="2" y1="4" x2="6" y2="4"/>
<line x1="4" y1="2" x2="4" y2="6"/>
</g>
<g stroke="#909090" stroke-width="1" stroke-linecap="square" >
<rect x="0" y="0" width="8" height="8"/>
</g>
</g>
</g>
</svg>
Got a solution myself. The trick is adding:
shape-rendering="crispEdges"
to the SVG elements.
From Mozilla MDN:
crispEdges
Indicates that the user agent shall attempt to emphasize the contrast between clean edges of artwork over rendering speed and geometric precision. To achieve crisp edges, the user agent might turn off anti-aliasing for all lines and curves or possibly just for straight lines which are close to vertical or horizontal. Also, the user agent might adjust line positions and line widths to align edges with device pixels.
See the difference on jsFilddle.

Resources