简体   繁体   English

如何在原版 Javascript 中使 html 元素对 cursor 产生影响?

[英]How to make html element lerp towards cursor in vanilla Javascript?

I'm trying to recreate the button effect on this website: https://advanced.team/team我正在尝试在此网站上重新创建按钮效果: https://advanced.team/team

Scroll down until you see this向下滚动直到你看到这个在此处输入图像描述

You can move your mouse around the div, even outside of the div itself a little bit and it will lerp towards the cursor.您可以在 div 周围移动鼠标,甚至在 div 本身之外稍微移动一下,它就会向 cursor 移动。

I'm trying to recreate this effect and it's pretty close, except, it's much more "glitchy".我正在尝试重新创建这种效果,它非常接近,除了它更“故障”。 You can see the movements are not smooth and it jumps around frequently.你可以看到动作不流畅,经常跳来跳去。 I assume this is because I'm not using a lerp function.我认为这是因为我没有使用 lerp function。 How would I recreate the effect on that site?我将如何在该网站上重新创建效果? Thanks in advance.提前致谢。

 const hoverElement = document.querySelector(".svg-container"); //My lerp function function lerp(start, end, amt) { return (1 - amt) * start + amt * end; } //Get bounds of my element + or - 10 pixels so it activates outside of the div let leftBound = hoverElement.getBoundingClientRect().left - 10; let rightBound = hoverElement.getBoundingClientRect().left + hoverElement.getBoundingClientRect().width + 10; let topBound = hoverElement.getBoundingClientRect().top - 10; let bottomBound = hoverElement.getBoundingClientRect().top + hoverElement.getBoundingClientRect().height + 10; window.addEventListener("mousemove", (e) => { //If the mouse is in the Bounds, translate the div, otherwise reset the translation if ( leftBound <= e.clientX && e.clientX <= rightBound && topBound <= e.clientY && e.clientY <= bottomBound ) { //Set the position so the center of the image is 0,0 instead of top-left corner let elementX = e.clientX - hoverElement.getBoundingClientRect().left - hoverElement.getBoundingClientRect().width / 2; let elementY = e.clientY - hoverElement.getBoundingClientRect().top - hoverElement.getBoundingClientRect().height / 2; hoverElement.style.transform = `translate(${elementX}px, ${elementY}px)`; } else { hoverElement.style.transform = `translate(${0}px, ${0}px)`; } });
 * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: black; }.formatting { display: flex; justify-content: center; align-items: center; height: 100vh; }.svg-container { border-radius: 50%; position: relative; border: 1px solid white; display: flex; justify-content: center; align-items: center; padding: 40px; cursor: pointer; transition: all 0.55s; }.svg-container::before { content: ""; background-color: none; position: absolute; border-radius: 50%; width: 0%; z-index: -4; height: 0%; transition: all 0.55s ease-in-out; }.svg-container:hover::before, .svg-container:focus::before { height: 100%; width: 100%; background-color: white; transition: height 0.55s ease-in-out, width 0.55s ease-in-out; }.svg-actual { position: absolute; display: flex; justify-content: center; align-items: center; z-index: 50; mix-blend-mode: difference; } path { transition: all 0.5s ease-in-out; }.svg-container:hover path { /* fill: white; */ transition: all 0.5s ease-in-out; }
 <div class="formatting"> <div class="svg-container"> <div class="svg-actual"> <svg width="27" height="15" viewBox="0 0 280 184" fill="none" xmlns="http://www.w3.org/2000/svg"> <path id="arrow" d="M259.585 97.2345L180.703 176.117L187.96 183.375L279.22 92.115L187.955 0.850169L180.707 8.09801L259.577 86.9878L0.129355 86.9758V97.2345L259.585 97.2345Z" fill="#ffffff"/> </svg> <!-- <div class="text"> Read More Read More Read More Read More Read More </div> --> </div> </div> </div>

If you can add a link to your project, I might be more helpful.如果您可以将链接添加到您的项目,我可能会更有帮助。 Anyway, this is the way to achieve the effect.无论如何,这是实现效果的方式。

  1. The element contains a container and inside of it theres the circle element, which means when you hover it, youalso hover the empty edges and not on the circle itself (important).该元素包含一个容器,其中有一个圆形元素,这意味着当你 hover 它时,你也 hover 空边而不是圆本身(重要)。
  2. Set a boundaries variable (they use 40px/45px)设置边界变量(他们使用 40px/45px)
  3. Add "mousemove" event on the square container(again, no the circle itself).在方形容器上添加“mousemove”事件(同样,没有圆圈本身)。 When you hover it with the mouse, calculate the distance between the mouse and the origin center of the container ((x or y) + ((width or height) / 2)) and store it as a value when the page loads) , this is the amount of pixels you need to translate.当你用鼠标 hover 它时,计算鼠标到容器原点中心的距离 ((x or y) + ((width or height) / 2)) 并将其存储为页面加载时的值) ,这是您需要翻译的像素数量。
  4. Check your pixels translate value do not cross the boundaries (you can use Math.max).检查您的像素转换值是否跨越边界(您可以使用 Math.max)。 make sure you calculate it correct when its less than 0.确保在小于 0 时计算正确。
  5. Now the tricky part, use Math.sqrt(value * newX/newY) to create some sort of an ease (theres probably some better ways, thats how I managed to do it).现在棘手的部分,使用 Math.sqrt(value * newX/newY) 来创造某种轻松(可能有一些更好的方法,这就是我设法做到的)。
  6. Apply the translate, and add "mouseleave" event to translate the circle to (0,0), so it get back to place when you're not hovering anymore.应用翻译,并添加“mouseleave”事件将圆圈翻译为(0,0),这样当你不再悬停时它会回到原位。
  7. Now the container should follow your mouse.现在容器应该跟随你的鼠标。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM