检测 SVG(React 组件)路径元素的左侧或右侧部分被点击
Detect left or right part was clicked of the path element of SVG (React component)
我有一个 svg 组件,还有一个组件有 onClick 处理程序
我怎样才能检测到这条路径的哪一部分被点击了?左边或一半
我的路径是半圈,我需要检测被点击的部分
(左边是1/2,一半是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>
主要思想是:
- 将形状放入
<defs>
- 在每一半上绘制 2 个矩形(r1 和 r2)。
- 使用这些矩形构建 2 个剪切路径(cp1 和 cp2)
- 使用
<use>
两次形状,第一次用 cp1 剪裁,第二次用 cp2 剪裁。
- 为剪辑的使用元素添加事件监听器
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>
只需取 path.getBoundingClientRect().width
,除以 2 得到路径的中心,并检查中心是否大于 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>
我有一个 svg 组件,还有一个组件有 onClick 处理程序 我怎样才能检测到这条路径的哪一部分被点击了?左边或一半 我的路径是半圈,我需要检测被点击的部分 (左边是1/2,一半是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>
主要思想是:
- 将形状放入
<defs>
- 在每一半上绘制 2 个矩形(r1 和 r2)。
- 使用这些矩形构建 2 个剪切路径(cp1 和 cp2)
- 使用
<use>
两次形状,第一次用 cp1 剪裁,第二次用 cp2 剪裁。 - 为剪辑的使用元素添加事件监听器
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>
只需取 path.getBoundingClientRect().width
,除以 2 得到路径的中心,并检查中心是否大于 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>