【问题标题】:SVG - moving a dot along a fixed circle following the mouse positionSVG - 沿着鼠标位置沿固定圆圈移动一个点
【发布时间】:2014-10-15 05:57:30
【问题描述】:

我正在尝试为一个点设置动画以跟随鼠标的药水。

这就像我不在眼睛上时一只眼睛在看箭头。 如果我在鼠标周围移动,该点应该沿着一个圆圈移动。 如果鼠标在眼睛上,眼睛应该跟随箭头。

这就是我目前正在尝试做的事情。 我使用 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;

任何想法社区?

【问题讨论】:

  • 向我们展示您目前拥有的代码。

标签: javascript svg snap.svg


【解决方案1】:

你必须测试你的鼠标坐标离圆心有多远,如果它们到达边缘就停下来。

这样的事情应该可以工作。

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】:

    这是我的视觉解决方案,它使用了 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);

    【讨论】:

    • 非常聪明的解决方案。它工作得很好,完全符合我的预期!谢谢!!
    • 对于读者挑战,我在下面扩展了你的答案,希望你不介意! jsfiddle.net/JwkYm/8
    【解决方案3】:

    只是稍微偏离了方向,但作为 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

    【讨论】:

    • +1 @Ian:干得好。对于.ellipse()convert it to path,其余编码相同。让我想起了早期的xeyes
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-16
    相关资源
    最近更新 更多