问题
I'm trying to animate a point to follow the potion of the mouse.
It's like an eye looking at the arrow while I'm not on the eye. The point should move along a circle if I mouve around the mouse. If the mouse is on the eye, the eye should follow the arrow.
That's what I'm currently trying to do. I use snap.svg library.
I currently have a point following the mobility of the mouse but I cant make it stay in a circle.
It looks like this so far :
var s = Snap(400,400);
var c1 = s.circle(0,0,10).attr({ fill: "red" });
function OnMouseMove(evt) {
c1.attr({ cx: evt.clientX , cy: evt.clientY });
}
document.onmousemove = OnMouseMove;
Any idea community ?
回答1:
Here's my visual solution, it uses Snap's built in functions:-
var s = Snap(400,400);
var circleX = 150, circleY = 150, circleRadius = 100;
var bigCircle = s.circle(circleX, circleY, circleRadius);
var L1 = s.path("M "+circleX+" "+circleY +"L 0 0").attr({stroke: "blue"});
// BigCircle default its black, lets change its attributes
bigCircle.attr({
fill: "#bada55",
stroke: "#000",
strokeWidth: 5
});
var c1 = s.circle(0,0,10).attr({ fill: "red" });
function OnMouseMove(evt) {
L1.attr({ d: "M "+circleX+" "+circleY +"L "+evt.clientX+" "+evt.clientY });
var totalLength = L1.getTotalLength();
if (totalLength < circleRadius) {
c1.attr({ cx: evt.clientX , cy: evt.clientY });
} else {
var PAL = L1.getPointAtLength(circleRadius);
c1.attr({ cx: PAL.x , cy: PAL.y });
}
}
document.onmousemove = OnMouseMove;
Update: Here's the fiddle demo. Challenge for readers: Try var bigCircle = s.ellipse(150, 150, 100, 50);
.
回答2:
You have to test how far away your mouse coordinates are from the centre of the circle, and stop them if they reach the edge.
Something like this should work.
function OnMouseMove(evt) {
// Get the mouse position relative to the centre of the circle (circleX,circleY)
var dx = evt.clientX - circleX;
var dy = evt.clientY - circleY;
// Calculate distance from centre of circle to mouse (Pythagoras' theorem)
var distance = Math.sqrt(dx * dx + dy *dy);
// Test against radius
if (distance > circleRadius) {
// Scale the dx,dy coords back so they are on the circumference
dx = dx * circleRadius / distance;
dy = dy * circleRadius / distance;
}
c1.attr({ cx: dx, cy: dy });
}
If this doesn't work for you, make a jsfiddle so we can see what you have so far.
回答3:
Just strayling slightly, but as an extension to Alvin Ks answer (for the readers challenge!), if you can make sure the the object is a path, you could use Snap.path.intersection which would work for many other shapes. It would need an extra bit of code for multiple intersections though possibly.
Relevant amendment to Alvins code...
function OnMouseMove(evt) {
L1.attr({ d: "M "+circleX+" "+circleY +"L "+evt.clientX+" "+evt.clientY });
var intersect = Snap.path.intersection( path, L1 )
if (intersect.length == 0) {
c1.attr({ cx: evt.clientX , cy: evt.clientY });
} else {
c1.attr({ cx: intersect[0].x , cy: intersect[0].y });
}
}
jsfiddle
来源:https://stackoverflow.com/questions/25429067/svg-moving-a-dot-along-a-fixed-circle-following-the-mouse-position