i have a svg path and i want to know if my mouse is on svg path or not, if it is i want to change the cursor to mouse to pointer.
This could have been easily done by adding mouse hover property on path and also with Recognize point(x,y) is inside svg path or outside with this solution.
but there is a twist, I have another transparent layer over it, because of which I cannot have those two solutions.
right now I am making top layer display none and it works fine. but because of this my mouse pointer and the action I do such as moving a certain element on mouse move is slow,
hence i want to find out if there is any other better way without making display equal to none.
please find the fiddle example, I want to change the cursor to pointer when its on mypath element and also want myline should be moving as i move mouse over the layer, i can do display to none on layer for time being, but i noticed on firefox, line movement is not that smooth,
/
<svg width="400" height="400">
<g>
<path id="mypath" d="M10 200 L200 90 L200 200" fill="transparent" stroke="black" stroke-width="5" />
<rect class="interactiveArea" width="500" height="500" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0);opacity:0.2" />
<line id="myline" x1="20" y1="0" x2="20" y2="400" stroke-width="2" stroke="black" />
</g>
</svg>
i have a svg path and i want to know if my mouse is on svg path or not, if it is i want to change the cursor to mouse to pointer.
This could have been easily done by adding mouse hover property on path and also with Recognize point(x,y) is inside svg path or outside with this solution.
but there is a twist, I have another transparent layer over it, because of which I cannot have those two solutions.
right now I am making top layer display none and it works fine. but because of this my mouse pointer and the action I do such as moving a certain element on mouse move is slow,
hence i want to find out if there is any other better way without making display equal to none.
please find the fiddle example, I want to change the cursor to pointer when its on mypath element and also want myline should be moving as i move mouse over the layer, i can do display to none on layer for time being, but i noticed on firefox, line movement is not that smooth,
https://jsfiddle/shyam_bhiogade/9a7zuou2/6/
<svg width="400" height="400">
<g>
<path id="mypath" d="M10 200 L200 90 L200 200" fill="transparent" stroke="black" stroke-width="5" />
<rect class="interactiveArea" width="500" height="500" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0);opacity:0.2" />
<line id="myline" x1="20" y1="0" x2="20" y2="400" stroke-width="2" stroke="black" />
</g>
</svg>
Share
Improve this question
edited Jun 8, 2017 at 6:16
shyam_
asked Jun 8, 2017 at 5:35
shyam_shyam_
2,4802 gold badges33 silver badges55 bronze badges
7
- 2 make the transparent layer pointer-events: none – Robert Longson Commented Jun 8, 2017 at 5:42
- that will not work..because i need mouse move event on the transparent layer.on mouse move, i move an elment along the mouse, also if mouse is on underlying path, i want to change the cursor to pointer – shyam_ Commented Jun 8, 2017 at 5:55
- create a minimal reproducible example and add it to the question. – Robert Longson Commented Jun 8, 2017 at 6:00
- Created the example – shyam_ Commented Jun 8, 2017 at 13:57
- 3 SVGGeometryElement.isPointInStroke() is only implemented in Chrome so far. Firefox, haven't found anything on Edge. – ccprog Commented Jun 8, 2017 at 19:11
2 Answers
Reset to default 3I have used the solution given at https://bl.ocks/mbostock/8027637 , it returns the distance of x and y point from the path, if the distance is less than 1px or width of the stroke, I consider that x and y point is on the path.
function closestPoint(pathNode, point) {
var pathLength = pathNode.getTotalLength(),
precision = 8,
best,
bestLength,
bestDistance = Infinity;
// linear scan for coarse approximation
for (var scan, scanLength = 0, scanDistance; scanLength <= pathLength; scanLength += precision) {
if ((scanDistance = distance2(scan = pathNode.getPointAtLength(scanLength))) < bestDistance) {
best = scan, bestLength = scanLength, bestDistance = scanDistance;
}
}
// binary search for precise estimate
precision /= 2;
while (precision > 0.5) {
var before,
after,
beforeLength,
afterLength,
beforeDistance,
afterDistance;
if ((beforeLength = bestLength - precision) >= 0 && (beforeDistance = distance2(before = pathNode.getPointAtLength(beforeLength))) < bestDistance) {
best = before, bestLength = beforeLength, bestDistance = beforeDistance;
} else if ((afterLength = bestLength + precision) <= pathLength && (afterDistance = distance2(after = pathNode.getPointAtLength(afterLength))) < bestDistance) {
best = after, bestLength = afterLength, bestDistance = afterDistance;
} else {
precision /= 2;
}
}
best = [best.x, best.y];
best.distance = Math.sqrt(bestDistance);
return best;
function distance2(p) {
var dx = p.x - point[0],
dy = p.y - point[1];
return dx * dx + dy * dy;
}
}
The SVGGeometryElement.isPointInFill() method determines whether a given point is within the fill shape of an element. Normal hit testing rules apply; the value of the pointer-events property on the element determines whether a point is considered to be within the fill. The point argument is interpreted as a point in the local coordinate system of the element.
var myPath = document.getElementById("mypath");
var txt = document.getElementById("txt");
var svg = document.getElementsByTagName("svg")[0];
svg.addEventListener("mousemove", function(event) {
var mouseX = event.clientX;
var mouseY = event.clientY;
var point = svg.createSVGPoint();
point.x = event.clientX;
point.y = event.clientY;
point=point.matrixTransform(svg.getScreenCTM().inverse());
var inShape=myPath.isPointInFill( point );
txt.innerText=inShape+" x:"+point.x+" y:"+point.y;
});
<svg width="300" height="200" style="border:1px solid black">
<g>
<path id="mypath" d="M118 62C118 62 118 62 119 62 135 62 152 62 168 62 168 62 168 63 168 63 168 69 168 74 169 79 172 80 174 80 177 81 191 85 200 94 204 109 206 114 205 120 204 126 199 139 190 148 176 152 169 153 162 153 156 151 142 147 133 138 129 124 129 122 129 121 128 120 128 120 128 120 127 120 122 120 117 120 112 119 112 100 112 81 113 62 113 62 113 62 113 62 115 62 116 62 118 62" fill="red" stroke="black" stroke-width="2" />
</g>
</svg>
<p>Move Mouse Over Shape <span id="txt" style="font-weight:bold"></span> </p>
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745262264a4619264.html
评论列表(0条)