How do I perfectly center a single character inside an SVG circle? - svg

I'd like to place a single character, perfectly centered, inside this circle:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" width="100" height="100">
<g>
<circle style="fill:#eeeeee" cx="50" cy="50" r="50">
</circle>
<text>C</text>
</g>
</svg>
Ideally, the solution works for any single ASCII character.
Thanks for the help!

Use a combination of text-anchor="middle" to centre the text horizontally, and dominant-baseline="central" to centre it vertically.
To simplify things, I've added a transform attribute to your <g> element to move the origin to the middle of your canvas.
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
<g transform="translate(50,50)">
<circle style="fill:#eeeeee" r="50" />
<text text-anchor="middle" dominant-baseline="central">C</text>
</g>
</svg>

Related

SVG Chrome Rendering Bug with Dominant Baseling inside Group Transform

The second X in the circle below is aligned vertical centrally on Firefox but not on Chrome, is this a bug?
The first X is aligned correctly on both.
<svg height="200">
<circle cx="100" cy="100" r="100" fill="red"></circle>
<text x="100" y="100" dominant-baseline="central" text-anchor="middle" font-size="50">X</text>
</svg>
<svg width="340px" height="100px" viewBox="0 0 100 29.41"><g transform="translate(8.333333333333334 7.500000000000001) scale(15.000000000000002 15.000000000000002)"><circle cx="0" cy="0" r="0.5" fill="red"></circle><text x="0" y="0" dominant-baseline="central" text-anchor="middle" font-size="0.4">X</text></g></svg>

Clip Path not working in an SVG element

I'm trying to get a rectangular <clipPath> to clip a <circle> in an SVG element, but I can't seem to get it work.
Does anyone know what the problem is?
Many thanks in advance for any help.
Codepen: https://codepen.io/emilychews/pen/jpLMaV
Em
#circle {width: 10rem;}
<defs>
<clipPath id="myClipPath">
<rect x="30" y="30" width="100" height="100"/>
</clipPath>
</defs>
<svg id="circle" style="clip-path: url(#myClipPath)" viewBox="0 0 391 391">
<circle fill="#000" cx="195.5" cy="195.5" r="195"/>
</svg>
You forget <svg> around your clip path declaration .
<svg width=0 height=0 >
<defs>
<clipPath id="myClipPath">
<rect x="50px" y="50px" width="200px" height="200px"/>
</clipPath>
</defs>
</svg>
<svg style="clip-path: url(#myClipPath)" id="circle" width="400" height="400">
<circle fill="#000" cx="100px" cy="100px" r="100px"/> </svg>
edit: i simplified and i added a witdh and height attribute

How to size an SVG

