I would like to vertically/horizontally center a text inside a rectangle made with a SVG Path element.
By center I don't mean having my first letter at the center of the rectangle but having the center of my text at the center of the path.
Here is my code structure:
<svg id="shape">
<path id = "a" d="M 0 0 L 100 0 L 100 100 L 0 100 Z"></path>
<text>
<textPath xlink:href="#a">My Text</textPath>
</text>
</svg>
I've managed to achieve that by doing something like this:
<svg id="shape">
<path id = "a" d="M 0 0 L 100 0 L 100 100 L 0 100 Z"></path>
<text x="50" y="50" text-anchor="middle" alignement-baseline="middle">My Text</text>
</svg>
Related
I am trying to make a shape like this
and i managed to get this sofar
But i cant get the right arc to go outwards instead of inwards.
I cant find any help online how to do this. I tried rotation and playing around with the rx,ry but no luck.
Here is the JSFiddle to it
JsFiddle
<svg height="200" width="300">
<g stroke="none" fill="blue">
<path d="
M 150 0
a 1 1 0 0 0 0 100
l -100 0
a 1 1 0 0 0 0 -100
l 100 0
Z
"/>
</g>
</svg>
On the first arc, you simply need to flip the sweep-flag to "clockwise":
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#elliptical_arc_curve
<svg height="200" width="300">
<g stroke="none" fill="blue">
<path d="
M 150 0
a 1 1 0 0 1 0 100
l -100 0
a 1 1 0 0 0 0 -100
l 100 0
Z
"/>
</g>
</svg>
AngularJS app.
Basically I've to make an horizontal arrow-like drawing with images that will be repeating inside depending on the array of items i sent to the html(ng-repeat).
I got told the best would be svg so here I am, but my knowledge of svg is pretty low. So I managed to make a little arrow with fixed witdh and height. But now I need it a lot bigger.
So I read about viewBox online. It scales the items I have in the SVG, but I have two problems so far.
Images don't work.
All items are stacked up and don't follow the space in between them that I had before.
This code is the working code I have right now, so you get an idea of the element I'm trying to draw. I use the element so I can ng-repeat it with tooltips and text inside, this code is simplified.
.container {
display: flex;
}
.justaclass {
fill: #9b3d9c;
background-color: #9b3d9c;
}
.justaclass-group {
display: inline-block;
position: relative;
}
.justaclass-image {
padding: 2px;
}
<div class="container">
<svg width="8" height="34">
<path class="justaclass"
d="M 0 0 L 7 17 L 0 34 L 17 34 L 17 0 z">
</path>
</svg>
<svg width="33" height="34" class="justaclass justaclass-image">
<image x="0" y="3" width="33" height="25" href="https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg"></image>
</svg>
<div class="justaclass-group">
<svg width="50" height="34" class="justaclass image">
<image width="45" height="30"
x="0" y="0"
href="https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg">
</image>
</svg>
<svg width="10" height="34">
<path class="justaclass"
d="M 0 0 L 0 34 L 10 17 z">
</path>
</svg>
</div>
The code isn't perfect pixel-wise here, but that's not my main issue.
Now that I try to make it bigger with viewBox, I can draw the 4 elements but they are misplaced. So If I add display:flex or display:table I quite cannot get the elements aligned horizontally, the elements just disappear.
Anyone got any idea of how to dinamically resize all this elements plus making them all in the same line just like display flex would do?
My first try at doing the above image with viewBox
But If I add display:flex into the container, the svg's are gone and I only see images.
.container {}
.justaclass {
fill: #9b3d9c;
background-color: #9b3d9c;
}
<div class="container">
<svg viewBox="0 0 150 50">
<path class="justaclass"
d="M 0 0 L 7 17 L 0 34 L 17 34 L 17 0 z">
</path>
</svg>
<svg viewBox="0 0 150 50">
<image width="150" height="50" href="https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg"></image>
</svg>
<svg viewBox="0 0 150 50">
<image width="150" height="50" href="https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg"></image>
</svg>
<svg viewBox="0 0 150 50">
<path class="justaclass"
d="M 0 0 L 0 34 L 10 17 z">
</path>
</svg>
</div>
There are a lot of things that need to change here. First lets talk about viewBox. This attribute describes how the numbers inside the <svg> tag relate to those outside. It gives a rectangle into which the inside content is rendered. Then, this rectangle is scaled such that it fits into the size given by width and height. That means, giving a viewBox without also defining width and height makes not much sense, as the size the content should be scaled to is missing.
What happens if the aspect ratio of the viewBox and that of the width and height do not match? As a default, the content is set into the middle and scaled such that it just fits. Other values can be given with the preserveAspectRatio attribute. For example, to get the left "arrow" part to the right of its rectangle (so there is no gap), set preserveAspectRatio="xMaxYMid meet".
width and height can be given as attributes for SVG content or as CSS properties. It makes sense to define them as styles if they are to be changeable.
Your linked images do not need to have a concrete size. Giving them width="100%" height="100%" scales them to the containing SVG element, without distorting them (unless you define so with preserveAspectRatio="none".
.container {
display: flex;
}
.container svg {
width: 50px;
height: 50px;
}
.container .justaclass {
fill: #9b3d9c;
background-color: #9b3d9c;
width: 150px;
}
<div class="container">
<svg width="50" height="50" viewBox="0 0 8 34" preserveAspectRatio="xMaxYMid meet">
<path
d="M 0 0 L 7 17 L 0 34 L 17 34 L 17 0 z">
</path>
</svg>
<svg class="justaclass">
<image width="100%" height="100%" href="https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg"></image>
</svg>
<svg class="justaclass">
<image width="100%" height="100%" href="https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg"></image>
</svg>
<svg viewBox="0 0 10 34" preserveAspectRatio="xMinYMid meet">
<path
d="M 0 0 L 0 34 L 10 17 z">
</path>
</svg>
</div>
viewBox defines the size of the contents of the svg before being scaled. You need to set them to the original size of your image and then scale the elements up either with the width and height tags you used before or with css. Here's a fiddle of everything scaled up to double size: https://jsfiddle.net/ohnqbufa/
You can see here that the viewport of your first element is set to the original size and the width and height are set to double.
<svg width="16" height="68" viewBox="0 0 8 34">
<path class="justaclass"
d="M 0 0 L 7 17 L 0 34 L 17 34 L 17 0 z">
</path>
</svg>
I am working with individual SVG paths and when there is a path join , need a mitre effect.Its quite new for me.
SVG shape looks like polygon , with each side as individual path.
Sample of my SVG code , does not display the original Polygon. Please see image for o/p:
<svg viewBox="0 0 330 330">
<g id="v-3" class="joint-viewport">
<g model-id="db69ee92-054d-4ce5-9300-ae09f385d9f2" id="j_1" class="joint-cell joint-type-custom joint-type-custom-line joint-element joint-theme-default" data-type="custom.Line" transform="translate(90,90)">
<g class="rotatable" id="v-12">
<g class="scalable" transform="scale(2.5,3.75)">
<path class="path0" id="v-13" d="M 0 0 L 30 0" stroke="#806476" stroke-width="15" cursor="pointer" event="element:path-click" stroke-linecap="square"></path>
<path class="path1" id="v-14" d="M 30 0 L 30 20" stroke="#181972" stroke-width="15" cursor="pointer" event="element:path-click" stroke-linecap="square"></path>
<path class="path2" id="v-15" d="M 30 20 L 60 20" stroke="#91a19b" stroke-width="15" cursor="pointer" event="element:path-click" stroke-linecap="square"></path>
<path class="path3" id="v-16" d="M 60 20 L 60 40" stroke="#f24167" stroke-width="15" cursor="pointer" event="element:path-click" stroke-linecap="square"></path>
<path class="path4" id="v-17" d="M 60 40 L 0 40" stroke="#21e578" stroke-width="15" cursor="pointer" event="element:path-click" stroke-linecap="square"></path>
<path class="path5" id="v-18" d="M 0 40 L 0 0" stroke="#cf2fe0" stroke-width="15" cursor="pointer" event="element:path-click" stroke-linecap="square"></path>
</g>
</g>
</g>
</g>
</svg>
The below image link of SVG shows the polygon shape. When I click on individual paths , the intersection should change as first path over the second , second path over the first and then the mitre effect. I achieved the other two , but not the mitre effect.
SVG shape
The second image link shows the transition for each mouse click.I need to know the mitre/diagonal effect as shown in last figure.
Image 3
If its the single svg , then mitre effect can be done with line-join.
How to have the mitre effect here ?
In order to get the miter you need to use shapes instead of strokes. You can do it by hand if you think that the miter is an isosceles right triangle whose catheti = 15.
<svg viewBox="0 0 300 300" width="200">
<path id="_1" d="M50,50L150,50 135,65 65,65z" fill="#806476"/>
<path id="_2" d="M150,50L150,150 135,165 135,65z" fill="#181972"/>
<path id="_3" d="M150,150 L250,150 235,165 135,165z" fill="#91a19b" />
<path id="_4" d="M250,150L250,250 235 235 235 165z" fill="#f24167"/>
<path id="_5" d="M250,250L50,250 65,235 235 235z" fill="#21e578"/>
<path id="_6" d="M50,250L50,50 65,65 65,235z" fill="#cf2fe0" />
</svg>
I want to draw a partial arc using SVG. According to the docs, the centre of the circle is calculated automatically. But my arc overflows the circle. It is easier to demonstrate it with a picture:
<svg width="500px" height="500px" viewBox="0 0 100 100" style="border: navy solid 1px;">
<g transform="translate(10 10) scale(0.5 0.5)">
<path d="M0 50 A1 1 0 0 1 100 50 Z" fill="blue"></path>
<path d="M0 50 A1 1 0 0 1 50 0 Z" fill="purple" opacity="0.7"></path>
</g>
</svg>
Here is the link to the codepen link.
You can draw arcs before blue circle (as I draw red one) or make redrawing of circle segment (the last line - I made it green to emphasize but must be blue). So combination of circle arc + segment gives moon crescent form
<path d="M50 50 L50 0 A1 1 0 0 1 100 50 Z" fill="red" opacity="0.7"></path>
<path d="M0 50 A1 1 0 0 1 100 50 Z" fill="blue"></path>
<path d="M0 50 A1 1 0 0 1 50 0 Z" fill="purple" opacity="0.7"></path>
<path d="M50 0 A50 50 0 0 0 0 50 Z" fill="green"></path>
I'm trying to get real "path" size, using getBoundingClientRect function for that, but in FireFox I get different results
In Google Chrome all is well:
1. 100px x 100px
2. 100px x 100px
But in FireFox:
1. 104px x 104px
2. 100px x 100px
Why stroke-width="1" added 4px? How to get real size without empty spaces in FF?
<div>With stroke-width="1"</div>
<svg width="110" height="110">
<path stroke-width="1" d="M0 0 L 100 0 L100 100 L 0 100 Z" fill="black" stroke="black"></path>
</svg>
<br>
<br>
<div>With stroke-width="0"</div>
<svg width="110" height="110">
<path stroke-width="0" d="M0 0 L 100 0 L100 100 L 0 100 Z" fill="black" stroke="black"></path>
</svg>
P.S.
I'm triyng to add "line with text" to this path. I get path position+size with getBoundingClientRect function, create new div in those coordinates.
Result:
I made solution for FF. Simple but it works.
last_current.attr('stroke-width',0); // FireFox fix!
let c_pos = last_current[0].getBoundingClientRect();
last_current.attr('stroke-width', 1); // FireFox fix!