Raphael.js 拖动时有奇怪的行为

Raphael.js has weird behavior on drag

我有一个圆圈,从圆心到圆圈边缘有一条直线。用户可以单击并拖动线并从他们设置线的任何位置获取度数。我正在使用答案 here 中的代码并相应地调整了代码。

一切正常,但受 raphael 影响的元素在页面下方越远,鼠标必须在圆圈外越远才能拖动线条。 jsfiddle

var canvas = Raphael('pivot', 0, 0, 320, 320);

var clock = canvas.circle(200, 150, 100).attr("stroke-width", 2);
canvas.circle(200, 150, 3).attr("fill", "#000");

var angleplus = 360,
    rad = Math.PI / 180,
    cx = 200,
    cy = 150,
    r = 90,
    startangle = -90,
    angle = 90,
    x, y, endangle;

for (i = 1; i < 5; i++) {

    endangle = startangle + angle;
    x = cx + r * Math.sin(endangle * rad);
    y = cy - r * Math.cos(endangle * rad);

    canvas.text(x, y, endangle);

    startangle = endangle;
}

var hand = canvas.path("M200 50L200 150").attr("stroke-width", 5);

hand.drag( move, start, end );

function move (dx,dy,x,y) {
    var pt = this.node.ownerSVGElement.createSVGPoint();
    pt.x = x; 
    pt.y = y;

    var angle = ( 90 + Math.atan2(pt.y - clock.attr('cy') - 5, pt.x - clock.attr('cx') - 5 ) * 180 / Math.PI + 360) % 360;
    this.rotate(angle, 200,150);
    this.angle = angle;
}

function start() {
};

function end() {
    alert(parseInt(this.angle));
}

我想知道为什么会发生这种情况,是否可以修复?

这是更新后的原始答案,添加了一点,又删除了一点冗余,我在原始答案中额外添加了一个 fiddle 来反映它。

我添加的关键位是...

var cpt = clock.node.ownerSVGElement.createSVGPoint();
cpt.x = clock.attr('cx');
cpt.y = clock.attr('cy');
cpt = cpt.matrixTransform(clock.node.getScreenCTM());

时钟的中心现在已经移动,因此单独使用圆的 cx 相对于鼠标事件没有任何意义。我们需要考虑屏幕上到时钟的任何偏移和转换。

我们可以用getScreenCTM(获取从元素到屏幕的矩阵)得到这个,我们可以用那个矩阵和原来的cx,cy来找出它在屏幕上的位置。

然后后面用新调整的坐标cpt代替cx,cy.x/y

var angle = ( 90 + Math.atan2(y - cpt.y - 5, x - cpt.x - 5 ) * 180 / Math.PI + 360)

jsfiddle - 拖动任意手