I am asking for a review of this code to see if I am following common best practices or if there is a better way to accomplish the goal set for this code.
My purpose was to create an image that would CSS3 rotateY()
to your mouse's position over it with as close to a semantic approach as I could get and scalable to any size.
My approach was a simple Div->Img tag structure, the div's size is indirectly the image's size due to the design limitation of listeners in JS being attached to the div (this is so the rotation's effect on size doesn't jitter the image around).
Anyway, if I could get some critique I would be very appreciative. Thank you for reading!
HTML index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hover Card</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<div class="hover-card">
<img src="images/me.jpg" alt="A picture of Torben Leif.">
</div>
</div>
<script src="scripts/main.js"></script>
</body>
</html>
css/style.css
.container {
margin: calc(50vh - 125px) auto;
width: 250px;
height: 250px;
}
.hover-card {
width: 230px;
height: 230px;
}
.hover-card img {
width: 100%;
height: 100%;
border-radius: 20px;
overflow: hidden;
object-fit: cover;
object-position: center 20%; /* Specific To Avatar Image */
transition: .2s linear;
transform-style: preserve-3d;
transform: perspective(600px) rotateY(var(--js-hover-rotate-val));
}
scripts/main.js
var card = document.querySelector('.hover-card');
var img = document.querySelector('.hover-card img');
var hoverComplete = true; // Used For Smooth Transitions While Rotating.
var degrees = 0; // External For Freeze Fix.
img.addEventListener('transitionend', (e) => {
if(e.propertyName == 'transform')
hoverComplete = true;
});
card.addEventListener('mousemove', (e) => {
if(hoverComplete) {
let newDegrees = Math.floor((1 - (e.pageX - card.getBoundingClientRect().left) / card.offsetWidth) * 90 - 45) * -1;
if(newDegrees !== degrees) { // Freeze Fix
degrees = newDegrees;
img.style.setProperty('--js-hover-rotate-val', degrees + 'deg');
hoverComplete = false;
}
}
});
card.addEventListener('mouseleave', (e) => {
img.style.setProperty('--js-hover-rotate-val', '0deg')
hoverComplete = false;
});