I am trying to reveal an image when I hover over a div or a line of text.
here are some references to the effect I am trying to achieve:
https://randellcommercial.uk/ - plugins.
https://1til1landskab.dk/ - really nice, also it changes background colour too which is cool.
http://adasokol.com/works/ - bit mental, but you get the idea.
this is what I have been basing my efforts off. however, it seems there is so much unnecessary code. I've been trimming it down and ended up with this. However, it's no good. it's glitchy and feels over-engineered.
document.documentElement.className = "js";
var supportsCssVars = function() {
var e,
t = document.createElement("style");
return (
(t.innerHTML = "root: { --tmp-var: bold; }"),
document.head.appendChild(t),
(e = !!(
window.CSS &&
window.CSS.supports &&
window.CSS.supports("font-weight", "var(--tmp-var)")
)),
t.parentNode.removeChild(t),
e
);
};
{
const mapNumber = (X, A, B, C, D) => ((X - A) * (D - C)) / (B - A) + C;
const getMousePos = (e) => {
let posx = 0;
let posy = 0;
if (!e) e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
} else if (e.clientX || e.clientY) {
posx =
e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy =
e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
return {
x: posx,
y: posy
};
};
// Generate a random float.
const getRandomFloat = (min, max) =>
(Math.random() * (max - min) + min).toFixed(2);
class HoverImgFx2 {
constructor(el) {
this.DOM = {
el: el
};
this.DOM.reveal = document.createElement("div");
this.DOM.reveal.className = "hover-reveal";
this.DOM.reveal.innerHTML = `<div class="hover-reveal__inner"><div class="hover-reveal__img" style="background-image:url(${this.DOM.el.dataset.img})"></div></div>`;
this.DOM.el.appendChild(this.DOM.reveal);
this.DOM.revealInner = this.DOM.reveal.querySelector(".hover-reveal__inner");
this.DOM.revealInner.style.overflow = "hidden";
this.DOM.revealImg = this.DOM.revealInner.querySelector(
".hover-reveal__img"
);
this.initEvents();
}
initEvents() {
this.positionElement = (ev) => {
const mousePos = getMousePos(ev);
const docScrolls = {
left: document.body.scrollLeft + document.documentElement.scrollLeft,
top: document.body.scrollTop + document.documentElement.scrollTop
};
this.DOM.reveal.style.top = `${mousePos.y + 20 - docScrolls.top}px`;
this.DOM.reveal.style.left = `${mousePos.x + 20 - docScrolls.left}px`;
};
this.mouseenterFn = (ev) => {
this.positionElement(ev);
this.showImage();
};
this.mousemoveFn = (ev) =>
requestAnimationFrame(() => {
this.positionElement(ev);
});
this.mouseleaveFn = () => {
this.hideImage();
};
this.DOM.el.addEventListener("mouseenter", this.mouseenterFn);
this.DOM.el.addEventListener("mousemove", this.mousemoveFn);
this.DOM.el.addEventListener("mouseleave", this.mouseleaveFn);
}
showImage() {
TweenMax.killTweensOf(this.DOM.revealInner);
TweenMax.killTweensOf(this.DOM.revealImg);
this.tl = new TimelineMax({
onStart: () => {
this.DOM.reveal.style.opacity = 1;
TweenMax.set(this.DOM.el, {
zIndex: 1000
});
}
})
.add("begin")
.add(
new TweenMax(this.DOM.revealInner, 0.4, {
ease: Quint.easeOut,
startAt: {
x: "-100%",
y: "-100%"
},
x: "0%",
y: "0%"
}),
"begin"
)
.add(
new TweenMax(this.DOM.revealImg, 0.4, {
ease: Quint.easeOut,
startAt: {
x: "100%",
y: "100%"
},
x: "0%",
y: "0%"
}),
"begin"
);
}
hideImage() {
TweenMax.killTweensOf(this.DOM.revealInner);
TweenMax.killTweensOf(this.DOM.revealImg);
this.tl = new TimelineMax({
onStart: () => {
TweenMax.set(this.DOM.el, {
zIndex: 999
});
},
onComplete: () => {
TweenMax.set(this.DOM.el, {
zIndex: ""
});
TweenMax.set(this.DOM.reveal, {
opacity: 0
});
}
})
.add("begin")
.add(
new TweenMax(this.DOM.revealInner, 0.3, {
ease: Quint.easeOut,
x: "100%",
y: "100%"
}),
"begin"
)
.add(
new TweenMax(this.DOM.revealImg, 0.3, {
ease: Quint.easeOut,
x: "-100%",
y: "-100%"
}),
"begin"
);
}
}
[...document.querySelectorAll('[data-fx="2"] > a, a[data-fx="2"]')].forEach(
(link) => new HoverImgFx2(link)
);
[
...document.querySelectorAll(
".block__title, .block__link, .content__text-link"
)
].forEach((el) => {
const imgsArr = el.dataset.img.split(",");
for (let i = 0, len = imgsArr.length; i <= len - 1; ++i) {
const imgel = document.createElement("img");
imgel.style.visibility = "hidden";
imgel.style.width = 0;
imgel.src = imgsArr[i];
imgel.className = "preload";
contentel.appendChild(imgel);
}
});
imagesLoaded(document.querySelectorAll(".preload"), () =>
document.body.classList.remove("loading")
);
}
.hover-reveal {
position: fixed;
width: 200px;
height: 150px;
}
.hover-reveal__inner,
.hover-reveal__img {
width: 100%;
height: 100%;
position: relative;
}
.hover-reveal__img {
background-size: cover;
background-position: 50% 50%;
}
<script src="https://cdn.jsdelivr.net/npm/gsap@3.0.1/dist/gsap.min.js"></script>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<main>
<div class="content">
<div class="block" data-fx="2">
<a class="block__link" data-img="https://www.kaspersky.co.uk/content/en-gb/images/product-icon-KSOS.png">Asli</a>
<a class="block__link" data-img="https://www.kaspersky.co.uk/content/en-gb/images/product-icon-KSOS.png">D24</a>
<a class="block__link" data-img="https://www.kaspersky.co.uk/content/en-gb/images/product-icon-KSOS.png">Jantung</a>
<a class="block__link" data-img="https://www.kaspersky.co.uk/content/en-gb/images/product-icon-KSOS.png">Tracka</a>
</div>
</div>
</main>
<script src="js/TweenMax.min.js"></script>
<script src="js/demo.js"></script>
</body>
How can I create a simple image reveal on rollover that is clean and simple?