I made little slider in html and js, the only thing I need to change is the transition between slides. Right now when moving from slide to slide the animation is fade (kind of flashbang) and new slide appears. I want this transition to be a smooth slide to left or right depending on which direction button was clicked. How can I make that smooth transition?
function showSlides(n) {
let i;
let slides = document.getElementsByClassName("SingleSlide");
let dots = document.getElementsByClassName("dot");
if (n > slides.length) { slideIndex = 1 }
if (n < 1) { slideIndex = slides.length }
for (i = 0; i < slides.length; i ) {
slides[i].style.display = "none";
}
for (i = 0; i < dots.length; i ) {
dots[i].className = dots[i].className.replace(" active", "");
}
slides[slideIndex - 1].style.display = "block";
dots[slideIndex - 1].className = " active";
}
let slideIndex = 1;
showSlides(slideIndex);
function plusSlides(n) {
showSlides(slideIndex = n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
* {
box-sizing: border-box
}
.header{
text-align: center;
margin-top: 20px;
margin-bottom: 40px;
color: rgb(192, 0, 144);
font-size: 50px;
}
body {
font-family: Verdana, sans-serif;
}
.SingleSlide {
height: 650px;
background-color: lightgrey;
padding: 90px;
border-radius: 40px;
}
h2{
color: rgb(192, 0, 144);
}
h3{
color: rgb(80, 80, 80);
}
.info {
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
img {
height: 200px;
width: 280px;
border-radius: 40px;
margin-left: auto;
margin-right: auto;
display: block;
-webkit-box-shadow: 0px 0px 24px 0px rgba(66, 68, 90, 1);
-moz-box-shadow: 0px 0px 24px 0px rgba(66, 68, 90, 1);
box-shadow: 0px 0px 24px 0px rgba(66, 68, 90, 1);
}
.Slides {
max-width: 1000px;
position: relative;
margin: auto;
-webkit-box-shadow: 0px 0px 24px 0px rgba(66, 68, 90, 1);
-moz-box-shadow: 0px 0px 24px 0px rgba(66, 68, 90, 1);
box-shadow: 0px 0px 24px 0px rgba(66, 68, 90, 1);
border-radius: 40px;
}
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
color: rgb(192, 0, 144);
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
font-size: 50px;
}
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
.prev:hover,
.next:hover {
background-color: gray;
}
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active,
.dot:hover {
background-color: rgb(192, 0, 144);
}
.fade {
animation-name: fade;
animation-duration: 1.5s;
}
@keyframes fade {
from {
opacity: .4
}
to {
opacity: 1
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<div > Our Employees</div>
<div >
<div >
<div >
<img src="data/emp1.jpg">
<div >
<h2> Anna Wesołowska</h2>
<h3> Product Manager</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse eget vestibulum nibh. Nulla volutpat faucibus pulvinar. Praesent sodales maximus ante, a mattis mi dictum rhoncus. Vivamus magna leo, rutrum sit amet facilisis at, suscipit a urna. Nulla aliquet at nibh ac fermentum. Phasellus placerat leo a est faucibus, at venenatis.</p>
</div>
</div>
</div>
<div >
<div profile>
<img src="data/emp2.jpg">
<div >
<h2> Maria Ryś </h2>
<h3> Accountant </h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras maximus massa rhoncus metus convallis, sed dapibus augue scelerisque. Nunc aliquet varius aliquet. Etiam consequat congue feugiat. Aliquam erat volutpat. Vivamus ultricies diam vitae lacus efficitur vehicula vitae in arcu. Nunc dui elit, aliquet vitae tristique nec, volutpat quis nulla. Cras.</p>
</div>
</div>
</div>
<div >
<div profile>
<img src="data/emp3.jpg">
<div >
<h2> Zbigniew Żaba </h2>
<h3> Intern </h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas accumsan quis sem et volutpat. Pellentesque ultrices tempus feugiat. Duis facilisis vel risus in consequat. Nam rutrum odio libero, a elementum augue porta in. Maecenas posuere porta leo, eget volutpat sapien sodales ut. Integer sodales lacus sed nulla cursus congue. Pellentesque.</p>
</div>
</div>
</div>
<div >
<div profile>
<img src="data/emp4.jpg">
<div >
<h2> Jolanta Konieczna </h2>
<h3> Receptionist </h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec nec arcu nec nisi hendrerit ultricies. In metus sem, accumsan vel nisl at, pharetra volutpat massa. Morbi quis nunc non tellus pulvinar varius. Nunc consequat in erat non maximus. Nullam et porta erat. Integer non elit vitae tortor maximus ullamcorper sit.</p>
</div>
</div>
</div>
<div >
<div profile>
<img src="data/emp5.jpg">
<div >
<h2> Amelia Cron </h2>
<h3> Data Analyst </h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer varius sodales augue, vel convallis elit elementum eget. Nunc lacus erat, vehicula sit amet luctus id, rutrum id libero. Fusce leo odio, bibendum ac vestibulum ac, porttitor eget orci. Praesent ac urna in tellus egestas lobortis ut vel eros. Ut fermentum.</p>
</div>
</div>
</div>
<a onclick="plusSlides(-1)">❮</a>
<a onclick="plusSlides(1)">❯</a>
</div>
<br>
<div style="text-align:center">
<span onclick="currentSlide(1)"></span>
<span onclick="currentSlide(2)"></span>
<span onclick="currentSlide(3)"></span>
<span onclick="currentSlide(4)"></span>
<span onclick="currentSlide(5)"></span>
</div>
<script src="script.js"></script>
</body>
</html>
CodePudding user response:
I prefer @Rocky Sims's solution with Bootstrap. It will save you time.
You can also use the following solution. (I'd suggest taking some tests if I've made an error):
function setValidSlideIndex(slide, slides_count) {
// parameter 'slide' accepts numbers,
// and following strings: "prev" & "next".
if (isNaN(slide))
{
if (slide == 'prev') {
// Decrement slideIndex.
--slideIndex;
}
else if (slide == 'next') {
// Increment slideIndex.
slideIndex;
}
else {
// Throw error.
console.error(`Invalid parameter slide: "${slide}".`);
return false;
}
}
else {
slideIndex = slide;
}
// If slideIndex is higher than available slides, set slide to 1.
if (slideIndex > slides_count) slideIndex = 1;
// If slideIndex is lower than available slides, set slide to last.
else if (slideIndex < 1) slideIndex = slides_count;
return true;
}
function showSlide(slide, ...direction) {
/* parameter 'slide' accepts numbers,
and following strings: "prev" & "next".
parameter 'direction' is optional,
it accepts following strings: "left" and "right".
It's purpose is to initialize .SingleSlide's slide-in/out animation
*/
if (isOnSlideAnimation) return false;
let slides = document.getElementsByClassName("SingleSlide");
let dots = document.getElementsByClassName("dot");
let prev_slide = (slides[slideIndex - 1])
? slides[slideIndex - 1]
: slides.length;
setValidSlideIndex(slide, slides.length);
let next_slide = slides[slideIndex - 1];
// Hide slides and remove slide classes.
Array.from(slides).map(slide => {
slide.classList.remove('slide-rtc');
slide.classList.remove('slide-ltc');
slide.classList.remove('slide-ctr');
slide.classList.remove('slide-ctl');
slide.style.display = 'none';
});
// Animate previous and next slide.
// (Validate direction: If value = 'right' or 'left', using RegExp)
if (/^(right|left)/gi.test(direction))
{
if (direction == 'right') {
next_slide.classList.add('slide-rtc');
prev_slide.classList.add('slide-ctl');
}
else {
next_slide.classList.add('slide-ltc');
prev_slide.classList.add('slide-ctr');
}
// Pause showSlides() until slide animation ends.
isOnSlideAnimation = true;
next_slide.addEventListener('animationend', () => {
isOnSlideAnimation = false
}, { once: true });
// Show previous slide.
prev_slide.style.display = 'block';
}
// Show next slide.
next_slide.style.display = 'block';
// Activate current dot.
Array.from(dots).map(dot => dot.classList.remove('active'));
dots[slideIndex - 1].classList.add('active');
}
let slideIndex = 1;
let isOnSlideAnimation = false;
showSlide(slideIndex);
* {
box-sizing: border-box
}
.header{
text-align: center;
margin-top: 20px;
margin-bottom: 40px;
color: rgb(192, 0, 144);
font-size: 50px;
}
body {
font-family: Verdana, sans-serif;
}
.SingleSlide {
position: absolute; /* Added */
height: 100%; /* Added */
padding: 90px;
/* border-radius: 40px; Removed */
/* background-color: lightgrey; Moved to .Slides */
}
h2{
color: rgb(192, 0, 144);
}
h3{
color: rgb(80, 80, 80);
}
.info {
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
img {
height: 200px;
width: 280px;
border-radius: 40px;
margin-left: auto;
margin-right: auto;
display: block;
-webkit-box-shadow: 0px 0px 24px 0px rgba(66, 68, 90, 1);
-moz-box-shadow: 0px 0px 24px 0px rgba(66, 68, 90, 1);
box-shadow: 0px 0px 24px 0px rgba(66, 68, 90, 1);
}
.Slides {
height: 650px; /* Changed */
overflow: hidden; /* Added */
max-width: 1000px;
position: relative;
margin: auto;
-webkit-box-shadow: 0px 0px 24px 0px rgba(66, 68, 90, 1);
-moz-box-shadow: 0px 0px 24px 0px rgba(66, 68, 90, 1);
box-shadow: 0px 0px 24px 0px rgba(66, 68, 90, 1);
border-radius: 40px;
background-color: lightgrey; /* Moved from .SingleSlide */
}
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
color: rgb(192, 0, 144);
font-weight: bold;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
font-size: 50px;
}
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
.prev:hover,
.next:hover {
background-color: gray;
}
.text {
color: #f2f2f2;
font-size: 15px;
padding: 8px 12px;
position: absolute;
bottom: 8px;
width: 100%;
text-align: center;
}
.numbertext {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
top: 0;
}
.dot {
cursor: pointer;
height: 15px;
width: 15px;
margin: 0 2px;
background-color: #bbb;
border-radius: 50%;
display: inline-block;
transition: background-color 0.6s ease;
}
.active,
.dot:hover {
background-color: rgb(192, 0, 144);
}
.fade {
animation-name: fade;
animation-duration: 1.5s;
}
@keyframes fade {
from {
opacity: .4
}
to {
opacity: 1
}
}
/* Added all below */
:root {
--slide-animation-delay: 1s;
}
@keyframes slideLeftToCenter {
from { transform: translateX(-100%) }
to { transform: translateX(0) }
}
@keyframes slideCenterToLeft {
from { transform: translateX(0) }
to { transform: translateX(-100%) }
}
@keyframes slideRightToCenter {
from { transform: translateX(100%) }
to { transform: translateX(0) }
}
@keyframes slideCenterToRight {
from { transform: translateX(0) }
to { transform: translateX(100%) }
}
.slide-ltc {
animation: slideLeftToCenter var(--slide-animation-delay) forwards;
}
.slide-ctl {
animation: slideCenterToLeft var(--slide-animation-delay) forwards;
}
.slide-rtc {
animation: slideRightToCenter var(--slide-animation-delay) forwards;
}
.slide-ctr {
animation: slideCenterToRight var(--slide-animation-delay) forwards;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<div > Our Employees</div>
<div >
<div >
<div >
<img src="data/emp1.jpg">
<div >
<h2> Anna Wesołowska</h2>
<h3> Product Manager</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse eget vestibulum nibh. Nulla volutpat faucibus pulvinar. Praesent sodales maximus ante, a mattis mi dictum rhoncus. Vivamus magna leo, rutrum sit amet facilisis at, suscipit a urna. Nulla aliquet at nibh ac fermentum. Phasellus placerat leo a est faucibus, at venenatis.</p>
</div>
</div>
</div>
<div >
<div profile>
<img src="data/emp2.jpg">
<div >
<h2> Maria Ryś </h2>
<h3> Accountant </h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras maximus massa rhoncus metus convallis, sed dapibus augue scelerisque. Nunc aliquet varius aliquet. Etiam consequat congue feugiat. Aliquam erat volutpat. Vivamus ultricies diam vitae lacus efficitur vehicula vitae in arcu. Nunc dui elit, aliquet vitae tristique nec, volutpat quis nulla. Cras.</p>
</div>
</div>
</div>
<div >
<div profile>
<img src="data/emp3.jpg">
<div >
<h2> Zbigniew Żaba </h2>
<h3> Intern </h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas accumsan quis sem et volutpat. Pellentesque ultrices tempus feugiat. Duis facilisis vel risus in consequat. Nam rutrum odio libero, a elementum augue porta in. Maecenas posuere porta leo, eget volutpat sapien sodales ut. Integer sodales lacus sed nulla cursus congue. Pellentesque.</p>
</div>
</div>
</div>
<div >
<div profile>
<img src="data/emp4.jpg">
<div >
<h2> Jolanta Konieczna </h2>
<h3> Receptionist </h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec nec arcu nec nisi hendrerit ultricies. In metus sem, accumsan vel nisl at, pharetra volutpat massa. Morbi quis nunc non tellus pulvinar varius. Nunc consequat in erat non maximus. Nullam et porta erat. Integer non elit vitae tortor maximus ullamcorper sit.</p>
</div>
</div>
</div>
<div >
<div profile>
<img src="data/emp5.jpg">
<div >
<h2> Amelia Cron </h2>
<h3> Data Analyst </h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer varius sodales augue, vel convallis elit elementum eget. Nunc lacus erat, vehicula sit amet luctus id, rutrum id libero. Fusce leo odio, bibendum ac vestibulum ac, porttitor eget orci. Praesent ac urna in tellus egestas lobortis ut vel eros. Ut fermentum.</p>
</div>
</div>
</div>
<a onclick="showSlide('prev', 'left')">❮</a>
<a onclick="showSlide('next', 'right')">❯</a>
</div>
<br>
<div style="text-align:center">
<span onclick="showSlide(1)"></span>
<span onclick="showSlide(2)"></span>
<span onclick="showSlide(3)"></span>
<span onclick="showSlide(4)"></span>
<span onclick="showSlide(5)"></span>
</div>
<script src="script.js"></script>
</body>
</html>