Cómo crear un círculo con enlaces en el lado del borde

Resuelto Akshay asked hace 9 años • 8 respuestas

Estoy intentando hacer un círculo como este . Pude hacerlo en el violín, pero el problema es que necesito que cada lado naranja sea un enlace y no puedo hacerlo con bordes. Si alguien puede ayudarme con esto estaré realmente agradecido.

#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>
Expandir fragmento

Akshay avatar Jan 14 '15 19:01 Akshay
Aceptado

La clave para crear un círculo con segmentos es encontrar puntos a lo largo del círculo que se usarían en los pathelementos SVG como coordenadas. Encontrar puntos en un círculo se puede hacer fácilmente usando ecuaciones trigonométricas si conocemos los ángulos.

Coordenada X del punto = Radio del círculo * Cos(Ángulo en Radianes) + Coordenada X del punto central

Coordenada Y del punto = Radio del círculo * Sin(Ángulo en radianes) + Coordenada Y del punto central

Ángulo en Radianes = Ángulo en Grados * Math.PI / 180

Los ángulos dependen del no. de segmentos que tenemos que crear. La fórmula genérica es (360 / nº de segmentos). Entonces, para crear un círculo con 6 segmentos, el ángulo cubierto por cada uno de los segmentos sería de 60 grados. El primer segmento abarcaría de 0 a 60 grados, el segundo de 60 a 120 grados y así sucesivamente.


Demostración de Círculo con 6 Segmentos:

La siguiente tabla muestra cómo se calculan los puntos para un círculo con 6 segmentos (donde el radio del círculo es 50, el punto central es 55,55):

ingrese la descripción de la imagen aquí

Una vez calculados los puntos, codificarlos pathes sencillo. El camino debe comenzar y terminar en el punto central (que es 50,50), desde el punto central, primero debemos dibujar una línea hasta el punto de origen y desde allí dibujar un arco hasta el punto de destino. pathA continuación se muestra cómo se vería una muestra :

<path d='M55,55 L105,55 A50,50 0 0,1 80,98.30z' />

Mostrar fragmento de código


Demostración de Círculo con 12 Segmentos:

Para un círculo con 12 segmentos, cada segmento cubriría 30 grados y, por lo tanto, los puntos se calcularían como en la siguiente tabla:

ingrese la descripción de la imagen aquí

Mostrar fragmento de código


Círculo con una porción interior no segmentada:

Si parece que una parte del círculo (con un radio más pequeño) en el centro parece no segmentada y si esa parte interior no necesita ser transparente , simplemente agregue un elemento de círculo adicional al final dentro del SVG.

Mostrar fragmento de código


Antecedentes diferentes para cada segmento:

Si cada uno de los segmentos debe tener un fondo diferente, simplemente agregue el fillatributo a cada pathelemento.

Mostrar fragmento de código


Demostración con una parte interior transparente:

Si la parte central no puede tener un color sólido, entonces todo se vuelve más complejo porque ya no podemos comenzar y terminar el camino en el punto central. En tales casos, tenemos que encontrar puntos tanto en el círculo exterior como en el círculo interior como se muestra a continuación:

ingrese la descripción de la imagen aquí

En este caso, pathdebe comenzar desde "Desde (Interior)" y terminar en el mismo punto, desde el inicio se debe dibujar una línea hacia "Desde (Exterior)", luego un arco hacia "Hacia (Exterior)", un línea a "Hasta (Interior)" y un arco a "Desde (Interior)".

Mostrar fragmento de código


Hacer de cada segmento un enlace en el que se puede hacer clic:

Esto es bastante sencillo de hacer una vez que se ha creado la forma. Al igual que en la respuesta de chipChocolate.py, simplemente ajuste cada ruta dentro de una etiqueta de anclaje SVG ( <a xlink:href="#">donde #se debe reemplazar la URL de la página vinculada).

Mostrar fragmento de código


Agregar texto dentro de la forma:

La adición de texto en SVG es un poco más compleja porque nuevamente tenemos que especificar el punto donde se debe colocar el texto. Si el texto es razonablemente pequeño (digamos unos pocos caracteres), entonces podemos nuevamente encontrar puntos en el círculo tales que el ángulo esté exactamente en el medio del segmento y usarlos. El radio podría establecerse de modo que sea la mitad del radio del círculo principal (si no hay una porción no segmentada) o que esté a mitad de camino entre el círculo interior y el círculo exterior. Las text-anchorconfiguraciones dominant-baselineque se agregan a través de CSS asegurarán que el texto esté ubicado de tal manera que tanto el centro horizontal como el vertical del texto coincidan con el punto especificado.

Si el texto es grande (y necesita ajustarse), entonces se debe realizar un manejo adicional porque el contenido dentro de la textetiqueta SVG no se ajustará automáticamente.

Cálculo de puntos para un círculo con 6 segmentos y sin área central no segmentada:

ingrese la descripción de la imagen aquí

Cálculo de puntos para círculo con 6 segmentos y área central no segmentada:

ingrese la descripción de la imagen aquí

Mostrar fragmento de código


Creación dinámica con JavaScript:

A continuación se muestra una implementación aproximada basada en JS para crear los segmentos dinámicamente. La función toma cuatro argumentos: la coordenada X del centro del círculo, la coordenada Y de su centro, el radio del círculo y el no. de segmentos/rebanadas.

Mostrar fragmento de código

La muestra JS no cubre los ejemplos con un círculo interno no segmentado, pero eso se puede lograr extendiéndolo.

Harry avatar Jan 20 '2016 14:01 Harry

Puede utilizar svg's arcpara crear las secciones y svgetiquetas de anclaje (equivalentes a etiquetas de anclaje HTML) para los enlaces.

ingrese la descripción de la imagen aquí

.frag {
  fill: #FFA500;
  stroke: #FFFFFF;
  transition: fill 0.3s ;
}
.center {
  fill: #008000;
}
a:hover .frag {
  fill: #FFC722;
}
text {
  font-size: 17px;
  fill: #FFFFFF;
}
<svg width="200" height="200" viewBox="-2 -2 202 203" shape-rendering="geometricPrecision">
  <a xlink:href="#"><path class="frag" d="M100,100 v-100 a100,100 1 0,1 86.6025,50" /><text x="135" y="42.5" text-anchor="middle">1</text></a>
  <a xlink:href="#"><path class="frag" d="M100,100 l86.6025,-50 a100,100 1 0,1 0,100" /><text x="170" y="105" text-anchor="middle">2</text></a>
  <a xlink:href="#"><path class="frag" d="M100,100 l86.6025,50 a100,100 1 0,1 -86.6025,50" /><text x="135" y="170" text-anchor="middle">3</text></a>
  <a xlink:href="#"><path class="frag" d="M100,100 v100 a100,100 1 0,1 -86.6025,-50" /><text x="65" y="170" text-anchor="middle">4</text></a>
  <a xlink:href="#"><path class="frag" d="M100,100 l-86.6025,50 a100,100 1 0,1 0,-100" /><text x="27.5" y="105" text-anchor="middle">5</text></a>
  <a xlink:href="#"><path class="frag" d="M100,100 l-86.6025,-50 a100,100 1 0,1 86.0025,-50" /><text x="65" y="42.5" text-anchor="middle">6</text></a>
  <a xlink:href="#"><path class="center" d="M100,100 v-50 a50,50 1 0,1 0,100 a50,50 1 0,1 0,-100" /></a>
</svg>
Expandir fragmento


También puedes estirar o cambiar el tamaño del archivo svg.

ingrese la descripción de la imagen aquí

.frag {
  fill: #FFA500;
  stroke: #FFFFFF;
  transition: fill 0.3s ;
}
.center {
  fill: #008000;
}
a:hover .frag {
  fill: #FFC722;
}
text {
  font-size: 17px;
  fill: #FFFFFF;
}
<svg width="100" height="200" viewBox="-2 -2 202 203" shape-rendering="geometricPrecision" preserveAspectRatio="none">
  <g id="circle">
    <a xlink:href="#"><path class="frag" d="M100,100 v-100 a100,100 1 0,1 86.6025,50" /><text x="135" y="42.5" text-anchor="middle">1</text></a>
    <a xlink:href="#"><path class="frag" d="M100,100 l86.6025,-50 a100,100 1 0,1 0,100" /><text x="170" y="105" text-anchor="middle">2</text></a>
    <a xlink:href="#"><path class="frag" d="M100,100 l86.6025,50 a100,100 1 0,1 -86.6025,50" /><text x="135" y="170" text-anchor="middle">3</text></a>
    <a xlink:href="#"><path class="frag" d="M100,100 v100 a100,100 1 0,1 -86.6025,-50" /><text x="65" y="170" text-anchor="middle">4</text></a>
    <a xlink:href="#"><path class="frag" d="M100,100 l-86.6025,50 a100,100 1 0,1 0,-100" /><text x="27.5" y="105" text-anchor="middle">5</text></a>
    <a xlink:href="#"><path class="frag" d="M100,100 l-86.6025,-50 a100,100 1 0,1 86.0025,-50" /><text x="65" y="42.5" text-anchor="middle">6</text></a>
    <a xlink:href="#"><path class="center" d="M100,100 v-50 a50,50 1 0,1 0,100 a50,50 1 0,1 0,-100" /></a>
  </g>
</svg>

<svg width="200" height="100" viewBox="-2 -2 202 203" shape-rendering="geometricPrecision" preserveAspectRatio="none">
  <use xlink:href="#circle" />
</svg>

<svg width="150" height="150" viewBox="-2 -2 202 203" shape-rendering="geometricPrecision" preserveAspectRatio="none">
  <use xlink:href="#circle" />
</svg>

<svg width="100" height="100" viewBox="-2 -2 202 203" shape-rendering="geometricPrecision" preserveAspectRatio="none">
  <use xlink:href="#circle" />
</svg>

<svg width="50" height="50" viewBox="-2 -2 202 203" shape-rendering="geometricPrecision" preserveAspectRatio="none">
  <use xlink:href="#circle" />
</svg>
Expandir fragmento

Weafs.py avatar Jan 14 '2015 13:01 Weafs.py

Enfoque solo CSS

NOTA: El marcado se puede reducir significativamente mediante el uso de pseudoelementos, que no he usado actualmente.

Puedes usar SVG , pero esto se puede hacer solo con CSS y HTML.

Lo que hice fue crear 12semicírculos (agregándolos overflow: hidden;al contenedor principal). Luego creé grupos separados de 6semicírculos.

Los ángulos en el centro deben ser 30degcada uno ( 360/12). Para lograr esto, tenemos que rotar los semicírculos desde el centro de su círculo original. Podemos hacer esto contransform-origin: 50% 100%;

Ahora sólo tienes que rotar/voltear el segundo grupo de 6semicírculos para completar el diseño.

Finalmente, agrega un círculo verde central para completar el diseño.

Mostrar fragmento de código

Salida en Firefox , Google Chrome e IE :

ingrese la descripción de la imagen aquí

The Pragmatick avatar Jan 15 '2015 12:01 The Pragmatick

Podrías usar un mapa como este:

#circle{
    position:relative;
    width:200px;
    height:200px;
    border-radius:50%;
    background:green;
}

