<div class="wrapper">
	<main>
	<ul>
		<li><a href="#">
			<span class="text">First menu link is here</span>
			<div class="image"><img src='https://images.unsplash.com/photo-1610119362388-44309205b6cc?crop=entropy&cs=srgb&fm=jpg&ixid=MXwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHw&ixlib=rb-1.2.1&q=85' alt=''></div>
		</a></li>
		<li><a href="#">
			<span class="text">The second project...</span>
			<div class="image"><img src='https://images.unsplash.com/photo-1610538200120-4afba13d080b?crop=entropy&cs=srgb&fm=jpg&ixid=MXwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHw&ixlib=rb-1.2.1&q=85' alt=''></div>
		</a></li>
		<li><a href="#">
			<span class="text">And yet another one after that</span>
			<div class="image"><img src='https://images.unsplash.com/photo-1610847033737-0c62d8d14534?crop=entropy&cs=srgb&fm=jpg&ixid=MXwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHw&ixlib=rb-1.2.1&q=85' alt=''></div>
		</a></li>
		<li><a href="#">
			<span class="text">Short one!</span>
			<div class="image"><img src='https://images.unsplash.com/photo-1609783113618-888ff54a7802?crop=entropy&cs=srgb&fm=jpg&ixid=MXwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHw&ixlib=rb-1.2.1&q=85' alt=''></div>
		</a></li>
		<li><a href="#">
			<span class="text">And the final one now</span>
			<div class="image"><img src='https://images.unsplash.com/photo-1610247998239-f02876883a8e?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MXwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHw&ixlib=rb-1.2.1&q=80&w=400' alt=''></div>
		</a></li>
	</ul>
</main>
</div>
html,
body {
	padding: 0;
	margin: 0;
	height: 100%;
}

.wrapper {
	width: 100%;
	height: 100%;
	overflow: hidden;
}

main {
	max-width: 900px;
	margin: 0 auto;
	padding: 75px 0;
}

ul {
	border-top: 1px solid #585858;
	li {
		a {
			height: 80px;
			display: flex;
			align-items: center;
			font-family: "Fraunces", serif;
			font-size: 42px;
			text-decoration: none;
			color: #a1a1a1;
			letter-spacing: 0.025em;
			border-bottom: 1px solid #585858;
			padding: 0 30px;
			position: relative;
			z-index: 1;
			.text {
				pointer-events: none;
				position: relative;
				z-index: 1;
				transition: transform 0.4s;
			}
			.image {
				max-width: 300px;
				max-height: 500px;
				opacity: 0;
				position: absolute;
				top: 0;
				left: 0;
				z-index: 0;
				pointer-events: none;
				background-color:#FFF;
				img {
					display: block;
					max-width: 100%;
					max-height: 100%;
				}
			}

			&.is-active {
				z-index: 2;
				.text {
					color: #000;
					transform: translateX(20px);
				}
			}
		}
	}
}
View Compiled
var cursor = document.getElementById("cursor");
var links = document.querySelectorAll("ul a");
var images = document.querySelectorAll("ul a .image");

Array.prototype.forEach.call(links, function (link) {
	link.addEventListener("mouseenter", linkEnterHandler, { passive: true });
	link.addEventListener("mouseleave", linkLeaveHandler, { passive: true });
	link.addEventListener("mousemove", linkMoveHandler, { passive: true });
});

function linkEnterHandler(e) {
	var image = this.querySelector(".image");
	var linkX = this.getBoundingClientRect().left;
	var linkY = this.getBoundingClientRect().top;
	var cursorX = e.clientX - linkX;
	var cursorY = e.clientY - linkY;
	var centerPoint = {};
	centerPoint.x = cursorX - image.offsetWidth / 2;
	centerPoint.y = cursorY - image.offsetHeight / 2;

	this.classList.add("is-active");
	gsap.set(image, { x: centerPoint.x, y: centerPoint.y });
	gsap.to(image, { autoAlpha: 1, duration: 0.4 });
}

function linkLeaveHandler() {
	var image = this.querySelector(".image");
	gsap.to(image, { autoAlpha: 0, duration: 0.2, overwrite: true });
	image.classList.remove("is-faded");
	this.classList.remove("is-active");
}

function linkMoveHandler(e) {
	var image = this.querySelector(".image");
	var linkX = this.getBoundingClientRect().left;
	var linkY = this.getBoundingClientRect().top;
	var textContent = this.querySelector('.text');
	var textLeftCoord = textContent.getBoundingClientRect().left;
	var textWidth = textContent.offsetWidth;
	var textRightBoundary = textLeftCoord + textWidth;
	var cursorX = e.clientX - linkX;
	var cursorY = e.clientY - linkY;
	var centerPoint = {};
	centerPoint.x = cursorX - image.offsetWidth / 2;
	centerPoint.y = cursorY - image.offsetHeight / 2;
	
	if(cursorX < textRightBoundary - 12 && !image.classList.contains("is-faded")){
		gsap.to(image.querySelector('img'), 0.5, { opacity: 0.6, overwrite: false });
		image.classList.add("is-faded");
	} else if(cursorX >= textRightBoundary - 12 && image.classList.contains("is-faded")){
		gsap.to(image.querySelector('img'), 0.5, { opacity: 1, overwrite: false });
		image.classList.remove("is-faded");
	}

	gsap.to(image, 1, { x: centerPoint.x, y: centerPoint.y, overwrite: false });
}

function getImageCoords(element, image, event){
	var image = element.querySelector(".image")
	var linkX = element.getBoundingClientRect().left
	var linkY = element.getBoundingClientRect().top
	var cursorX = event.clientX - linkX
	var cursorY = event.clientY - linkY
	
	return {x: cursorX - image.offsetWidth / 2, y: cursorY - image.offsetHeight / 2}
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.co/gsap@3/dist/gsap.min.js