How to create a vertical carousel using simple JavaScript and CSS

I am trying to create a vertical carousel using vanilla JavaScript and CSS. I know jQuery has a carousel library, but I want it to be from scratch, without external libraries. I started by simply trying to move the top image, and then I decided to move on to the next image movement. I am stuck in the first image. Here I need your help, StackOverflowers.

My HTML:

<div class="slider vertical" > <img class="first opened" src="http://malsup.imtqy.com/images/beach1.jpg"> <img class="opened" src="http://malsup.imtqy.com/images/beach2.jpg"> <img src="http://malsup.imtqy.com/images/beach3.jpg"> <img src="http://malsup.imtqy.com/images/beach4.jpg"> <img src="http://malsup.imtqy.com/images/beach5.jpg"> <img src="http://malsup.imtqy.com/images/beach9.jpg"> </div> <div class="center"> <button id="prev">∧ Prev</button> <button id="next">∨ Next</button> </div> 

JavaScript:

 var next = document.getElementById('next'); var target = document.querySelector('.first'); next.addEventListener('click', nextImg, false); function nextImg(){ if (target.classList.contains('opened')) { target.classList.remove('opened'); target.classList.add('closed'); } else { target.classList.remove('closed'); target.classList.add('opened'); } } 

CSS

 div.vertical { width: 100px; } .slider { position: relative; overflow: hidden; height: 250px; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; -ms-box-sizing:border-box; box-sizing:border-box; -webkit-transition:-webkit-transform 1.3s ease; -moz-transition: -moz-transform 1.3s ease; -ms-transition: -ms-transform 1.3s ease; transition: transform 1.3s ease; } .slider img { width: 100px; height: auto; padding: 2px; } .first.closed{ /* partially offscreen */ -webkit-transform: translate(0, -80%); -moz-transform: translate(0, -80%); -ms-transform: translate(0, -80%); transform: translate(0, -80%); } .first.opened{ /* visible */ -webkit-transform: translate(0, 0%); -moz-transform: translate(0, 0%); -ms-transform: translate(0, 0%); transform: translate(0, 0%); } 

My way of thinking was:

  • use classes to move and display content
  • use javascript to add and remove classes

I think that I may have incorrectly violated the problem.

Here's how I would like to look: http://jsfiddle.net/natnaydenova/7uXPx/

And this is my terrible attempt: http://jsfiddle.net/6cb58pkr/

+7
javascript html css animation carousel
source share
1 answer

An alternative to using CSS transform properties is to provide absolute carousel positioning inside the div wrapper and control the top carousel property. Then you can use any weakening function that you like to animate the sliding movement. In the snippet below, I use cubic I / O relief .

The hard thing to keep an eye on is the order in which you rotate the images and perform the sliding animation. If you want to show the following image below, you should:

  • slide the carousel up one frame of the image.
  • rotate the first image to the end
  • reset vertical carousel offset to zero

To show the following image above:

  • rotate the last image to the beginning
  • instantly move the carousel up the height of one image frame
  • slide the carousel until its vertical offset reaches zero.

In the following snippet, you can set the carousel width by setting Carousel.width at the top of the script. (Although the height of the image should not be the same as the width of the image, I assume that all images are the same size.) You can also play with the parameters Carousel.numVisible and Carousel.duration .

 var Carousel = { width: 100, // Images are forced into a width of this many pixels. numVisible: 2, // The number of images visible at once. duration: 600, // Animation duration in milliseconds. padding: 2 // Vertical padding around each image, in pixels. }; function rotateForward() { var carousel = Carousel.carousel, children = carousel.children, firstChild = children[0], lastChild = children[children.length - 1]; carousel.insertBefore(lastChild, firstChild); } function rotateBackward() { var carousel = Carousel.carousel, children = carousel.children, firstChild = children[0], lastChild = children[children.length - 1]; carousel.insertBefore(firstChild, lastChild.nextSibling); } function animate(begin, end, finalTask) { var wrapper = Carousel.wrapper, carousel = Carousel.carousel, change = end - begin, duration = Carousel.duration, startTime = Date.now(); carousel.style.top = begin + 'px'; var animateInterval = window.setInterval(function () { var t = Date.now() - startTime; if (t >= duration) { window.clearInterval(animateInterval); finalTask(); return; } t /= (duration / 2); var top = begin + (t < 1 ? change / 2 * Math.pow(t, 3) : change / 2 * (Math.pow(t - 2, 3) + 2)); carousel.style.top = top + 'px'; }, 1000 / 60); } window.onload = function () { document.getElementById('spinner').style.display = 'none'; var carousel = Carousel.carousel = document.getElementById('carousel'), images = carousel.getElementsByTagName('img'), numImages = images.length, imageWidth = Carousel.width, aspectRatio = images[0].width / images[0].height, imageHeight = imageWidth / aspectRatio, padding = Carousel.padding, rowHeight = Carousel.rowHeight = imageHeight + 2 * padding; carousel.style.width = imageWidth + 'px'; for (var i = 0; i < numImages; ++i) { var image = images[i], frame = document.createElement('div'); frame.className = 'pictureFrame'; var aspectRatio = image.offsetWidth / image.offsetHeight; image.style.width = frame.style.width = imageWidth + 'px'; image.style.height = imageHeight + 'px'; image.style.paddingTop = padding + 'px'; image.style.paddingBottom = padding + 'px'; frame.style.height = rowHeight + 'px'; carousel.insertBefore(frame, image); frame.appendChild(image); } Carousel.rowHeight = carousel.getElementsByTagName('div')[0].offsetHeight; carousel.style.height = Carousel.numVisible * Carousel.rowHeight + 'px'; carousel.style.visibility = 'visible'; var wrapper = Carousel.wrapper = document.createElement('div'); wrapper.id = 'carouselWrapper'; wrapper.style.width = carousel.offsetWidth + 'px'; wrapper.style.height = carousel.offsetHeight + 'px'; carousel.parentNode.insertBefore(wrapper, carousel); wrapper.appendChild(carousel); var prevButton = document.getElementById('prev'), nextButton = document.getElementById('next'); prevButton.onclick = function () { prevButton.disabled = nextButton.disabled = true; rotateForward(); animate(-Carousel.rowHeight, 0, function () { carousel.style.top = '0'; prevButton.disabled = nextButton.disabled = false; }); }; nextButton.onclick = function () { prevButton.disabled = nextButton.disabled = true; animate(0, -Carousel.rowHeight, function () { rotateBackward(); carousel.style.top = '0'; prevButton.disabled = nextButton.disabled = false; }); }; }; 
 body { font-family: sans-serif; } .buttons { margin: 5px 0; } button { font-size: 14px; display: inline; padding: 3px 6px; border: 2px solid #ccc; background: #fff; border-radius: 5px; outline: none; } button:hover { border: 2px solid #888; background: #ffe; cursor: pointer; } #carouselWrapper { position: relative; overflow: hidden; } #carousel { position: absolute; visibility: hidden; } 
 <div id="spinner"> Loading... </div> <div id="carousel"> <img src="http://malsup.imtqy.com/images/beach1.jpg"> <img src="http://malsup.imtqy.com/images/beach2.jpg"> <img src="http://malsup.imtqy.com/images/beach3.jpg"> <img src="http://malsup.imtqy.com/images/beach4.jpg"> <img src="http://malsup.imtqy.com/images/beach5.jpg"> <img src="http://malsup.imtqy.com/images/beach9.jpg"> </div> <div class="buttons"> <button id="prev">&uarr; Prev</button> <button id="next">&darr; Next</button> </div> 
+7
source share

All Articles