Krullmizter
Krullmizter

Reputation: 567

Fade & swap images with opacity & setInterval

I'm trying to swap out a main image when when a user hovers over a thumbnail of said image (like a gallery.) I need to use set & clearInterval whilst editing the DOM. All this with vanilla JavaScript. The issue I have here is that:

I know that set & clearInterval has something to do with this, but I can't get it to work properly.

const MAINIMG = document.getElementById("mainImage");
let imgSrc;

function swapImg(e) {
    MAINIMG.style.opacity = 1;
    imgSrc = e.target.src;

    if (MAINIMG.currentSrc != e.target.currentSrc) {
        fadeImg();    
    } 
}

function fadeImg() {
    timer = setInterval(opacity, 100);
}

function opacity(src) {

    if (MAINIMG.style.opacity >= 0.5) {
        MAINIMG.style.opacity = MAINIMG.style.opacity - 0.1;

    } else if (MAINIMG.style.opacity == 0.4) {
        MAINIMG.src = imgSrc;
        MAINIMG.style.opacity = MAINIMG.style.opacity + 0.1;
        clearInterval(timer);
    }
}

document.getElementById("imgOne").addEventListener("mouseover", swapImg);
document.getElementById("imgTwo").addEventListener("mouseover", swapImg);

HTML

<img id="mainImage" src="../images/imgOne.jpg" alt="" width="200" />

<div id="galleryImages">
   <img src="../images/imgOne.jpg" height="111.35" id="imgOne"/>
   <img src="../images/imgTwo.jpg" width="80" id="imgTwo" />
</div>

Upvotes: 0

Views: 265

Answers (1)

Emiel Zuurbier
Emiel Zuurbier

Reputation: 20954

Edited answer

The style.opacity value has a funny behavior to it. When it has a value above 0 it is an integer, but when it reaches 0 it becomes a string. So when doing MAINIMG.style.opacity = MAINIMG.style.opacity + 0.1; you are actually adding 0.1 to "0".

You can tackle this by parsing the opacity value to a floating point number and then add the 0.1 to it. Check the example below.

MAINIMG.style.opacity = parseFloat(MAINIMG.style.opacity) + 0.1;

Original answer

CSS is really good in handling transitions and will save you a lot of trouble calculating the opacity of an element. So if you can try to use it.

Down here I've made an example of what you could do to make it work using a combination of Vanilla JavaScript and CSS.

The swapImg function gets the src of the hovered image, just like in your own example, and checks if the MAINIMG.src is different from the hovered image. If it is not it will add a class to the MAINIMG called fade. This class sets the opacity of the image to 0. The duration of the opacity transition is set in the MAINIMG.style.transitionDuration = TRANSITION_SPEED + 'ms'; line. You can modify this value if you want to your liking.

After the transition is complete the MAINIMG will be invisible. Then the setTimeout kicks in, changes the src of the MAINIMG and removes the fade class so the image will appear again.

I hope this is what you are looking for.
If you have any questions let me know.

const MAINIMG = document.getElementById("mainImage");
const GALLERYIMAGES = document.getElementById("galleryImages");
const TRANSITION_SPEED = 250;

MAINIMG.style.transitionDuration = TRANSITION_SPEED + 'ms';

function swapImg(e) {
  if (e.target.tagName === 'IMG') {
    const newSrc = e.target.src;
    if (newSrc !== MAINIMG.src) {
      MAINIMG.classList.add('fade');
      setTimeout(function() {
        MAINIMG.src = newSrc;
        MAINIMG.classList.remove('fade');
      }, TRANSITION_SPEED);
    }
  }
}

GALLERYIMAGES.addEventListener('mouseover', swapImg);
img {
  display: inline-block;
}

#mainImage {
  width: 200px;
  height: 200px;
  transition-property: opacity;
  transition-timing-function: ease-in-out;
}

#mainImage.fade {
  opacity: 0;
}

#galleryImages img {
  width: 100px;
  height: 100px;
}
<img id="mainImage" src="https://source.unsplash.com/random/201x200" alt="" width="200" />

<div id="galleryImages">
   <img class="galleryHover" src="https://source.unsplash.com/random/201x200"/>
   <img class="galleryHover" src="https://source.unsplash.com/random/200x201"/>
</div>

Upvotes: 1

Related Questions