【发布时间】:2021-10-13 01:51:32
【问题描述】:
我有一个跟随光标的正方形。 它的边框顶部是红色的,以查看旋转是否正确。 我正在尝试根据鼠标移动角度旋转它。就像如果鼠标向右上方移动 45 度,那么正方形必须旋转 45 度。 问题是当我慢慢移动鼠标时,方块开始疯狂地旋转。但如果我将鼠标移动得足够快,正方形就会非常顺畅地旋转。
实际上,这只是我想要完成的任务的一部分。我的整个任务是制作自定义圆形光标,当鼠标移动时会伸展。我试图实现的想法: 通过鼠标移动角度旋转圆圈,然后缩放它以产生拉伸效果。但由于我上面描述的问题,我不能这样做。当鼠标速度慢时,我需要我的跟随者平稳旋转。
class Cursor {
constructor() {
this.prevX = null;
this.prevY = null;
this.curX = null;
this.curY = null;
this.angle = null;
this.container = document.querySelector(".cursor");
this.follower = this.container.querySelector(".cursor-follower");
document.addEventListener("mousemove", (event) => {
this.curX = event.clientX;
this.curY = event.clientY;
});
this.position();
}
position(timestamp) {
this.follower.style.top = `${this.curY}px`;
this.follower.style.left = `${this.curX}px`;
this.angle = Math.atan2(this.curY - this.prevY, this.curX - this.prevX) * 180/Math.PI;
console.log(this.angle + 90);
this.follower.style.transform = `rotateZ(${this.angle + 90}deg)`;
this.prevX = this.curX;
this.prevY = this.curY;
requestAnimationFrame(this.position.bind(this));
}
}
const cursor = new Cursor();
.cursor-follower {
position: fixed;
top: 0;
left: 0;
z-index: 9999;
pointer-events: none;
user-select: none;
width: 76px;
height: 76px;
margin: -38px;
border: 1.5px solid #000;
border-top: 1.5px solid red;
}
<div class="cursor">
<div class="cursor-follower"></div>
</div>
【问题讨论】:
-
尽量不要默认为90度?另外,只有在光标移动时才动画?
-
我将 90degs 添加到 atan2 结果,因为它的输出与我传递给手动旋转的内容不对应。示例:如果我将光标移动到右上角(旋转函数中为 45 度),atan2 将返回 -45。我添加 90 使其变为 45,然后传递给旋转()。您可以自己删除 +90,看看这不是问题。
-
这不是增加 90 度。 1) 直线移动将使角度默认为 90 度。 2)删除您的requestAnimationFrame,因为它也默认为90度。无法为您提供更多帮助,因为我无法找到解决 #1 的方法。
-
平均角度 => 存储最后 3 个点左右并计算角度,例如 a1 = α(curr, L1), a2 = α(curr, L2), a3 = α(curr, L3), than a = a1 * w1 + a2 *w2 + a3*w3 其中 (w1 + w2 w3 = 1) 和 (w1 > w2 > w3)。权重因子 w1、w2、w3 是经验性的,您应该为它们找到一些不错的值,例如 (w1 = 0.5, w2 = 0.35, w3 = 0.15)。其他方法是通过几个点构建一条曲线并使用插值并找到一个切线(这可能太多了)。只要只使用两个点,您的动画就不会流畅。
-
一切尽在掌握,算法本身几乎和你能得到的一样流畅。看看this other fiddle。它将光标(10 秒后)从非常平滑变为真正快速的银色光标,它可以感知鼠标移动中的最小变化。您可以使用参数(在类的开头)来调整光标行为。您还可以通过在代码末尾的最后一个
if条件中将 0 切换为 1 来检查自动移动(在之前的if中将 1 切换为 0)。
标签: javascript