Home > database >  How to make a circle split into thirds, where each third is a button?
How to make a circle split into thirds, where each third is a button?

Time:12-01

I have looked around the internet and I haven't found a good solution to my problem. I want to make a circle, that is split into 3 parts, and each of those three parts are buttons that do things. This is what I mean: Button Concept

I have tried using css and border radius, and I have also tried using the tag in html, and none of them seemed to give me the results I wanted. Is this possible?

CodePudding user response:

CSS clip-path method

see: https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path for information about clip-path

One idea using css clip-path is described here.

Although usually used to style image borders to interesting shapes, the css clip-path property can be used to mask areas of a div or other html element.

In the following snippet, three divs have been rendered on top of each other (by setting their position attributes to absolute and giving them identical top and left attribute values). The divs are made circular by applying border-radius: 50%.

css clip-path has then been applied with different coordinates to each circle, masking all but one (different for each) sector sweeping (roughly as I haven't calculated exact coordinates) a third of a circle.

Javascript is used to add click event listeners to each div so that a click can be assigned to each of the sectors independently.

This might provide an approach you can refine to your needs.

const circles=document.querySelectorAll("div.circle");

for (let i=0; i<circles.length; i  ) {
circles[i].addEventListener('click', (e) => {
console.log(e.target.id)}) // end click event listener;

circles[i].addEventListener('mousedown', (e) => {
e.target.style.filter= "brightness(85%)"
})

circles[i].addEventListener('mouseup', (e) => {
e.target.style.filter= "brightness(100%)"
})
} // next circle;
body {
  background: yellow;
}

div.circle {
  position: absolute;
  top: 3em;
  left: 3em;
  width: 100px;
  aspect-ratio: 1;
  border: 1px solid black;
  border-radius: 50%;
 
  cursor: pointer;
}

#red {
  background: red;
}

#green {
  background: green;
  clip-path: polygon(-80% 180%, 50% 50%, 180% 180%, -80% 180%);
}

#blue {
  background: blue;
  clip-path: polygon(-80% 0%, 50% 0%, 50% 50%, -80% 180%);
}
<p> click parts of the circle</p>

<div  id="red"> </div>
<div  id="green"> </div>
<div  id="blue"> </div>

The clip-path values are sets of coordinates (with 0,0 being the top-left of the element's bounding box), in my example using % units (% of the div size). Each path is forming a triangle with one apex at the centre of the circle, and the other two far enough away to enclose the arc of that sector. Note negative values are allowed and have been used here. The values used are estimates, you will have to calculate exact values if you need perfect sectors.

Note also that no clip-path was applied to the red sector, it was not needed because the other circles are stacked on top of it.

Edit

To make the sectors more 'button-like' I've added further (entirely optional) event listeners for mousedown and mouseup events which toggle the brightness of the sector to indicate a button press. Further styles could be toggled in these event listeners to add any effects needed to improve the authenticity of the button behaviour (such as drop shadows etc.)

  • Related