2016-01-17 2 views
2

SVG путь элемента, например:Как определить, какой сегмент пути svg щелкнут в javascript?

<path id="path1" 
d="M 160 180 C 60 140 230 20 200 170 C 290 120 270 300 200 240 C 160 390 50 240 233 196" 
stroke="#009900" stroke-width="4" fill="none"/> 

Он имеет 4 сегмента SVG (3 сегмента кривой в человеческих глаз):

M 160 180 
    C 60 140 230 20 200 170 
    C 290 120 270 300 200 240 
    C 160 390 50 240 233 196 

, когда щелчок по пути, я получаю x и y мыши позиции, то как определить, какой сегмент кривой нажат?

function isInWhichSegment(pathElement,x,y){ 
     //var segs = pathElement.pathSegList; //all segments 
     // 
     //return the index of which segment is clicked 
     // 
    } 
+1

Вы кажетесь отвергли очевидное решение рендеринга каждого сегмента в качестве отдельного объекта. Можете ли вы объяснить, почему? –

+0

@squeamishossifrage Это решение необходимо разделить один путь на многие элементы пути и принести больше вопросов, когда я обрабатываю узлы DOM. Я не надеюсь создавать новые элементы. – cuixiping

ответ

2

Есть несколько методов для SVGPathElements, которые вы можете использовать. На самом деле это не так, но вы можете получить общую длину своего пути, а затем проверить на каждой точке длины координаты с getPointAtLength и сравнить его с координатами щелчка. Как только вы видите, что щелчок был на какой длине, вы получаете сегмент этой длины с getPathSegAtLength. как это, например:

var pathElement = document.getElementById('path1') 
 
var len = pathElement.getTotalLength(); 
 

 
pathElement.onclick = function(e) { 
 
    console.log('The index of the clicked segment is', isInWhichSegment(pathElement, e.offsetX, e.offsetY)) 
 
} 
 

 
function isInWhichSegment(pathElement, x, y) { 
 
    var seg; 
 
    // You get get the coordinates at the length of the path, so you 
 
    // check at all length point to see if it matches 
 
    // the coordinates of the click 
 
    for (var i = 0; i < len; i++) { 
 
    var pt = pathElement.getPointAtLength(i); 
 
    // you need to take into account the stroke width, hence the +- 2 
 
    if ((pt.x < (x + 2) && pt.x > (x - 2)) && (pt.y > (y - 2) && pt.y < (y + 2))) { 
 
     seg = pathElement.getPathSegAtLength(i); 
 
     break; 
 
    } 
 
    } 
 
    return seg; 
 
}
<svg> 
 
    <path id="path1" d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="#009900" stroke-width="4" fill="none" /> 
 
</svg>

+0

это решение, но неэффективное. Есть ли математическое и эффективное решение? – cuixiping

Смежные вопросы