我可以用下面的代码做一个跟随鼠标的方框。
document.addEventListener('mousemove', (e) => {
document.documentElement.style.setProperty('--mouse-x', e.clientX + 'px');
document.documentElement.style.setProperty('--mouse-y', e.clientY + 'px');
});
.box {
width: 50px;
height: 50px;
background-color: blue;
transform: translate(calc(var(--mouse-x) - 50%), calc(var(--mouse-y) - 50%));
}
<div class="box"></div>
但是,一旦元素不在左上角,它就会断开。
document.addEventListener('mousemove', (e) => {
document.documentElement.style.setProperty('--mouse-x', e.clientX + 'px');
document.documentElement.style.setProperty('--mouse-y', e.clientY + 'px');
});
.box {
width: 50px;
height: 50px;
margin-left: 150px;
background-color: blue;
transform: translate(calc(var(--mouse-x) - 50%), calc(var(--mouse-y) - 50%));
}
<div class="box"></div>
如何在变换中使用绝对坐标?我不想使用left/top/ position : fixed/absolute,因为我需要保留元素在流中的位置。
我可以使用JavaScript来获取中心位置,然后使用该信息来获得正确的中心。
document.addEventListener('mousemove', (e) => {
document.documentElement.style.setProperty('--mouse-x', e.clientX + 'px');
document.documentElement.style.setProperty('--mouse-y', e.clientY + 'px');
});
window.addEventListener('load', (e) => {
const box = document.querySelector('.box');
const rect = box.getBoundingClientRect();
box.setAttribute('style', `
--center-x: ${rect.left + (rect.width / 2)}px;
--center-y: ${rect.top + (rect.height / 2)}px;
`);
});
.box {
width: 50px;
height: 50px;
margin-left: 150px;
background-color: blue;
transform: translate(calc(var(--mouse-x) - var(--center-x)), calc(var(--mouse-y) - var(--center-y)));
}
<div class="box"></div>
这是可行的,但它并不理想,如果页面中的其他内容发生变化,它很容易被破坏。当有更多的元素时,它也会变慢,我希望它尽可能快。有没有更好的方法来做这件事?我可以使用CSS/Vanilla JS。
发布于 2021-10-10 11:00:08
请不要使用translate()
,我建议您在CSS中使用left
和top
属性。它们可以帮助您根据坐标定位图元。
window.addEventListener('load', (e) => {
const box = document.querySelector('.box');
const rect = box.getBoundingClientRect();
document.addEventListener('mousemove', (e) => {
box.style.left = e.pageX + 'px';
box.style.top = e.pageY + 'px';
});
});
.box {
width: 50px;
height: 50px;
position:absolute;
transform:translate(-50%,-50%);
background-color: blue;
}
<div class="box"></div>
transform: translate()
属性相对于框的大小有效,但left
和top
属性不起作用。在某些情况下,它也可以快得多,因为在你的代码中有大量的计算。然而,这很简单。
发布于 2021-10-10 19:24:48
这是一个使用requestAnimationFrame()
函数的解决方案。requestAnimationFrame()
方法告诉浏览器您希望执行动画,并请求浏览器在下一次重新绘制之前调用指定的函数来更新动画。对于刷新率较高的监视器,此函数的运行次数将超过与刷新率匹配的次数。
更多信息here
以下是可行的解决方案:
const box = document.querySelector('.box');
const rect = box.getBoundingClientRect();
let mouseX = 0;
let mouseY = 0
document.addEventListener('mousemove', (e) => {
mouseX = e.pageX + 'px';
mouseY = e.pageY + 'px';
})
function mouseMove() {
box.style.left = mouseX;
box.style.top = mouseY;
requestAnimationFrame(mouseMove)
};
mouseMove()
.box {
width: 50px;
height: 50px;
position: absolute;
transform: translate(-50%, -50%);
background-color: blue;
}
<div class="box"></div>
https://stackoverflow.com/questions/69517764
复制