使用绝对坐标进行变换转换



我可以用下面的代码创建一个鼠标后面的方框。

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。

你不必使用translate(),我建议你在CSS中使用lefttop属性。它们可以帮助您基于坐标定位元素。

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()属性相对于盒子的大小起作用,但lefttop属性不起作用。在某些情况下,它也可以更快,因为在你的代码中有很多计算正在进行。然而,这很简单。

下面是使用requestAnimationFrame()函数的解决方案。requestAnimationFrame()方法告诉浏览器您希望执行动画,并请求浏览器调用指定的函数在下次重新绘制之前更新动画。对于高刷新率的显示器,此功能将运行更多次数以匹配刷新率。

更多信息在这里

下面是工作解决方案:

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>

最新更新