GhostOrder
GhostOrder

Reputation: 663

Add transition css to image slider

I have a slider with 3 images and 3 buttons which change the current image 'src' attribute (and hence change the current image), but now I want to add a smooth transition when I change the image and I would like to get this using css transitions.

So when I click on any bullet I need the current image fades out and then the new image fades in. how can I do this?

var listItemContainer = document.getElementById('carousel-index');
var imageChanger = document.getElementById('image-container').getElementsByTagName('img');
var bulletNumber;

for (i = 0; i < listItemContainer.children.length; i++){
  (function(index){
     listItemContainer.children[i].onclick = function(){
     bulletNumber = index;
     imageChanger[0].setAttribute('src', 'https://civilian-interviewe.000webhostapp.com/img/mini_slider_' + (bulletNumber+1) + '.png');   
    }
  })(i);
};
body{
 text-align:center;
}
#carousel-index{
  margin:0;
  padding:0;  
}
#carousel-index li {
  display: inline-block;
  width: 2em;
  height: 2em;
  border-radius: 100%;
  background-color: #666;
  cursor: pointer;
}
<div id="image-container">
  <img src="https://civilian-interviewe.000webhostapp.com/img/mini_slider_1.png"/>
    <ul id="carousel-index">
      <li></li>
      <li></li>
      <li></li>	
    </ul>
</div> 

Here is a CODEPEN

PD: I want to do this without Jquery.

Upvotes: 0

Views: 7046

Answers (5)

myfunkyside
myfunkyside

Reputation: 3950

One more alternative, JS based, didn't change HTML or CSS (explanation as comments in the code):

var listItemContainer = document.getElementById('carousel-index');
var imageChanger = document.getElementById('image-container').getElementsByTagName('img')[0];
var newSrc, fadeDelta=-0.01; //don't change 'delta', change 'fadeoutDelay' and 'fadeinDelay'

(function initImageChanger(i,count){
  imageChanger.style.opacity = 1; //set opacity in JS, otherwise the value returns "" (empty)
  listItemContainer.children[i].onclick = function(){
    var fadeoutDelay=5, fadeinDelay=15, opacity=parseFloat(imageChanger.style.opacity); //change delays to alter fade-speed
    
    function changeSrc(){
      var src = imageChanger.getAttribute('src');
      var ext = src.substring(src.lastIndexOf('.')); //store extension
      src = src.substring(0,src.lastIndexOf('_')+1); //store source up to the identifying number
      return src+i+ext; //combine parts into full source
    }
    function fade(delay){
      imageChanger.style.opacity = (opacity+=fadeDelta);
      if (fadeDelta<0 && opacity<=0){ //fade-out complete
        imageChanger.setAttribute('src',newSrc);
        fadeDelta*=-1, delay=fadeinDelay; //invert fade-direction
      } else if (fadeDelta>0 && opacity>=1){newSrc=null, fadeDelta*=-1; return;} //fade-in complete, stop function
      setTimeout(function(){fade(delay);},delay);
    }
    //start fade, but only if image isn't already fading, otherwise only change source (and reset)
    if (changeSrc() != imageChanger.getAttribute('src')){
      newSrc=changeSrc();
      if (opacity==0 || opacity==1){fade(fadeoutDelay);}
      else if (fadeDelta>0){fadeDelta *= -1;} //reset fade for new source
    }
  };
  if (++i < count){initImageChanger(i,count);} //iterate to next element
})(0,listItemContainer.children.length); //supply start-arguments
body {text-align:center;}

#image-container img {width:auto; height:150px;}
#carousel-index {margin:0; padding:0;}
#carousel-index li {display:inline-block; width:2em; height:2em; border-radius:100%; background-color:#666; cursor:pointer;}
<div id="image-container">
  <img src="https://civilian-interviewe.000webhostapp.com/img/mini_slider_1.png"/>
  <ul id="carousel-index"><li></li><li></li><li></li></ul>
</div>
codepen: http://codepen.io/anon/pen/xgwBre?editors=0010

Upvotes: 1

Deep
Deep

Reputation: 9794

use CSS3 animation with add class in javascript

var listItemContainer = document.getElementById('carousel-index');
var imageChanger = document.getElementById('image-container').getElementsByTagName('img');
var bulletNumber;

for (i = 0; i < listItemContainer.children.length; i++) {
  (function(index) {
    listItemContainer.children[i].onclick = function() {
      bulletNumber = index;

         imageChanger[0].className = "hide"; 
      
      setTimeout(function(){ 
          imageChanger[0].setAttribute('src', 'https://civilian-interviewe.000webhostapp.com/img/mini_slider_' + (bulletNumber + 1) + '.png');
         },501);
       
      setTimeout(function(){ 
     imageChanger[0].className = "show";
      }, 1001);
      
    }
  })(i);
};
body {
  text-align: center;
}
#carousel-index {
  margin: 0;
  padding: 0;
}
#carousel-index li {
  display: inline-block;
  width: 2em;
  height: 2em;
  border-radius: 100%;
  background-color: #666;
  cursor: pointer;
}

#image-container img.show  {
    animation: show .5s;
    animation-fill-mode: both;
}
@keyframes show {
    from {
        transform:scale(0.7);
        opacity:0
    }
    to {
        transform: scale(1);
        opacity:1
    }
}

