如何在边界侧创建带有链接的圆圈
我正在尝试制作一个像
计算完点后,path
本身的编码就很简单了.路径应该从中心点开始和结束(即 50,50),从中心点开始,我们应该先画一条线到 From Point,然后从那里画一条弧线到 To Point.下面是示例 path
的样子:
svg {高度:220px;宽度:220px;}小路 {填充:透明;中风:黑色;}
<svg viewBox='0 0 110 110'><路径d='M55,55 L105,55 A50,50 0 0,1 80,98.30z'/><路径d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z'/><路径d='M55,55 L30,98.30 A50,50 0 0,1 5,55z'/><路径d='M55,55 L5,55 A50,50 0 0,1 30,11.69z'/><路径d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z'/><路径d='M55,55 L80,11.69 A50,50 0 0,1 105,55z'/></svg>
12段圆演示:
对于一个有 12 段的圆,每段将覆盖 30 度,因此点的计算如下表所示:
svg {高度:220px;宽度:220px;}小路 {填充:透明;中风:黑色;}
<svg viewBox='0 0 110 110'><路径d='M55,55 L105,55 A50,50 0 0,1 98.30,80z'/><路径d='M55,55 L98.30,80 A50,50 0 0,1 80,98.30z'/><路径d='M55,55 L80,98.30 A50,50 0 0,1 55,105z'/><路径d='M55,55 L55,105 A50,50 0 0,1 30,98.30z'/><路径d='M55,55 L30,98.30 A50,50 0 0,1 11.69,80z'/><路径d='M55,55 L11.69,80 A50,50 0 0,1 5,55z'/><路径d='M55,55 L5,55 A50,50 0 0,1 11.69,30z'/><路径d='M55,55 L11.69,30 A50,50 0 0,1 30,11.69z'/><路径d='M55,55 L30,11.69 A50,50 0 0,1 55,5z'/><路径d='M55,55 L55,5 A50,50 0 0,1 80,11.69z'/><路径d='M55,55 L80,11.69 A50,50 0 0,1 98.30,30z'/><路径d='M55,55 L98.30,30 A50,50 0 0,1 105,55z'/></svg>
内部未分段的圆圈:
如果它看起来好像中心的圆的一部分(半径较小)看起来是未分割的,并且如果内部不需要是透明的,只需在末尾添加一个额外的圆元素在 SVG 中.
svg {高度:220px;宽度:220px;}小路 {填充:透明;中风:黑色;}圆圈 {填充:黄绿色;中风:黑色;}
<svg viewBox='0 0 110 110'><路径d='M55,55 L105,55 A50,50 0 0,1 80,98.30z'/><路径d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z'/><路径d='M55,55 L30,98.30 A50,50 0 0,1 5,55z'/><路径d='M55,55 L5,55 A50,50 0 0,1 30,11.69z'/><路径d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z'/><路径d='M55,55 L80,11.69 A50,50 0 0,1 105,55z'/><圆cx='55' cy='55' r='25'/></svg>
每个段的背景不同:
如果每个段应该有不同的背景,那么只需将 fill
属性添加到每个 path
元素.
svg {高度:220px;宽度:220px;}小路 {中风:黑色;}圆圈 {填充:黄绿色;中风:黑色;}
<svg viewBox='0 0 110 110'><路径d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' 填充='深红色'/><路径d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' fill='tomato'/><路径 d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' 填充='sandybrown'/><路径d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' 填充='mediumseagreen'/><路径d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z'填充='巧克力'/><路径d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' fill='teal'/><圆cx='55' cy='55' r='25'/></svg>
内部透明的演示:
如果中心部分不能有纯色,那么整个事情就会变得更加复杂,因为我们不能再在中心点开始和结束路径.在这种情况下,我们必须在外圆和内圆上都找到点,如下所示:
在这种情况下,path
必须从From(Inner)"开始.并在同一点结束,从开始应该画一条线到From(Outer)",然后画一条弧线到To(Outer)",一条线到To(Inner)".和从(内部)"的弧线.
svg {高度:220px;宽度:220px;}小路 {填充:透明;中风:黑色;}
<svg viewBox='0 0 110 110'><路径d='M80,55 L105,55 A50,50 0 0,1 80,98.30 L67.5,76.65 A25,25 0 0,0 80,55z'/><路径d='M67.5,76.65 L80,98.30 A50,50 0 0,1 30,98.30 L42.5,76.65 A25,25 0 0,0 67.5,76.65z'/><路径d='M42.5,76.65 L30,98.30 A50,50 0 0,1 5,55 L30,55 A25,25 0 0,0 42.5,76.65z'/><路径d='M30,55 L5,55 A50,50 0 0,1 30,11.69 L42.5,33.34 A25,25 0 0,0 30,55z'/><路径d='M42.5,33.34 L30,11.69 A50,50 0 0,1 80,11.69 L67.5,33.34 A25,25 0 0,0 42.5,33.34z'/><路径d='M67.5,33.34 L80,11.69 A50,50 0 0,1 105,55 L80,55 A25,25 0 0,0 67.5,33.4z'/></svg>
使每个片段成为可点击的链接:
一旦创建了形状本身,就很容易做到这一点.就像在chipChocolate.py的回答中一样,只需将每个路径包装在一个SVG锚标记中(<a xlink:href="#">
其中 #
应该被替换链接页面的 URL).
svg {高度:220px;宽度:220px;}小路 {填充:透明;中风:黑色;}
<svg viewBox='0 0 110 110'><a xlink:href="#"><path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z'/></a><a xlink:href="#"><path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z'/></a><a xlink:href="#"><path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z'/></a><a xlink:href="#"><path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z'/></a><a xlink:href="#"><path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z'/></a><a xlink:href="#"><path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z'/></a></svg>
在形状中添加文本:
SVG 中的文本添加稍微复杂一些,因为我们必须再次指定应该放置文本的位置.如果文本相当小(比如几个字符),那么我们可以再次在圆上找到点,使得角度正好在线段的中间并使用它.半径可以设置为它是父圆半径的一半(如果没有未分割的部分),或者它是内圆和外圆之间的一半.通过 CSS 添加的 text-anchor
、dominant-baseline
设置将确保文本以这样一种方式定位,即文本的水平和垂直中心与指定点匹配.
如果文本很大(并且需要环绕),则应进行额外处理,因为 SVG text
标记内的内容不会自动环绕.
6段圆且无中心未分段区域的点计算:
6段圆和中心未分割区域的点计算:
svg {高度:220px;宽度:220px;}小路 {填充:透明;中风:黑色;}文本 {文本锚:中间;主导基线:中间;/* 在 IE 中不起作用 */字体:12px Calibri,Arial;}
<svg viewBox='0 0 110 110'><路径d='M55,55 L105,55 A50,50 0 0,1 80,98.30z'/><文本 x='76.65' y='67.5'>1</text><路径d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z'/><text x='55' y='80'>2</text><路径d='M55,55 L30,98.30 A50,50 0 0,1 5,55z'/><text x='33.4' y='67.5'>3</text><路径d='M55,55 L5,55 A50,50 0 0,1 30,11.69z'/><text x='33.4' y='42.5'>4</text><路径d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z'/><text x='55' y='30'>5</text><路径d='M55,55 L80,11.69 A50,50 0 0,1 105,55z'/><text x='76.65' y='42.5'>6</text></svg><svg viewBox='0 0 110 110'><路径d='M55,55 L105,55 A50,50 0 0,1 80,98.30z'/><文本 x='87.47' y='73.75'>1</text><路径d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z'/><text x='55' y='92.5'>2</text><路径d='M55,55 L30,98.30 A50,50 0 0,1 5,55z'/><text x='22.52' y='73.75'>3</text><路径d='M55,55 L5,55 A50,50 0 0,1 30,11.69z'/><text x='22.52' y='36.25'>4</text><路径d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z'/><text x='55' y='17.5'>5</text><路径d='M55,55 L80,11.69 A50,50 0 0,1 105,55z'/><text x='87.47' y='36.25'>6</text><圆cx='55' cy='55' r='25'/></svg>
使用 JavaScript 进行动态创建:
下面是一个粗略的基于 JS 的实现,用于动态创建段.该函数有四个参数——圆心的 X 坐标、圆心的 Y 坐标、圆的半径和编号.段/片.
var fromAngle, toAngle, fromCoordX, fromCoordY, toCoordX, toCoordY, path, d;函数 createPie(cx, cy, r, slices) {for (var i = 0; i < 切片; i++) {path = document.createElementNS("http://www.w3.org/2000/svg", "path");fromAngle = i * 360/切片;toAngle = (i + 1) * 360/切片;fromCoordX = cx + (r * Math.cos(fromAngle * Math.PI/180));fromCoordY = cy + (r * Math.sin(fromAngle * Math.PI/180));toCoordX = cx + (r * Math.cos(toAngle * Math.PI/180));toCoordY = cy + (r * Math.sin(toAngle * Math.PI/180));d = 'M' + cx + ',' + cy + 'L' + fromCoordX + ',' + fromCoordY + 'A' + r + ',' + r + ' 0 0,1 ' + toCoordX + ','+ toCoordY + 'z';path.setAttributeNS(null, "d", d);document.getElementById('pie').appendChild(path);}}createPie(55, 55, 50, 6);
svg {高度:220px;宽度:220px;}小路 {填充:透明;中风:黑色;}
<svg viewBox="0 0 110 110" id="pie"></svg>
上一页>JS 示例不包含未分段内圆的示例,但可以通过扩展它来实现.
I am trying to make a circle like this. I was able to make it in the fiddle, but the problem is that I need each orange side to be a link and I can't do it with borders. If anyone can help me with this I will be really grateful.
#circle { width: 200px; height: 200px; border-radius: 50%; background: green; } #incircle { width: 100px; height: 100px; border-radius: 50%; border: 50px dotted orange; }
<div id="circle"> <div id="incircle"></div> </div>
解决方案
The key to creating a circle with segments is to find points along the circle which would be used in the SVG
path
elements as coordinates. Finding points on a circle can be done easily using trigonometric equations if we know the angles.X Coordinate of point = Radius of the circle * Cos(Angle in Radians) + X Coordinate of center point
Y Coordinate of point = Radius of the circle * Sin(Angle in Radians) + Y Coordinate of center point
Angle in Radians = Angle in Degrees * Math.PI / 180
The angles depend on the no. of segments that we have to create. The generic formula is (360 / no. of segments). So to create a circle with 6 segments, the angle covered by each of the segment would be 60 degrees. The first segment would cover from 0 to 60 degrees, second from 60 to 120 degrees and so on.
Demo of Circle with 6 Segments:
Below table shows how the points are calculated for a circle with 6 segments (where radius of circle is 50, center point is 55,55):
Once the points are calculated, coding the
path
itself is simple. The path should start and end at the center point (which is 50,50), from the center point, we should first draw a line to From Point and from there draw an arc to the To Point. Below is how a samplepath
would look like:<path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' />
svg { height: 220px; width: 220px; } path { fill: transparent; stroke: black; }
<svg viewBox='0 0 110 110'> <path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' /> <path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' /> <path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' /> <path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' /> <path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z' /> <path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' /> </svg>
Demo of Circle with 12 Segments:
For a circle with 12 segments, each segment would cover 30 degrees and so the points would be calculated as in the below table:
svg { height: 220px; width: 220px; } path { fill: transparent; stroke: black; }
<svg viewBox='0 0 110 110'> <path d='M55,55 L105,55 A50,50 0 0,1 98.30,80z' /> <path d='M55,55 L98.30,80 A50,50 0 0,1 80,98.30z' /> <path d='M55,55 L80,98.30 A50,50 0 0,1 55,105z' /> <path d='M55,55 L55,105 A50,50 0 0,1 30,98.30z' /> <path d='M55,55 L30,98.30 A50,50 0 0,1 11.69,80z' /> <path d='M55,55 L11.69,80 A50,50 0 0,1 5,55z' /> <path d='M55,55 L5,55 A50,50 0 0,1 11.69,30z' /> <path d='M55,55 L11.69,30 A50,50 0 0,1 30,11.69z' /> <path d='M55,55 L30,11.69 A50,50 0 0,1 55,5z' /> <path d='M55,55 L55,5 A50,50 0 0,1 80,11.69z' /> <path d='M55,55 L80,11.69 A50,50 0 0,1 98.30,30z' /> <path d='M55,55 L98.30,30 A50,50 0 0,1 105,55z' /> </svg>
Circle with an unsegmented inner portion:
If it should look as though a portion of the circle (with a smaller radius) in center looks unsegmented and if that inner portion need not be transparent, just add an extra circle element at the end within the SVG.
svg { height: 220px; width: 220px; } path { fill: transparent; stroke: black; } circle { fill: yellowgreen; stroke: black; }
<svg viewBox='0 0 110 110'> <path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' /> <path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' /> <path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' /> <path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' /> <path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z' /> <path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' /> <circle cx='55' cy='55' r='25' /> </svg>
Different Background for each Segment:
If each of the segments should have a different background to them then just add the
fill
attribute to eachpath
element.svg { height: 220px; width: 220px; } path { stroke: black; } circle { fill: yellowgreen; stroke: black; }
<svg viewBox='0 0 110 110'> <path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' fill='crimson' /> <path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' fill='tomato' /> <path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' fill='sandybrown' /> <path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' fill='mediumseagreen' /> <path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z' fill='chocolate' /> <path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' fill='teal' /> <circle cx='55' cy='55' r='25' /> </svg>
Demo with a transparent inner portion:
If the center portion cannot have a solid color then the whole thing becomes more complex because we can no longer start and end the path at the center point. In such cases, we have to find points on both the outer circle and the inner circle like below:
In this case, the
path
has to start from the "From(Inner)" and end at same point, from the start a line should be drawn to "From(Outer)", then an arc to "To(Outer)", a line to "To(Inner)" and an arc to "From (Inner)".svg { height: 220px; width: 220px; } path { fill: transparent; stroke: black; }
<svg viewBox='0 0 110 110'> <path d='M80,55 L105,55 A50,50 0 0,1 80,98.30 L67.5,76.65 A25,25 0 0,0 80,55z' /> <path d='M67.5,76.65 L80,98.30 A50,50 0 0,1 30,98.30 L42.5,76.65 A25,25 0 0,0 67.5,76.65z' /> <path d='M42.5,76.65 L30,98.30 A50,50 0 0,1 5,55 L30,55 A25,25 0 0,0 42.5,76.65z' /> <path d='M30,55 L5,55 A50,50 0 0,1 30,11.69 L42.5,33.34 A25,25 0 0,0 30,55z' /> <path d='M42.5,33.34 L30,11.69 A50,50 0 0,1 80,11.69 L67.5,33.34 A25,25 0 0,0 42.5,33.34z' /> <path d='M67.5,33.34 L80,11.69 A50,50 0 0,1 105,55 L80,55 A25,25 0 0,0 67.5,33.4z' /> </svg>
Making each segment a clickable link:
This is pretty simple to do once the shape itself has been created. Like in chipChocolate.py's answer, just wrap each path within a SVG anchor tag (
<a xlink:href="#">
where#
should be replaced the URL of the linked page).svg { height: 220px; width: 220px; } path { fill: transparent; stroke: black; }
<svg viewBox='0 0 110 110'> <a xlink:href="#"><path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' /></a> <a xlink:href="#"><path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' /></a> <a xlink:href="#"><path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' /></a> <a xlink:href="#"><path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' /></a> <a xlink:href="#"><path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z' /></a> <a xlink:href="#"><path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' /></a> </svg>
Adding text within the shape:
Text addition in SVG is slightly more complex because again we have to specify the point where the text should be placed. If the text is reasonably small (say a few characters), then we can again find points on the circle such that the angle is exactly in the middle of the segment and use it. The radius could be set such that it is half the parent circle's radius (if there is no unsegmented portion) or such that it is half way between the inner circle and outer circle. The
text-anchor
,dominant-baseline
settings that are added via CSS would make sure that the text is positioned in such a way that both the horizontal and vertical center of the text matches with the specified point.If the text is large (and needs to wrap around), then extra handling should be done because contents within the SVG
text
tag won't get wrapped around automatically.Point calculation for circle with 6 segments and no central unsegmented area:
Point calculation for circle with 6 segments and central unsegmented area:
svg { height: 220px; width: 220px; } path { fill: transparent; stroke: black; } text { text-anchor: middle; dominant-baseline: middle; /* doesn't work in IE */ font: 12px Calibri, Arial; }
<svg viewBox='0 0 110 110'> <path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' /> <text x='76.65' y='67.5'>1</text> <path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' /> <text x='55' y='80'>2</text> <path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' /> <text x='33.4' y='67.5'>3</text> <path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' /> <text x='33.4' y='42.5'>4</text> <path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z' /> <text x='55' y='30'>5</text> <path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' /> <text x='76.65' y='42.5'>6</text> </svg> <svg viewBox='0 0 110 110'> <path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' /> <text x='87.47' y='73.75'>1</text> <path d='M55,55 L80,98.30 A50,50 0 0,1 30,98.30z' /> <text x='55' y='92.5'>2</text> <path d='M55,55 L30,98.30 A50,50 0 0,1 5,55z' /> <text x='22.52' y='73.75'>3</text> <path d='M55,55 L5,55 A50,50 0 0,1 30,11.69z' /> <text x='22.52' y='36.25'>4</text> <path d='M55,55 L30,11.69 A50,50 0 0,1 80,11.69z' /> <text x='55' y='17.5'>5</text> <path d='M55,55 L80,11.69 A50,50 0 0,1 105,55z' /> <text x='87.47' y='36.25'>6</text> <circle cx='55' cy='55' r='25' /> </svg>
Dynamic creation with JavaScript:
Below is a rough JS based implementation in order to create the segments dynamically. The function takes four arguments - the X coordinate of the circle's center, the Y coordinate of its center, the radius of the circle and the no. of segments/slices.
var fromAngle, toAngle, fromCoordX, fromCoordY, toCoordX, toCoordY, path, d; function createPie(cx, cy, r, slices) { for (var i = 0; i < slices; i++) { path = document.createElementNS("http://www.w3.org/2000/svg", "path"); fromAngle = i * 360 / slices; toAngle = (i + 1) * 360 / slices; fromCoordX = cx + (r * Math.cos(fromAngle * Math.PI / 180)); fromCoordY = cy + (r * Math.sin(fromAngle * Math.PI / 180)); toCoordX = cx + (r * Math.cos(toAngle * Math.PI / 180)); toCoordY = cy + (r * Math.sin(toAngle * Math.PI / 180)); d = 'M' + cx + ',' + cy + ' L' + fromCoordX + ',' + fromCoordY + ' A' + r + ',' + r + ' 0 0,1 ' + toCoordX + ',' + toCoordY + 'z'; path.setAttributeNS(null, "d", d); document.getElementById('pie').appendChild(path); } } createPie(55, 55, 50, 6);
svg { height: 220px; width: 220px; } path { fill: transparent; stroke: black; }
<svg viewBox="0 0 110 110" id="pie"></svg>
JS sample doesn't cover the examples with an unsegmented inner circle but that can be achieved by extending this.
相关文章