If you transform rotate, it seems to work, but you have to move the mouse cursor to the top left of the browser for rotate to work. I want it to work when I move the mouse cursor relative to the center of the blue square element. What should I do?
window.addEventListener("mousemove", (e) => {
const card = document.querySelector(".card");
const body = document.querySelector("body");
const w = card.clientWidth;
const h = card.clientHeight;
const bodyRect = body.getBoundingClientRect();
const cardRect = card.getBoundingClientRect();
const left = cardRect.left - bodyRect.left (card.clientWidth/2);
const top = cardRect.top - bodyRect.top (card.clientHeight/2);
console.log(`cardRect.left : ${cardRect.left}, bodyRect.left : ${bodyRect.left}, card.clientWidth/2 : ${card.clientWidth/2}`);
console.log(`cardRect.top : ${cardRect.top}, bodyRect.top : ${bodyRect.top}, card.clientHeight/2 : ${card.clientHeight/2}`);
const rotx = (e.pageY - top) / e.pageY;
const roty = (e.pageX - left) / e.pageX;
console.log(`roty : ${roty}, rotx : ${rotx}`)
card.style.msTransform = `rotateX(${rotx}deg) rotateY(${roty}deg)`;
card.style.webkitTransform = `rotateX(${rotx}deg) rotateY(${roty}deg)`;
card.style.transform = `rotateX(${rotx}deg) rotateY(${roty}deg)`;
});
.card {
width: 400px;
height: 400px;
background-color: #00f;
margin: 0 auto;
padding: 0;
transform-style: preserve-3d;
transform: perspective(400px);
will-change: transform;
}
<div >
</div>
CodePudding user response:
Your math is all over the place. Look at the rotation angles you compute/log, they are <5deg for almost the entire screen.
window.addEventListener("mousemove", (e) => {
const card = document.querySelector(".card");
const cardRect = card.getBoundingClientRect();
const center = new DOMPoint(
cardRect.x cardRect.width/2,
cardRect.y cardRect.height/2
);
//turn 180deg/400px distance from the center
const scale = 180/400;
const rotY = (e.pageX - center.x) * scale;
const rotX = -(e.pageY - center.y) * scale;
card.style.transform = `rotateX(${rotX}deg) rotateY(${rotY}deg)`;
});
.card {
width: 400px;
height: 400px;
background-color: #00f;
margin: 0 auto;
padding: 0;
transform-style: preserve-3d;
transform: perspective(400px);
will-change: transform;
}
<div >
</div>
CodePudding user response:
Your formulae for rotx and roty are wrong. Try these:
const rotx = e.pageY - card.clientHeight / 2;
const roty = e.pageX - card.clientWidth / 2;
Here is a snippet to demonstrate.
window.addEventListener("mousemove", (e) => {
const card = document.querySelector(".card");
const body = document.querySelector("body");
const w = card.clientWidth;
const h = card.clientHeight;
const bodyRect = body.getBoundingClientRect();
const cardRect = card.getBoundingClientRect();
const left = cardRect.left - bodyRect.left (card.clientWidth/2);
const top = cardRect.top - bodyRect.top (card.clientHeight/2);
console.log(`cardRect.left : ${cardRect.left}, bodyRect.left : ${bodyRect.left}, card.clientWidth/2 : ${card.clientWidth/2}`);
console.log(`cardRect.top : ${cardRect.top}, bodyRect.top : ${bodyRect.top}, card.clientHeight/2 : ${card.clientHeight/2}`);
const rotx = e.pageY - card.clientHeight / 2;
const roty = e.pageX - card.clientWidth / 2;
console.log(`roty : ${roty}, rotx : ${rotx}`)
card.style.msTransform = `rotateX(${rotx}deg) rotateY(${roty}deg)`;
card.style.webkitTransform = `rotateX(${rotx}deg) rotateY(${roty}deg)`;
card.style.transform = `rotateX(${rotx}deg) rotateY(${roty}deg)`;
});
.card {
width: 400px;
height: 400px;
background-color: #00f;
margin: 0 auto;
padding: 0;
transform-style: preserve-3d;
transform: perspective(400px);
will-change: transform;
}
<div >
</div>