SVG - 沿着鼠标位置的固定圆移动一个点

时间:2014-08-21 14:31:56

标签: javascript svg snap.svg

我正在尝试动画一个点来跟随鼠标的药水。

当我不在眼睛上时,就像一只眼睛看着箭头。 如果我在鼠标周围移动,该点应该沿着圆圈移动。 如果鼠标在眼睛上,则眼睛应该遵循箭头。

这就是我目前正在尝试做的事情。 我使用snap.svg库。

我目前有一点关注鼠标的移动性,但我不能让它保持一个圆圈。

到目前为止看起来像这样:

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;

任何想法社区?

3 个答案:

答案 0 :(得分:4)

这是我的视觉解决方案,它使用了Snap的内置功能: -

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;

更新:这是fiddle demo。读者面临的挑战:尝试var bigCircle = s.ellipse(150, 150, 100, 50);

答案 1 :(得分:3)

你必须测试你的鼠标坐标距离圆心的距离,并在它们到达边缘时停止它们。

这样的事情应该有效。

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 });
}

如果这对你不起作用,请制作一个jsfiddle,这样我们就能看到你到目前为止所做的一切。

答案 2 :(得分:1)

只是略微变形,但作为Alvin Ks答案的延伸(对于读者的挑战!),如果你能确保对象是一个路径,你可以使用Snap.path.intersection,它可以用于许多其他形状。尽管可能需要额外的代码用于多个交叉点。

Alvins代码的相关修订......

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