动画 SVG:围绕固定点 mouse/rotate 方向移动形状?

Animating SVG: Move shape in direction of mouse/rotate around fixed point?

在查看论坛上发布的类似问题后,没有找到可以帮助我解决自己问题的内容,我将其发布。

我正在使用 SVG.js 在 Web 文档中生成 SVG 形状。我希望其中一个形状“跟随”mouse/cursor。

我的意思是:形状有一个固定的 position/anchor 点(在它的原始中心),它只能从这个固定点移动有限的距离(比如说 50 像素)。 每当光标移动时,我希望形状沿光标的方向移动,但距离其原始位置的距离不超过定义的距离。我附上了一个简短的动画来说明我的描述:

如果光标消失,形状会弹回到原来的中心。

我了解 Javascript、HTML 和 CSS。这种类型的元素操作对我来说是新的,数学让我很头疼,任何帮助都会很棒。

看起来我需要形状基本上围绕其原始中心旋转,相对于光标有一个角度?我真的不确定如何解决这个问题。我已经尝试使用一种方法来计算角度 described in this post. 我的形状移动了,但没有按预期移动:

// init
var draw = SVG().addTo('body')

// draw 
window.shape = draw.circle(25, 25).stroke({
  color: '#000',
  width: 2.5
}).fill("#fff");
shape.attr("id", "circle1");
shape.move(50, 50)


// move
var circle = $("#circle1");
var dist = 10;

$(document).mousemove(function(e) {

  // angle
  var circleCenter = [circle.offset().left + circle.width() / 2, circle.offset().top + circle.height() / 2];
  var angle = Math.atan2(e.clientX - circleCenter[0], -(e.clientY - circleCenter[1])) * (180 / Math.PI);

  var x = Math.sin(angle) * dist;
  var y = (Math.cos(angle) * dist) * -1;

  shape.animate().dmove(x, y);

})
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/3.0.16/svg.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

注意:解决方案是否依赖于 jQuery 对我来说并不重要(理想情况下它不依赖)。

在反复尝试计算角度和距离的一些解决方案后,我找到了答案。

我正在使用一个固定的参考点来计算形状中心和光标之间的直线的角度。然后我将形状相对于这个参考点移动给定的量:

// Init canvas
var draw = SVG().addTo('body')

// Draw reference/anchor
var shape_marker_center = draw.circle(3,3).fill("#f00").move(150, 150);;
var grafikCenter = [shape_marker_center.attr("cx"), shape_marker_center.attr("cy")]

// Draw shapes
var shape = draw.circle(25, 25).stroke({color: '#000', width: 2.5 }).fill("none");
shape.attr("id", "circle1").attr({cx: grafikCenter[0], cy:grafikCenter[1]})
var shape2 = draw.circle(50, 50).stroke({color: '#000', width: 2.5 }).fill("none");
shape2.attr("id", "circle2").attr({cx: grafikCenter[0], cy:grafikCenter[1]})
var shape3 = draw.circle(75, 75).stroke({color: '#000', width: 2.5 }).fill("none");
shape3.attr("id", "circle3").attr({cx: grafikCenter[0], cy:grafikCenter[1]})

$(document).mousemove(function(e) {
  var pointA = [shape_marker_center.attr("cx"), shape_marker_center.attr("cy")];
  var pointB = [e.clientX, e.clientY];
  var angle = Math.atan2(pointB[1] - pointA[1], pointB[0] - pointA[0]) * 180 / Math.PI ;
  //
  var distance_x_1 = Math.cos(angle*Math.PI/180) * 16;
  var distance_y_1 = Math.sin(angle*Math.PI/180) * 16;
  var distance_x_2 = Math.cos(angle*Math.PI/180) * 8;
  var distance_y_2 = Math.sin(angle*Math.PI/180) * 8;
  //
  shape.center((grafikCenter[0] + distance_x_1), (grafikCenter[1] + distance_y_1));
  shape2.center((grafikCenter[0] + (distance_x_2) ), (grafikCenter[1] + (distance_y_2)));
})
svg {
  width: 100vw;
  height: 100vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/3.0.16/svg.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>