SVG - moving a dot along a fixed circle following the mouse position

≯℡__Kan透↙ 提交于 2019-12-11 03:23:37

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!