Is there any possible way to get/find the border radius of an SVG?
Specifically, the rounded corners.
Example:
<svg width="266" height="185" viewBox="-1.5 0 71 48">
<path fill="currentColor" style="stroke: #0059dd; stroke-width:1px;color:black;" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z" fill="#000000" ></path><path d="M 45,24 27,14 27,34" fill="#0059dd"></path>
</svg>
Related
I have the following generated test-SVG (excerpt).
<svg _ngcontent-dhk-c13=""><g _ngcontent-dhk-c13="" hccard="" _nghost-dhk-c12="" ng-reflect-card="[object Object]"><rect _ngcontent-dhk-c12="" id="8261337b-fb4b-4ac9-a213-0d86cc3dc604" width="100" height="100" x="750" y="450"></rect><g _ngcontent-dhk-c12="" hcedge="" _nghost-dhk-c11="" ng-reflect-edge="[object Object]"><path _ngcontent-dhk-c11="" stroke="black" stroke-width="2" d="M 750 450 L 750 600 Z"></path></g><g _ngcontent-dhk-c12="" hcedge="" _nghost-dhk-c11="" ng-reflect-edge="[object Object]"><path _ngcontent-dhk-c11="" stroke="black" stroke-width="2" d="M 750 450 L 750 600 Z"></path></g><!--bindings={
"ng-reflect-ng-for-of": "[object Object],[object Object"
}--></g><!--bindings={
"ng-reflect-ng-for-of": "[object Object],[object Object"
}--></svg>
There should be a <path> element going from 750/450 to 750/600. However nothing is visible. If i move the <path> element outside of its <g> container into the <g> container above that also holds the red <rect>, it is suddenly visible. Any other way to fix this, other than moving the <path> out of the inner <g>?
As #enxaneta said, the rect and path in your SVG are way outside its default viewport. A viewport is the area on your page that the SVG contents are rendered into.
If we use some CSS to make the viewport size visible (light brown area) and make overflow visible, we can see what's happening.
svg {
background-color: linen;
overflow: visible;
transform: scale(0.5);
}
<svg>
<g>
<rect width="100" height="100" x="750" y="450"></rect>
<g>
<path stroke="black" stroke-width="2" d="M 750 450 L 750 600 Z"></path>
</g>
<g>
<path stroke="black" stroke-width="2" d="M 750 450 L 750 600 Z"></path>
</g>
</g>
</svg>
If you want to fix that, you'll need to do one of two things:
Make the viewport bigger
In the example below, I have made the SVG width and height big enough so that the content is now visible. You may need to scroll down and right to see it.
svg {
background-color: linen;
}
<svg width="850" height="600">
<g>
<rect width="100" height="100" x="750" y="450"></rect>
<g>
<path stroke="black" stroke-width="2" d="M 750 450 L 750 600 Z"></path>
</g>
<g>
<path stroke="black" stroke-width="2" d="M 750 450 L 750 600 Z"></path>
</g>
</g>
</svg>
Tell the browser where in the SVG your elements are, so that it can draw them inside the viewport. You do this by adding a viewBox.
In the example below, I've chosen viewBox values that define the boundaries of the content. The browser is scaling and moving that content so that it fits in the viewport.
svg {
background-color: linen;
width: 400px;
height: 400px;
}
<svg viewBox="750 450 100 150">
<g>
<rect width="100" height="100" x="750" y="450"></rect>
<g>
<path stroke="black" stroke-width="2" d="M 750 450 L 750 600 Z"></path>
</g>
<g>
<path stroke="black" stroke-width="2" d="M 750 450 L 750 600 Z"></path>
</g>
</g>
</svg>
I have a curved svg line like this
<path d="M70,260 C105,260 126,330 160,330"
style="stroke: #ff4444;stroke-width:2; fill:none;"/>
what I want is to add another svg (like https://www.flaticon.com/free-icon/play-button_149657) in the middle of my line pointing to the end point.
any ideas?
One way to achieve the result is a degenerate animation:
Define the marker shape (obj1 in the example below)
Position the marker at the beginning of the curve (track1 below; this is the path definition from your example).
Specify an animated motion of the marker shape along the curve with some particular settings:
Explicit positioning along the track using keyTimes, keyPoints attributes, limiting the range of positions to exactly one point: the midpoint of the curve
Infinite duration, infinite repeat
Auto-rotation of the shape according to the orientation of the track curve ( rotate attribute )
Effectively there is no animation at all but the shape is positioned at the center of the curve, properly oriented.
Example
<html>
<head>
<title>SVG object centered on path</title>
</head>
<body>
<svg width="200px" height="200px"
viewBox="0 0 500 500"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<path
id="obj1"
d="M11.18,0 L-2.5,10 -2.5,-10 Z"
stroke="black" stroke-width="1" fill="green"
>
</path>
<path
id="track1"
d="M70,260 C105,260 126,330 160,330"
stroke="#ff4444" stroke-width="2" fill="none"
/>
</defs>
<use xlink:href="#track1"/>
<use xlink:href="#obj1">
<animateMotion
calcMode="linear"
dur="infinite"
repeatCount="infinite"
rotate="auto"
keyPoints="0.5;0.5"
keyTimes="0.0;1.0"
>
<mpath xlink:href="#track1"/>
</animateMotion>
</use>
</svg>
</body>
</html>
There are a number of ways to do this.
One way is to "cheat" a little and use a <textPath> and an arrow character.
SVG marker-mid on specific point on path
This is a little hacky, and may not work reliably on all browsers, but it may be good enough for your needs.
Another way is split the path in two (using De Casteljau's algorithm), and use a <marker>.
<svg viewBox="0 200 200 200" width="400">
<defs>
<marker id="Triangle"
viewBox="0 0 10 10" refX="0" refY="5"
markerUnits="strokeWidth"
markerWidth="4" markerHeight="3"
orient="auto">
<path d="M 0 0 L 10 5 L 0 10 z" />
</marker>
</defs>
<path d="M 70,260
C 87.5,260 101.5,277.5 115.375,295
C 129.25,312.5 143,330 160,330"
style="stroke: #ff4444; stroke-width:2; fill:none; marker-mid:url(#Triangle)"/>
</svg>
There are other ways using Javascript. For example, you could use the SVGPathElement.getPointAtLength() method to find the coordinates of the centre of the path. Then position a triangle at that location.
I have an embedded svg that is will only stretch to about 2/3 of it's container size. I would like to get it to fill the entire container.
Here's how it currently looks:
I have a plunker here showing the embedded svg: http://plnkr.co/edit/5PbBmhV6aBiAtanXTVgM
The simplified svg structure is like this:
<svg id="approach_shot" viewBox="0 0 360 360" preserveAspectRatio="xMinYMin meet" class="content">
<rect fill="#FFFFFF" stroke="#000000" stroke-width="0.5" width="360" height="360"></rect>
<g id="green">
<defs>
<circle id="ball" r="6" stroke="#000000" fill="#FFFFFF" stroke-width="0.5"></circle>
</defs>
<g>
<path fill="#005C1F" stroke="#005C1F" stroke-width="0.75" stroke-miterlimit="10" d="M42.09 171.26c-10.48-25.3-9.77-52.43-0.17-75.92l-18.48-7.65c-11.56 28.22-12.42 60.83 0.17 91.23 0.08 0.2 0.17 0.4 0.25 0.6l18.48-7.65C42.26 171.65 42.17 171.46 42.09 171.26z"/>
more paths...
</g>
<g id="shots">
<use xlink:href="#ball" transform="translate(150,150) scale(1.0)" />
</g>
</g>
</svg>
I've been hacking on this for a few hours, and nothing I do impacts that green image. The outer rectangle fills the container just fine.
Thanks for your help!
The simplest way is to fix your viewBox attribute. You currently have it set to a width and height of 360, when your circle is only about 247 in diameter.
The top-left of the circle is at roughly (11, 9.5), so changing your viewBox to:
viewBox="11 9.5 247 247"
will cause it to fill your viewport.
How did I determine the dimensions of the circle? I used a little bit of javascript and called the getBBox() function on the element with id="green".
var b = document.getElementById("green").getBBox();
alert(b.x+" "+b.y+" "+b.width+" "+b.height);
Demo here
I need to place text relative to the parent <g>.
Currently, I have a path and a text element wrapped in a <g>. But all the text coordinates are relative to the outer most <g>.
<svg width="1000" height="550">
<g transform="translate(500,275)" stroke-width="2" stroke="black">
<g>
<path d="M1.6838893488276108e-14,-275A275,275 0 0,1 238.15698604072065,137.49999999999994L0,0Z" id="path_0" style="fill: rgb(17, 17, 17);"></path>
<text transform="translate(100, 100)" class="tooltipText" stroke-width="0" fill="white" style="text-anchor: middle;">text</text>
</g>
<g>
<path d="M238.15698604072065,137.49999999999994A275,275 0 0,1 -238.1569860407206,137.50000000000009L0,0Z" id="path_1" style="fill: rgb(34, 34, 34);"></path>
<text transform="translate(100, 100)" class="tooltipText" stroke-width="0" fill="white" style="text-anchor: middle;">text</text>
</g>
<g>
<path d="M-238.1569860407206,137.50000000000009A275,275 0 0,1 -5.051668046482832e-14,-275L0,0Z" id="path_2" style="fill: rgb(51, 51, 51);"></path>
<text transform="translate(100, 100)" class="tooltipText" stroke-width="0" fill="white" style="text-anchor: middle;">text</text>
</g>
</g>
</svg>
It's hard to see which part of this you're having trouble with, but I'll explain as best I can.
Your SVG picture is 1000 pixels wide and 550 pixels tall:
<svg width="1000" height="550">
The top level node inside this SVG is a <g> node that moves the origin of the coordinate system from the top left corner to (500,275) (i.e., the middle of the drawing area; Y coordinates increase from top to bottom in SVGs)
<g transform="translate(500,275)" ... >
All the children of this top-level node will therefore use this transformed coordinate system. You have added additional <g> nodes as children of this top-level node, but they don't really do anything in this instance because they contain no attributes:
<g>
As a result, the <path> nodes will still be using the same transformed coordinate system that was set up by the top-level <g>. These all produce circular sectors with an apex at (0,0). And since (0,0) corresponds to the middle of the drawing area in this transformed coordinate system, that is where they end up:
<path d="M0-275A275 275 0 0 1 238 137.5L0 0Z" style="fill: rgb(17, 17, 17);"></path>
<path d="M238 137.5A275 275 0 0 1-238 137.5L0 0Z" style="fill: rgb(34, 34, 34);"></path>
<path d="M-238 137.5A275 275 0 0 1 0-275L0 0Z" style="fill: rgb(51, 51, 51);"></path>
Your <text> nodes are also drawn in this coordinate system, but offset by (100,100) because you added a transform attribute to shift them 100 pixels down and 100 pixels to the right:
<text transform="translate(100, 100)" ... >text</text>
So the end result is that all three of your text nodes are drawn at coordinates of (600,375) relative to the top left corner of the drawing area. If you want the text to appear somewhere else, you'll have specify a different offset. For example:
<text transform="translate(120,-80)" ... >text</text>
<text transform="translate(0,160)" ... >text</text>
<text transform="translate(-120,-80)" ... >text</text>
<svg width="1000" height="550">
<g transform="translate(500,275)" stroke-width="2" stroke="black">
<g>
<path d="M0-275A275 275 0 0 1 238 137.5L0 0Z" style="fill: rgb(17, 17, 17);"></path>
<text transform="translate(120,-80)" class="tooltipText" stroke-width="0" fill="white" style="text-anchor: middle;">text</text>
</g>
<g>
<path d="M238 137.5A275 275 0 0 1-238 137.5L0 0Z" style="fill: rgb(34, 34, 34);"></path>
<text transform="translate(0,160)" class="tooltipText" stroke-width="0" fill="white" style="text-anchor: middle;">text</text>
</g>
<g>
<path d="M-238 137.5A275 275 0 0 1 0-275L0 0Z" style="fill: rgb(51, 51, 51);"></path>
<text transform="translate(-120,-80)" class="tooltipText" stroke-width="0" fill="white" style="text-anchor: middle;">text</text>
</g>
</g>
</svg>
I've tried unsuccessfully to replace the white triangle, the marker-start, with an inverse mask/clip-path in order to cut the end of the arrow in shape of the marker instead of painting it white.
Not sure if marker masks can be defined.
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" id="mySVG" viewBox="-100 0 200 200" height="600" width="700">
<defs>
<marker refY="0.5" refX="0.0" markerHeight="4" markerWidth="2" orient="auto" id="head">
<path fill="#D0D0D0" d="M0,0 L0.5,0.5 L0,1 L-0.5,0.5 Z"/>
</marker>
<marker refY="0.6" refX="0.1" markerHeight="4" markerWidth="2" orient="auto" id="tail">
<clip-Path id="cp1" d="M0 0 V1.3 L0.6 0.6 Z">
<path fill="white" d="M0 0 V1.3 L0.6 0.6 Z" />
<clip-Path>
</marker>
</defs>
<path id="myArrow" marker-start="url(#tail)" marker-end="url(#head)" d="M -66.38265586443396 22.21132594835645 A 70 70 0 0 0 66.38265586443396 22.21132594835645" fill="none" stroke="#D0D0D0" stroke-width="8" clip-path="url(#cp1)"/>
Markers are independent symbols which are positioned and drawn at the various points in the path after the path has been drawn.
It sounds like you are trying to use them to clip out bits of the path. This is futile. That's not how markers work, I'm afraid.