I am trying to create an SVG sprite.
I have set the SVG image to be 100px wide, 50px height, then offset the second by 50.
How can I set the size of the actual icon? Currently, the icon is huge and not 50px.
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100px"
height="50px">
<defs>
<g id="arrow">
<path d="M378.135,227.256L206.224,55.354c-12.354-12.359-12.354-32.394,0-44.748c12.354-12.359,32.388-12.359,44.747,0
L445.258,204.89c6.177,6.18,9.262,14.271,9.262,22.366c0,8.098-3.091,16.195-9.262,22.372L250.971,443.91
c-12.359,12.365-32.394,12.365-44.747,0c-12.354-12.354-12.354-32.391,0-44.744L378.135,227.256z M9.265,399.166
c-12.354,12.354-12.354,32.391,0,44.744c12.354,12.365,32.382,12.365,44.748,0l194.287-194.281
c6.177-6.177,9.257-14.274,9.257-22.372c0-8.095-3.086-16.192-9.257-22.366L54.013,10.606c-12.365-12.359-32.394-12.359-44.748,0
c-12.354,12.354-12.354,32.388,0,44.748L181.18,227.256L9.265,399.166z"/>
</g>
</defs>
<use x="0" y="0" style="fill: #333" xlink:href="#arrow" />
<use x="50" y="0" style="fill: #999" xlink:href="#arrow" />
</svg>
This is what I see:
DO NOT USE TRANSFORM FOR SCALING
What you are missing is a defined viewBox.
If you do not define a viewBox the viewBox is the same size as the height and width that you defined.
So when you draw a path and some of its point are above 370 then they will be outside its container. Since your defined size is 100 width by 50 height. Any point with values higher then the size will not be drawn.
when you define a viewBox you can change the size without affecting what is drawn or not.
This is the article i allways use when i forget how to properly scale svgs: https://css-tricks.com/scale-svg/
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100px"
height="50px"
viewBox="0 0 500 500">
<defs>
<g id="arrow">
<path d="M378.135,227.256L206.224,55.354c-12.354-12.359-12.354-32.394,0-44.748c12.354-12.359,32.388-12.359,44.747,0
L445.258,204.89c6.177,6.18,9.262,14.271,9.262,22.366c0,8.098-3.091,16.195-9.262,22.372L250.971,443.91
c-12.359,12.365-32.394,12.365-44.747,0c-12.354-12.354-12.354-32.391,0-44.744L378.135,227.256z M9.265,399.166
c-12.354,12.354-12.354,32.391,0,44.744c12.354,12.365,32.382,12.365,44.748,0l194.287-194.281
c6.177-6.177,9.257-14.274,9.257-22.372c0-8.095-3.086-16.192-9.257-22.366L54.013,10.606c-12.365-12.359-32.394-12.359-44.748,0
c-12.354,12.354-12.354,32.388,0,44.748L181.18,227.256L9.265,399.166z"/>
</g>
</defs>
<use x="0" y="0" style="fill: #333" xlink:href="#arrow" />
<use x="50" y="0" style="fill: #999" xlink:href="#arrow" />
</svg>
Like this? I just added transform="scale(0.1)" attribute to the g tag to make it 10x smaller
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100px"
height="50px">
<defs>
<g id="arrow" transform="scale(0.1)">
<path d="M378.135,227.256L206.224,55.354c-12.354-12.359-12.354-32.394,0-44.748c12.354-12.359,32.388-12.359,44.747,0
L445.258,204.89c6.177,6.18,9.262,14.271,9.262,22.366c0,8.098-3.091,16.195-9.262,22.372L250.971,443.91
c-12.359,12.365-32.394,12.365-44.747,0c-12.354-12.354-12.354-32.391,0-44.744L378.135,227.256z M9.265,399.166
c-12.354,12.354-12.354,32.391,0,44.744c12.354,12.365,32.382,12.365,44.748,0l194.287-194.281
c6.177-6.177,9.257-14.274,9.257-22.372c0-8.095-3.086-16.192-9.257-22.366L54.013,10.606c-12.365-12.359-32.394-12.359-44.748,0
c-12.354,12.354-12.354,32.388,0,44.748L181.18,227.256L9.265,399.166z"/>
</g>
</defs>
<use x="0" y="0" style="fill: #333" xlink:href="#arrow" />
<use x="50" y="0" style="fill: #999" xlink:href="#arrow" />
</svg>

Grouping several SVG's into one object

