Trying to create this mouse tracking effect - which causes a transform3d change on the block and contents - and also adds a flash light where the mouse is.
How would you write this in vanilla js so it's stable - I am not sure on the formula used to calculate these degree changes - as they seem to go min -8 to max 9 degrees.
https://jsfiddle.net/qzo3ck5m/46/
var myElement = $("#p1");
function setTranslate(xPos, yPos, zPos, el) {
console.log("test");
el.style.transform = `translate3d(0, 0, 0) scale3d(1, 1, 1) rotateX(${xPos}deg) rotateY(${yPos}deg) rotateZ(0deg) skew(0deg, 0deg)`;
}
myElement.mousemove(function(event) {
console.log("mousemoveY---", event.clientX, event.clientY);
let y = event.clientY;
let x = event.clientX;
var position = {
top: myElement[0].offsetTop,
left: myElement[0].offsetLeft
};
console.log("x", x);
console.log("y", y);
console.log("position", position);
let degx = position.left - x;
let degy = position.top - y;
console.log("degx", degx);
console.log("degy", degy);
let fullDegrees = 8;
setTranslate(-degx / 20, -degy / 20, 0, myElement[0]);
});
myElement.mouseleave(function() {
console.log("mouseleave");
setTranslate(0, 0, 0, myElement[0]);
});
.container {
padding: 40px;
}
.blockwrapper {
will-change: transform;
transform: translate3d(0, 0, 0) scale3d(1, 1, 1) rotateX(0deg) rotateY(0deg) rotateZ(0deg) skew(0deg, 0deg);
margin: 10px;
}
.block {
background-color: skyblue;
width: 160px;
height: 160px;
}
.moved {
background-color: pink;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="container">
<div class="blockwrapper">
<div class="block moved">Moved</div>
</div>
<div id="p1" class="blockwrapper">
<div class="block">Movable</div>
</div>
</div>
How about calculating the distance between the center of the block and the cursor position?
Also, if you want to use jQuery, use the $.fn.on
method to attach the listeners.
let sensitivity = 0.5;
function setTranslate($el, x, y, z=0) {
$el.css({
transform: `rotateX(${x}deg) rotateY(${y}deg) rotateZ(${z}deg)`
});
}
$('.blockwrapper').on({
mousemove: function(event) {
const $block = $(event.currentTarget).find('.block');
const $spotlight = $block.find('.spotlight');
let { clientX: x, clientY: y } = event;
let rect = $block[0].getBoundingClientRect();
// Calculate the center of the element
let centerX = rect.left + rect.width / 2;
let centerY = rect.top + rect.height / 2;
// Calculate the relative position from the center
let deltaX = (x - centerX);
let deltaY = (y - centerY);
// Calculate the rotation angles to move away from the cursor
let rotateX = -deltaY * sensitivity; // Invert to tilt away
let rotateY = deltaX * sensitivity; // Invert to tilt away
setTranslate($block, rotateX, rotateY);
// Move the spotlight
let spotlightSize = $spotlight.width();
let spotlightX = x - rect.left - spotlightSize / 2;
let spotlightY = y - rect.top - spotlightSize / 2;
$spotlight.css({
transform: `translate(${spotlightX}px, ${spotlightY}px)`,
opacity: 1
});
},
mouseleave: function(event) {
const $block = $(event.currentTarget).find('.block');
const $spotlight = $block.find('.spotlight');
setTranslate($block, 0, 0);
// Hide the spotlight
$spotlight.css({ opacity: 0 });
}
});
body {
background: #000;
}
.container {
padding: 0.5rem;
}
.blockwrapper {
display: inline-block;
perspective: 1000px;
position: relative;
overflow: visible;
margin: 0.5rem;
background: red;
width: fit-content;
border-radius: 2rem;
will-change: transform;
transform: translate3d(0, 0, 0) scale3d(1, 1, 1) rotateX(0deg) rotateY(0deg) rotateZ(0deg) skew(0deg, 0deg);
}
.block {
position: relative;
z-index: 1;
overflow: hidden;
width: 120px;
height: 120px;
padding: 1rem;
border: thin solid #444;
border-radius: 1.8rem;
background-color: #222;
color: #eee;
transition: transform 0.5s ease;
}
.spotlight {
position: absolute;
top: 0;
left: 0;
width: 80px;
height: 80px;
border-radius: 50%;
pointer-events: none;
background: rgb(255,255,0);
background: radial-gradient(circle, rgba(255,255,0,0.5) 0%, rgba(255,255,0,0.1) 25%, transparent 75%);
transform: translate(-50%, -50%);
transition: opacity 0.2s ease;
z-index: 2;
opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div class="container">
<div class="blockwrapper">
<div class="block">
Movable #1
<div class="spotlight"></div>
</div>
</div>
<div class="blockwrapper">
<div class="block">
Movable #2
<div class="spotlight"></div>
</div>
</div>
<div class="blockwrapper">
<div class="block">
Movable #3
<div class="spotlight"></div>
</div>
</div>
</div>