I am trying to apply 'opacity / sliding to left' for my automatic slider but I couldn't make it. Please help me with this.
let images = ["images/a.jpg", "images/b.jpg", "images/c.jpg", "images/d.jpg", ];
let i = 0;
function changeImg() {
document.querySelector("#slider img").src = images[i];
if (i < images.length - 1) {
i ;
} else {
i = 0;
}
setTimeout("changeImg()", 1000);
}
onload(changeImg());
#slider img {
width: 100vw;
height: 60vh;
transition: opacity 2s ease-out;
}
<section id="slider">
<img name="slide" width="400" height="200" />
</section>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
The initial requirement is for the image to fade and another one be shown.
This can be achieved by placing the images one on top of the other (position absolute) and opacity 0 with a transition set on opacity. When it is a particular images turn to be shown the image before it is set to opacity 0 and the new image has its opacity set to 1.
let images = ["https://picsum.photos/id/1015/300/300", "https://picsum.photos/id/1016/200/300", "https://picsum.photos/id/1018/300/200.jpg", "https://picsum.photos/id/1022/400/300", ];
const slider = document.querySelector('#slider');
const imgEls = [];
images.forEach(image => {
let imgEl = document.createElement('img');
imgEl.src = image;
imgEls.push(imgEl);
slider.appendChild(imgEl);
});
let i = 0;
function changeImg() {
imgEls[i].style.opacity = 0;
if (i < images.length - 1) {
i ;
} else {
i = 0;
}
imgEls[i].style.opacity = 1;
setTimeout("changeImg()", 1000);
}
window.onload = changeImg;
#slider {
width: 100vw;
height: 60vh;
position: relative;
isplay: felx;
justify-content: center;
align-items: center;
}
#slider img {
display: inline-block;
width: 100vw;
height: 60vh;
object-fit: contain;
transition: opacity 2s ease-out;
opacity: 0;
position: absolute;
top: 0;
left: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section id="slider">
<https://stackoverflow.com/questions/69870264/how-to-add-css-transitions-to-automatic-slider#img name="slide" width="400" height="200" />
</section>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
While the action seems to correspond to what was discussed in the comments it doesn't make a real 'slider' and the question also talks of sliding to the left using CSS.
This snippet takes a slightly different approach to the question's code in that once the initial set up of the slides has been done using Javascript everything else is done via CSS. This has the advantage that it's possible the system can just hand the animation to the GPU without needing to interrupt back to the main program on a timeout.
Each image is located at left 100% (ie just off screen to the right) and it is given the same animation as the other - move to the center, wait and then move out to the left - opacity fading in and out respectively. The images however start animating at staggered times so the sliding looks continuous.
const slider = document.querySelector('#slider');
const images = ["https://picsum.photos/id/1015/300/300", "https://picsum.photos/id/1016/200/300", "https://picsum.photos/id/1018/300/200", "https://picsum.photos/id/1022/400/300"];
let div;
let count = 0;
images.forEach(image => {
div = document.createElement('div');
div.style.animationDelay = (count * 2) 's';
count ;
div.style.setProperty('--img', 'url(' image ')');
slider.appendChild(div);
});
slider.style.setProperty('--n', count);
#slider {
overflow: hidden;
width: 100vw;
height: 60vh;
position: relative;
}
#slider div {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
opacity: 0;
display: inline-block;
background-size: contain;
background-position: center center;
background-repeat: no-repeat;
background-image: var(--img);
animation-name: slide;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-duration: calc(var(--n) * 2s);
animation-fill-mode: forwards;
}
@keyframes slide {
0% {
opacity: 0;
transform: translateX(100vw);
}
12.5% {
opacity: 1;
transform: translateX(0);
}
25% {
opacity: 1;
transform: translateX(0);
}
37.5%,
100% {
opacity: 0;
transform: translateX(-100vw);
}
}
<div id="slider"></div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Note that the keyframes settings assume 4 images. The % values would have to be changed for more or fewer. Unfortunately CSS does not allow variables as % values in keyframes so the JS would ideally find the number of images and create the correct keyframes.