Smooth content change transition

Inspired by: https://stackoverflow.com/questions/48297873/how-to-change-innerhtml-smoothly-with-pure-javascript?

by katalin_2003

HTML

<button id="proj_switcher">Projects</button>
<div id="project" class="reveal">
  <div id="proj_name"></div>
  <div id="proj_description"></div>
  <img id="proj_img" src=""><br>
</div>

CSS

body {
  font-family: sans-serif;
}

#project {
  transition: opacity 0.5s ease-in-out;
}

.fade {
  opacity: 0;
}

.reveal {
  opacity: 1;
}

JavaScript

/**
 * Constructor function for Projects
 */
function Project(name, description, img) {
  this.name = name;
  this.description = description;
  this.img = img;
}

// An array containing all the projects with their information
var projects = [
  new Project('Project 1', 'Project 1 Description', 'https://www.colorbook.io/imagecreator.php?hex=1168A6&width=250&height=150&text=Hello1'),
  new Project('Project 2', 'Project 2 Description', 'https://www.colorbook.io/imagecreator.php?hex=231f20&width=250&height=150&text=Hello2'),
  new Project('Project 3', 'Project 3 Description', 'https://www.colorbook.io/imagecreator.php?hex=d9dc3c&width=250&height=150&text=Hello3'),
  new Project('Project 4', 'Project 4 Description', 'https://www.colorbook.io/imagecreator.php?hex=036017&width=250&height=150&text=Hello4'),
  new Project('Project 5', 'Project 5 Description', 'https://www.colorbook.io/imagecreator.php?hex=4e4e4c&width=250&height=150&text=Hello5')
];

// Cacheing HTML elements
var project = document.querySelector('#project');
var projName = document.querySelector('#proj_name');
var projDescr = document.querySelector('#proj_description');
var projImg = document.querySelector('#proj_img');
var projButton = document.querySelector('#proj_switcher');

// Index of the current project being displayed
var projIndex = 0;

projButton.addEventListener('click', function() {

  // Fade out
  project.classList.remove('reveal');
  project.classList.add('fade');

  // Fade in 
  setTimeout(function() {
    projName.innerHTML = projects[projIndex].name;
    projDescr.innerHTML = projects[projIndex].description;
    projImg.src = projects[projIndex].img;
    projImg.style.width = '250px';
    projImg.style.height = '150px';
    projIndex = (projIndex + 1) % projects.length;
    project.classList.add('reveal');
    projButton.textContent = 'Next Project';
  }, 500);

});