#mappinglink{
    position:absolute;
    top:0px;
    left:0px;
}

#incircle{
    width:100px;
    height:100px;
    border-radius:50%;
    border:50px dotted orange;
    border-spacing: 10px 50px;
}
<div id="circle">
    <div id="incircle"></div>
    <img id="mappinglink" width="200" height="200" usemap="#mymap" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"/>
    <map name="mymap">
        <area  alt="" title="" href="#" shape="poly" coords="29,28,71,3,84,50,64,64" style="outline:none;" target="_self"     />
        <area  alt="" title="" href="#" shape="poly" coords="148,12,122,55,142,73,184,46" style="outline:none;" target="_self"     />
        <area  alt="" title="" href="#" shape="poly" coords="149,96,199,93,192,142,146,121" style="outline:none;" target="_self"     />
        <area  alt="" title="" href="#" shape="poly" coords="105,149,128,141,159,180,112,200" style="outline:none;" target="_self"     />
        <area  alt="" title="" href="#" shape="poly" coords="59,133,79,147,65,193,23,164" style="outline:none;" target="_self"     />
        <area  alt="" title="" href="#" shape="poly" coords="48,87,50,108,3,120,4,71" style="outline:none;" target="_self"     />
    </map>
</div>
Expandir fragmento

Hacketo avatar Jan 14 '2015 13:01 Hacketo