Link Image Animation on Hover

Create a link image animation with hover using HTML, CSS, and Javascript

 Yogesh    24 Dec, 2020    1800


 Demo  Download

In this post, we will learn how to create a text link hover effect animation with the background images. The images are appear on hover of an link element. To get started, first we will create the list item in HTML

HTML List Item

<ul class="list">
  <li><a dd-portfolio="project1" href="javascript:;">Garage</a></li>
  <li><a dd-portfolio="project2" href="javascript:;">Event Planner</a></li>
  <li><a dd-portfolio="project3" href="javascript:;">Restaurent</a></li>
  <li><a dd-portfolio="project4" href="javascript:;">Decorations</a></li>
  <li><a dd-portfolio="project5" href="javascript:;">Healthcare</a></li>
</ul>

In the above snippet we are using the "dd-portfolio" attribute to unique identification. Next, we will create a floating div that will float on the dom with the mouse position.

HTML Structure

<div class="floater dn" id="floater">
  <img id="project1" src="images/pexels-mike-190537.jpg">
  <img id="project2" src="images/pexels-alex-andrews-1983046.jpg">
  <img id="project3" src="images/pexels-chan-walrus-941861.jpg">
  <img id="project4" src="images/pexels-fox-750843.jpg">
  <img id="project5" src="images/pexels-miguel-á-padriñán-3936358.jpg">
</div>

Then we will apply the CSS to list item and floater div with hover animation.

:root {
  --font: 'Poppins', sans-serif;
  --floater_width: 700px;
  --floater_height: 400px;
  --transition: all .75s;
}
body {
  background-color: #000000;
}
/* List items */
.list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.list li {
  display: flex;
}
.list li a {
  display: flex;
  width: 100%;
  justify-content: center;
  border-bottom: 1px solid rgba(255, 255, 255, .25);
  outline: none;
  padding: 2rem;
  font-family: var(--font);
  font-weight: 900;
  font-size: 5rem;
  text-decoration: none;
  color: transparent;
  transition: var(--transition);
  -webkit-text-stroke: 2px #fff;
}
.list li a:hover {
  color: #fff;
  -webkit-text-stroke: 2px transparent;
  text-shadow: 1px 1px 3px rgba(0, 0, 0, .25);
}
/* Floater div */
.floater.dn {
  visibility: hidden;
  opacity: 0;
}
.floater {
  position: fixed;
  display: inline-block;
  width: var(--floater_width);
  height: var(--floater_height);
  visibility: visible;
  opacity: 1;
  z-index: -1;
  transition: var(--transition) cubic-bezier(0,.2,.6,1);
}
/* Portfolio Image */
.floater img {
  position: absolute;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  filter: blur(0px) hue-rotate(180deg);
  transition: var(--transition);
}
.floater img.active {
  opacity: 1;
  filter: blur(0) hue-rotate(0);
  box-shadow: none;
}

Now, let's do the crucial part.

The Javascript

// Create floater const
const floater = document.getElementById('floater');
// Get floater width & height
const floater_width = floater.clientWidth
const floater_height = floater.clientHeight
// Fetch all the portfolio images.
const portfolio_images = document.querySelectorAll('#floater img');
// List of the items.
const list_items = document.querySelectorAll('.list li a');
list_items.forEach((item) => {
  // Mouse move event
  item.addEventListener('mousemove', fnMouseMove);
  // Mouse leave event.
  item.addEventListener('mouseleave', fnMouseOut);
});
// Declate initial x,y pos at 0,0
let x =0, y=0;
// To detect the first mouse move.
let first_move = false;
// Get window half size(to change the animation direction).
let half_win_size = window.innerWidth / 2;
function fnMouseMove(e) {
  if( !first_move ) {
    // Remove display none on first mouse move.
    floater.classList.remove('dn');
    first_move = true;
  }
  // Get x,y mouse co-ordinates
  x = e.clientX || e.pageX;
  y = e.clientY || e.pageY;
  // X direction animation/pos
  let x_dir = x / window.innerWidth;
  let portfolio_attr = this.getAttribute('dd-portfolio');
  // Animate image on x axis
  ( x > half_win_size ? x_dir = -(x_dir*5) : x_dir = (  ( 1 - x_dir)*5) );
  floater.style.transform = "perspective(400px) rotateY("+(x_dir)+"deg)";
  // Activate the current hovered portfolio/image
  let current_portfolio = document.getElementById(portfolio_attr);
  portfolio_images.forEach(image => {
    image.classList.remove('active');
  });
  current_portfolio.classList.add('active');
  floater.style.opacity = 1;
  // Floater div animation
  floater.style.top = (y - ( floater_height / 2 ))+'px';
  floater.style.left = (x - ( floater_width / 2))+'px';
}
// Mouse leave function
function fnMouseOut(e) {
  // Remove the animation.
  portfolio_images.forEach(image => {
    image.classList.remove('active');
  });
}

Combine together in an HTML file and see the magic. I hope you guys liked the demo.


Credits / Resources

  • Google font(Poppins) => <a href="https://fonts.google.com/specimen/Poppins>https://fonts.google.com/specimen/Poppins</a>
  • Free Stock Photos(Pexels) => https://www.pexels.com/



Related Snippets