Following Eyes (attempt)
Idea for JS code was taken from: https://codepen.io/sergep/pen/rkcjt
by Konstantin Rouda
HTML
<div class="face">
<div class="face__eye face__eye--left">
<div class="face__pupil"></div>
</div>
<div class="face__eye face__eye--right">
<div class="face__pupil"></div>
</div>
</div>
<div class="log"></div>
<script src="script.js"></script>
<!-- <script>
;(function() {
"use strict";
//// Variables
const face = document.querySelector(".face");
const pupils = face.querySelectorAll(".face__pupil");
const log = document.querySelector(".log");
face.addEventListener("mousemove", onMouseMove);
function onMouseMove(e) {
debugger;
let eye = pupils[0].parentNode;
let pupil = pupils[0];
let relativeX = (e.pageX - this.offsetLeft) - (pupil.offsetWidth + (pupil.offsetWidth / 2));
let relativeY = (e.pageY - this.offsetTop) - (pupil.offsetHeight + (pupil.offsetHeight / 2));
log.textContent = `e.pageY: ${e.pageY} relativeY: ${relativeY}
| (e.pageY - this.offsetTop): ${(e.pageY - this.offsetTop)}
(eye.offsetTop + eye.offsetHeight) ${(eye.offsetTop + eye.offsetHeight)}`;
if(relativeX > (eye.offsetWidth - pupil.offsetWidth))
{ relativeX = eye.offsetWidth - pupil.offsetWidth; }
if(relativeX < (eye.offsetLeft))
{ relativeX = eye.offsetLeft - (pupil.offsetWidth / 2); }
if( relativeY > ((eye.offsetTop + eye.offsetHeight) / 2) )
{ relativeY = ( (eye.offsetTop + eye.offsetHeight) / 2); }
if( relativeY < (eye.offsetTop))
{ relativeY = eye.offsetTop - pupil.offsetHeight - 10; }
for(let pupil of pupils) {
pupil.style.setProperty("left", `${relativeX}px`);
pupil.style.setProperty("top", `${relativeY}px`);
}
};
})();
</script>-->
CSS
HTML {
font-family: sans-serif, serif;
font-size: 100%;
line-height: 1.5;
box-sizing: border-box;
}
BODY {
color: #3a3d40;
margin: 0;
}
*, *::before, *::after {
box-sizing: inherit;
color: inherit;
}
/*Actual Style*/
.face {
position: relative;
max-width: 300px; height: 300px;
margin: 2em auto 0;
border: 1px solid;
}
.face__eye {
position: absolute;
top: 15%;
width: 40%; height: 40%;
border: 1px solid;
border-radius: 50%;
}
.face__eye--left {
left: 5%;
}
.face__eye--right {
right: 5%;
}
.face__pupil {
position: absolute;
left: 35%; top: 35%;
width: 30%; height: 30%;
border-radius: inherit;
background: #000;
}
JavaScript
;(function() {
"use strict";
//// Variables
const face = document.querySelector(".face");
const pupils = face.querySelectorAll(".face__pupil");
const log = document.querySelector(".log");
function setEyePosition(eye, pupil, eyeOffsetX, eyeOffsetY) {
const r = pupil.offsetWidth / 2;
const eyeX = (eye.offsetWidth / 2) - r;
const eyeY = (eye.offsetHeight / 2) - r;
const distanceThreshold = eyeX;
let relativeX = 0;
let relativeY = 0;
face.addEventListener("mousemove", onMouseMove);
function onMouseMove(e) {
const pointX = e.pageX - r - eyeOffsetX - eyeX;
const pointY = e.pageY - r - eyeOffsetY - eyeY;
const distance = Math.sqrt( Math.pow(pointX, 2) + Math.pow(pointY, 2) );
if(distance < distanceThreshold) {
relativeX = e.pageX - eyeOffsetX - r;
relativeY = e.pageY - eyeOffsetY - r;
} else {
relativeX = pointX / distance * distanceThreshold + eyeX;
relativeY = pointY / distance * distanceThreshold + eyeY;
}
};
let x = 0;
let y = 0;
/*Update pupil location*/
let intervalID = window.setInterval(function() {
x += (relativeX - x) / 1;
y += (relativeY - y) / 1;
pupil.style.setProperty("left", `${x}px`);
pupil.style.setProperty("top", `${y}px`);
}, 5);
};
const eyeLeft = pupils[0].parentNode;
const eyeRight = pupils[1].parentNode;
const eyeLeftOffsetX = eyeLeft.offsetParent.offsetLeft + eyeLeft.offsetLeft;
const eyeLeftOffsetY = eyeLeft.offsetParent.offsetTop + eyeLeft.offsetTop;
const eyeRightOffsetX = eyeRight.offsetParent.offsetLeft + eyeRight.offsetLeft;
const eyeRightOffsetY = eyeRight.offsetParent.offsetTop + eyeRight.offsetTop;
setEyePosition(eyeLeft, pupils[0], eyeLeftOffsetX, eyeLeftOffsetY);
setEyePosition(eyeRight, pupils[1], eyeRightOffsetX, eyeRightOffsetY);
})();