I'm trying to reuse an SVG sprite icone into new SVG object.
The new object is just a circle that contains the icon from the sprite.
I understand that I need to use the defs tag to group some shapes together,
But i have have a problem referencing my sprite icone inside the defs tag.
sprite:
<svg style="display:none;">
<symbol id="icon_1" viewBox="0 0 54 54">
<path d="M10.6 29.3h14.5V44H10.6z" class="st0"/>
<path d="M25 29.3h14.5V44H25zm-7.2-14.7h14.5v14.7H17.8zm0 0l3.9-4m10.6 4l3.9-4m-3.9 18l3.9-3.7m-25.6 4.4l4.3-4.4m24.6 4.7l3.9-4M39.5 44l3.9-4M21.2 10.6h15M14.5 24.9h3.3m17.7.6h7.9M36.2 10v15.5m7.2.1V40" class="st0"/>
</symbol >
new object:
<svg><defs>
<g id="shape">
<circle cx="40" cy="40" r="40" fill="rgba(124,240,10,0.5)" />
<image x="0" y="0" xlink:href="#icon_1"></image>
</g>
I read that i can use image tags to reference SVG elements.
obviously i'm doing something wrong.
Basically the expected result should be a stroked circle with the icon inside
in a way that I will be able to animate the entire object
Thanks
You were close. Your main problem was that you were careless with your opening and closing tags.
Your second SVG had a stray opening <defs> element, which meant that the <g id="shape"> element was left inside the <defs> section. <defs> is for defining elements to be re-used later, and anything in a <defs> will only be drawn when referenced from elsewhere.
There were a couple of other problems.
You can't use an <image> to reference a symbol. You will need to use a <use> for that.
You will need to supply a width and height so that the symbol gets draw at an appropriate size.
<svg width="0" height="0">
<defs>
<symbol id="icon_1" viewBox="0 0 54 54">
<path d="M10.6 29.3h14.5V44H10.6z" class="st0"/>
<path d="M25 29.3h14.5V44H25zm-7.2-14.7h14.5v14.7H17.8zm0 0l3.9-4m10.6 4l3.9-4m-3.9 18l3.9-3.7m-25.6 4.4l4.3-4.4m24.6 4.7l3.9-4M39.5 44l3.9-4M21.2 10.6h15M14.5 24.9h3.3m17.7.6h7.9M36.2 10v15.5m7.2.1V40" class="st0"/>
</symbol>
</defs>
</svg>
new object:
<svg>
<g id="shape">
<circle cx="40" cy="40" r="40" fill="rgba(124,240,10,0.5)" />
<use x="0" y="0" width="80" height="80" xlink:href="#icon_1"></use>
</g>
</svg>
The image tag is designed to be used with complete images, not fractions. I guess that use is the right tag for your use case.
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1">
<symbol id="icon_1" viewBox="0 0 54 54">
<path d="M10.6 29.3h14.5V44H10.6z" class="st0"/>
<path d="M25 29.3h14.5V44H25zm-7.2-14.7h14.5v14.7H17.8zm0 0l3.9-4m10.6 4l3.9-4m-3.9 18l3.9-3.7m-25.6 4.4l4.3-4.4m24.6 4.7l3.9-4M39.5 44l3.9-4M21.2 10.6h15M14.5 24.9h3.3m17.7.6h7.9M36.2 10v15.5m7.2.1V40" class="st0"/>
</symbol>
<defs>
<g id="shape">
<circle cx="40" cy="40" r="40" fill="rgba(124,240,10,0.5)" />
<use x="2" y="-3" width="80" height="80" xlink:href="#icon_1"/>
</g>
</defs>
<use xlink:href="#shape"/>
</svg>
Also, if the sprite is in a separate file, you have to reference the symbol within that file: <use hlink:href="sprites.svg#icon1"/>.

Make SVG element transparent (like a mask)

How can I use the polygon as a mask, which will make the area in the circle transparent?
I cannot manage it
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" />
<polygon points="20,30 25,20 80,40 80,60 25,80, 20,70 70,50"/>
</svg>
Masks are quite simple. They are described here: http://www.w3.org/TR/SVG11/masking.html#Masking
In your case, it is just a matter of adding a few lines.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="50" mask="url(#hole)"/>
<mask id="hole">
<rect x="0" y="0" width="100" height="100" fill="white"/>
<polygon points="20,30 25,20 80,40 80,60 25,80, 20,70 70,50" fill="black"/>
</mask>
</svg>
In the mask definition, we have to add a white rectangle the size of the circle to make the <circle> visible (white means opaque), and we make the <polygon> black (transparent) to create the hole.
Fiddle here
I'd say try using Inkscape to make an SVG file, draw your items on each other, select them both and use the Path->Exclusion menu to do so. Save your file and then you can look at the code of the .svg file to see what it did.

Resources