#image-container img.hide  {
    animation: hide .5s;
    animation-fill-mode: both;
}
@keyframes hide {
    from {
        transform:scale(1);
        opacity:1
    }
    to {
        transform:scale(0.7);
        opacity:0
    }
}
<div id="image-container">
  <img src="https://civilian-interviewe.000webhostapp.com/img/mini_slider_1.png" />
  <ul id="carousel-index">
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

Upvotes: 1

sinisake
sinisake

Reputation: 11318

You can use CSS transition, and i guess that desired property is opacity.

var listItemContainer = document.getElementById('carousel-index');
var imageChanger = document.getElementById('image-container').getElementsByTagName('img');
var bulletNumber;
imageChanger[0].classList.add('fadeIn');
for (i = 0; i < listItemContainer.children.length; i++){
  (function(index){
     listItemContainer.children[i].onclick = function(){
     bulletNumber = index;
   imageChanger[0].classList.remove('fadeIn');
   
     setTimeout(function(){ 
   
     imageChanger[0].classList.add('fadeIn');
     } , 100);
     imageChanger[0].setAttribute('src', 'https://civilian-interviewe.000webhostapp.com/img/mini_slider_' + (bulletNumber+1) + '.png');   
      
 
    }
  })(i);
};
body{
 text-align:center;
}
#carousel-index{
  margin:0;
  padding:0;  
}
#carousel-index li {
  display: inline-block;
  width: 2em;
  height: 2em;
  border-radius: 100%;
  background-color: #666;
  cursor: pointer;
}
img {
  opacity:0;
}
img.fadeIn {
  opacity:1;
  transition:opacity 0.5s ease;
}
<div id="image-container">
  <img src="https://civilian-interviewe.000webhostapp.com/img/mini_slider_1.png"/>
    <ul id="carousel-index">
      <li></li>
      <li></li>
      <li></li>	
    </ul>
</div> 

Start image opacity should be 0, of course:

img {
  opacity:0;
}
img.fadeIn {
  opacity:1;
  transition:opacity 0.5s ease;
}

And then, on click (remove added class -> set opacity to 0 again), and add it again. You can play with values to get desired effect.

EDIT: fadeOut/fadeIn... it was little tricky, because of one container, and img src changing, but additional timeout solves it:

var listItemContainer = document.getElementById('carousel-index');
var imageChanger = document.getElementById('image-container').getElementsByTagName('img');
var bulletNumber;
imageChanger[0].classList.add('fadeIn');
for (i = 0; i < listItemContainer.children.length; i++){
  (function(index){
     listItemContainer.children[i].onclick = function(){
     bulletNumber = index;
   imageChanger[0].classList.remove('fadeIn');
   imageChanger[0].classList.add('fadeOut');
   
     setTimeout(function(){ 
   
     imageChanger[0].classList.add('fadeIn');
     imageChanger[0].classList.remove('fadeOut');
     } , 1000);
       setTimeout(function(){ 
     imageChanger[0].setAttribute('src', 'https://civilian-interviewe.000webhostapp.com/img/mini_slider_' + (bulletNumber+1) + '.png');   
      } , 1000);
 
    }
  })(i);
};
body{
 text-align:center;
}
#carousel-index{
  margin:0;
  padding:0;  
}
#carousel-index li {
  display: inline-block;
  width: 2em;
  height: 2em;
  border-radius: 100%;
  background-color: #666;
  cursor: pointer;
}
img {
  opacity:0;
}
img.fadeIn {
  opacity:1;
  transition:opacity 0.5s ease;
}
img.fadeOut {
  opacity:0;
  transition:opacity 0.5s ease;
}
<div id="image-container">
  <img src="https://civilian-interviewe.000webhostapp.com/img/mini_slider_1.png"/>
    <ul id="carousel-index">
      <li></li>
      <li></li>
      <li></li>	
    </ul>
</div> 

P.S. Images should be probably preloaded, in order to all work fine on first load.

Upvotes: 1

Yaje
Yaje

Reputation: 2821

CodePen sample

I've added some css transitions to the css

div#image-container {
opacity:1;
-webkit-transition: opacity 1s;
-moz-transition: opacity 1s;     
transition: opacity 1s; 

}

div#image-container.fade {
opacity:0;
}

and some function to handle the event:

var image = document.getElementById('image-container');
  if(image.className === 'fade'){
    image.className = '';
    setTimeout(function(){
      image.className = 'fade';
    },1000)
  }else{
    image.className = 'fade';
    setTimeout(function(){
      image.className = '';
    },1000)
  }
  setTimeout(function(){
    bulletNumber = index;
 imageChanger[0].setAttribute('src', 'https://civilian-interviewe.000webhostapp.com/img/mini_slider_' + (bulletNumber+1) + '.png');   
  },1000);

Upvotes: 2

Obsidian Age
Obsidian Age

Reputation: 42304

It's not a perfect solution, but here's one way of doing it without jQuery:

First create a new function:

function fadeChange(element) {
    var op = 0.1;
    var timer = setInterval(function () {
        if (op >= 1){
            clearInterval(timer);
        }
        element.style.opacity = op;
        element.style.filter = 'alpha(opacity=' + op * 100 + ")";
        op += op * 0.1;
    }, 10);
}

Then call that function when setting the new image:

fadeChange(imageChanger[0]);

This is demonstrated through the updated codepen here.

It's a bit clunky, but does fade the images. You may want to consider using a single image for the monitor, and then simply changing the contents of the monitor through this method.

Upvotes: 0

Related Questions