Detect left or right part was clicked of the path element of SVG (React component)

Viewed 202

I have a component which is svg and there is which has handler onClick How can I detect which part of this path was clicked? Left or half My path is half circle and I need to detect the part which was clicked (left is 1/2, half is 1/2)

<svg viewBox="0 0 651 592" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M636.971 285C636.971 322.427 628.927 359.487 613.298 394.065C597.668 428.643 574.76 460.061 545.881 486.525C517.002 512.99 482.718 533.983 444.986 548.306C407.253 562.628 366.812 570 325.971 570C285.13 570 244.689 562.628 206.957 548.306C169.224 533.983 134.94 512.99 106.061 486.525C77.1818 460.061 54.2737 428.643 38.6445 394.065C23.0153 359.487 14.9711 322.427 14.9711 285H110.253C110.253 310.96 115.833 336.666 126.674 360.65C137.515 384.634 153.404 406.427 173.435 424.783C193.467 443.14 217.247 457.701 243.419 467.636C269.591 477.57 297.643 482.684 325.971 482.684C354.3 482.684 382.351 477.57 408.523 467.636C434.695 457.701 458.475 443.14 478.507 424.783C498.538 406.427 514.428 384.634 525.268 360.65C536.109 336.666 541.689 310.96 541.689 285H636.971Z" fill="red"/>
</svg>

2 Answers

The main idea is:

  1. Put the shape in the <defs>
  2. draw 2 rectangles (r1 and r2) over each half.
  3. use those rectangle to build 2 clipping paths (cp1 & cp2)
  4. use the shape twice with <use> and clip the first one with cp1 and the second with cp2.
  5. add event listeners to the clipped use elements

u1.addEventListener("click",()=>{console.log(u1.id)})
u2.addEventListener("click",()=>{console.log(u2.id)})
<svg viewBox="0 200 651 392" fill="none" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <path id="shape" d="M636.971 285C636.971 322.427 628.927 359.487 613.298 394.065C597.668 428.643 574.76 460.061 545.881 486.525C517.002 512.99 482.718 533.983 444.986 548.306C407.253 562.628 366.812 570 325.971 570C285.13 570 244.689 562.628 206.957 548.306C169.224 533.983 134.94 512.99 106.061 486.525C77.1818 460.061 54.2737 428.643 38.6445 394.065C23.0153 359.487 14.9711 322.427 14.9711 285H110.253C110.253 310.96 115.833 336.666 126.674 360.65C137.515 384.634 153.404 406.427 173.435 424.783C193.467 443.14 217.247 457.701 243.419 467.636C269.591 477.57 297.643 482.684 325.971 482.684C354.3 482.684 382.351 477.57 408.523 467.636C434.695 457.701 458.475 443.14 478.507 424.783C498.538 406.427 514.428 384.634 525.268 360.65C536.109 336.666 541.689 310.96 541.689 285H636.971Z" fill="red" />
<clipPath id="cp1">
    <rect id="r1" x="14.971099853515625" y="285" width="310.99993896484375" height="285"></rect>
</clipPath>
<clipPath id="cp2">
    <rect id="r2" x="325.9710388183594" y="285" width="310.99993896484375" height="285"></rect>
</clipPath>
 </defs>
  
    <use xlink:href="#shape" clip-path="url(#cp1)" id="u1"/>
    <use xlink:href="#shape" clip-path="url(#cp2)" id="u2"/>
</svg>

Just take the path.getBoundingClientRect().width, devide it by 2 to get center of the path and check if the center bigger or not than e.offsetX.

document.querySelector('path').addEventListener('click', e => {
    if(e.offsetX < e.target.getBoundingClientRect().width/2){
        text.textContent = "LEFT SIDE";
    } else {
        text.textContent = "RIGHT SIDE";
    }
})
<svg viewBox="0 200 651 400" fill="none" xmlns="http://www.w3.org/2000/svg">
        <path d="M636.971 285C636.971 322.427 628.927 359.487 613.298 394.065C597.668 428.643 574.76 460.061 545.881 486.525C517.002 512.99 482.718 533.983 444.986 548.306C407.253 562.628 366.812 570 325.971 570C285.13 570 244.689 562.628 206.957 548.306C169.224 533.983 134.94 512.99 106.061 486.525C77.1818 460.061 54.2737 428.643 38.6445 394.065C23.0153 359.487 14.9711 322.427 14.9711 285H110.253C110.253 310.96 115.833 336.666 126.674 360.65C137.515 384.634 153.404 406.427 173.435 424.783C193.467 443.14 217.247 457.701 243.419 467.636C269.591 477.57 297.643 482.684 325.971 482.684C354.3 482.684 382.351 477.57 408.523 467.636C434.695 457.701 458.475 443.14 478.507 424.783C498.538 406.427 514.428 384.634 525.268 360.65C536.109 336.666 541.689 310.96 541.689 285H636.971Z" fill="red"/>
</svg>
<p id="text" style="position:fixed;top:0;left:0;font-size:30px">
    NO CLICK YET
</p>

Related