Javascript carousel css transition not working - javascript

hi im wondering why my css transition is not working. the carousel does the loop and and all, but my transition only works when i open dev tools and point at the element with my mouse.
heres the code : https://codepen.io/anon/pen/zXQpNo
thanks for your help
var slides = Array.from(document.querySelectorAll(".slide_element"));
var i = 0;
function test(){
if(i === slides.length - 1){
slides[slides.length - 1].classList.remove("displaying");
i = 0;
slides[i].classList.add("displaying");
}
else{
slides[i].classList.remove("displaying");
slides[i+1].classList.add("displaying");
i++;
}
}
setInterval(() => {
test();
}, 3000);

in "slide_element" remove display: none; and the transition add to it (all) so it will become like this transition: all .3s;
and set it to absolute positioning, so your css would look like this:
.slide_element{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
transition: all 0.3s;
transform: translateX(1000px);
}

Related

How to add CSS transitions to Automatic Slider?

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>
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>
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>
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.

Div flashing when removing class with visibility

I'm having an issue with a notification system I am building.
All works fine till the end where my javascript is triggered to remove the show class from the notification div. When the class is removed, there is a brief flash to the start position of the div.
Example here
JS to show notification:
function showNotification() {
notificationRef.current.classList.add("nShow");
setTimeout(() => {
notificationRef.current.classList.remove("nShow");
}, 4000);
}
Notification CSS has general positioning and styling with visibility: hidden and top: 85px set.
nShow (class to show notification):
.notification.nShow {
visibility: visible;
animation: fadeNotiIn 1s, fadeNotiOut 1s 3s;
}
#keyframes fadeNotiIn {
from {
top: 0;
opacity: 0;
}
to {
top: 85px;
opacity: 1;
}
}
#keyframes fadeNotiOut {
from {
top: 85px;
opacity: 1;
}
to {
top: 0;
opacity: 0;
}
}
It seems that visibility: hidden is being set after opacity: 1 so there is a flash when removing the show class.
Thanks
Here is a sample. I would not advise you to use animation here. Between the two animations you plan, your element goes back to its default state and that's making things ugly.
Instead, what I would do is use a short transition to smooth a bit the thing between the two states, and keep handling it through JS.
const notification = document.querySelector('.notification');
function startNotification() {
notification.classList.add("nShow");
setTimeout(() => {
notification.classList.remove("nShow");
}, 3000);
}
.notification {
opacity: 0;
position: absolute;
top: 0px;
transition: all 1s;
}
.notification.nShow {
top: 85px;
opacity: 1;
}
.root {
position: relative;
}
<button onclick="startNotification()">Start notification</button>
<div class="root">
<div class="notification">Hello</div>
</div>
As said in the first version, I don't think you should go for visibility and opacity at the same time, and since you are already using opacity, let's use it completely.

How do I get Javascript to run animation instead of CSS

I am doing a splash screen for my website. I have managed to get it working as JS wasn't working.
"use strict";
$(function(){
$('.fadein img:gt(0)').hide();
setInterval(function(){
$('.fadein :first-child').fadeOut()
.next('img').fadeIn()
.end().appendTo('.fadein');},
6000);
});
const splash = document.querySelector('.splash');
document.addEventListener('DOMContentLoaded', (e)=> {
setTimeout(function()=> {
splash.classList.add('display-none');
}, 10000);
})
The bottom code breaks the top code (which works and runs the slideshow).
.splash {
position: fixed;
top: 0;
left: 0;
width: auto;
height: auto;
z-index: 200;
}
.splash.display-none {
position: fixed;
opacity: 0;
top: 0;
left: 0;
width: 100%;
height: 100vh;
z-index: -10;
transition: all 6s;
}
#keyframes fadeIn {
to{
opacity: 0;
visibility: hidden;
}
}
#-webkit-keyframes fadeIn {
to{
opacity: 0;
visibility: hidden;
}
}
.splash {
opacity: 1;
animation: fadeIn 2s ease-in forwards;
-webkit-animation: fadeIn 2s ease-in forwards;
animation-delay: 0.75s;
}
.fade-in {
height: 100vh;
width: 100%;
}
This is my CSS, and the animation works. My only problem with it is that if I went back to homepage, the animation would happen again. This is why I want to use Javascript so it only happens on a new instance of loading the website.
Use localStorage to see if splash screen has been shown already. Set them to display:none immediately so they are completely hidden. I'm not sure what you actually want to happen with the splash, so I'm just hiding them completely. I think it would be more pleasant to just have a very short opacity transition instead.
You can use localStorage.removeItem to clear the splashed flag.
You may want to use a unique ID for the localStorage name for this specific splash, and not just "splashed".
document.addEventListener('DOMContentLoaded', (e)=> {
const splashed = localStorage.getItem('splashed')
const splash = document.querySelector('.splash');
const splasher = () => {
splash.classList.add('display-none');
localStorage.setItem('splashed',1)
};
splashed ? splash.forEach(x=>x.style.display='none') : setTimeout(splasher, 10000);
})

3D wheel spinning effect in css

I am trying to build a simple web element that resembles the wheel contestants spin on The Price is Right (sample video). My question is: is there a more efficient way to achieve this effect than what I've cobbled together below?
My first attempt at this functionality basically decrements the translateY property of an element that contains the elements to be spun [codepen]:
setInterval(shiftCards, 100)
var translateY = -60,
cardIdx = 0,
startCards = 60,
wrap = document.querySelector('.wrap');
for (var i=0; i<startCards; i++) {
addCard()
}
function addCard() {
var div = document.createElement('div');
div.className = 'card';
div.style.top = (cardIdx * 12) + 'px';
wrap.appendChild(div);
cardIdx++;
}
function shiftCards() {
wrap.style.transform = 'translateY(' + translateY + 'px)';
translateY -= 12;
var cards = wrap.querySelectorAll('.card');
if (cards.length >= startCards) {
cards[0].parentNode.removeChild(cards[0]);
addCard();
}
}
.cards {
width: 80px;
height: 200px;
overflow: hidden;
background: #aaa;
}
.wrap {
position: relative;
transition: transform .25s;
}
.card {
width: 100%;
height: 10px;
margin: 2px 0;
background: red;
position: absolute;
left: 0;
right: 0;
}
<div class='cards'>
<div class='wrap'>
</div>
</div>
Is there a more efficient way to achieve this functionality? Can I create an element with n children and actually just spin them in the Z-dimension, rather than create an artificial spin as I've done above? Any guidance others can offer on this question will be very appreciated!
You can use css-animations for this: (They are probably more efficient)
/* only alignment */
body, html {
height: 100%;
margin: 0;
padding: 0;
}
.wrapper {
display:flex;
justify-content:center;
align-items:center;
height: 100%;
}
/* actual spinning */
img {
animation: spin 5s infinite linear;
/*
spin: the keyframes (=animation) we want to have
5s: how long it should take for one iteration
infinite: how often should it repeat
linear: the easing between the different key frames You can also try 'ease'
*/
}
#keyframes spin {
0% {transform: translateY(-60px);} /* Starting point */
100% {transform: translateY(-360px);} /* end point */
}
#-webkit-keyframes spin {
0% {transform: translateY(-60px);}
100% {transform: translateY(-360px);}
}
<div class="wrapper">
<img src="https://www.placecage.com/300/100" class="spin">
</div>

Pre loader on window load

I have found this loader but not sure if its actually loading content or just running numbers. I am new to JavaScript, I want it to load the page but every time I run it counts all the way I don't see it slow down with heaver images so I am not sure if it is actually loading the page.
'use strict';
loader();
function loader(_success) {
var obj = document.querySelector('.preloader'),
inner = document.querySelector('.preloader-inner'),
page = document.querySelector('body');
obj.classList.add('show');
page.classList.remove('show');
var w = 0,
t = setInterval(function () {
w = w + 1;
inner.textContent = w + '';
if (w === 99) {
obj.classList.remove('show');
page.classList.add('show');
clearInterval(t);
w = 0;
if (_success) {
return _success();
}
}
}, 20);
}
.preloader {
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
visibility: hidden;
opacity: 0;
-webkit-transition: all 0.5s ease;
transition: all 0.5s ease;
z-index: 1000;
}
.preloader-inner {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
text-align: center;
}
.show {
visibility: visible !important;
opacity: 1 !important;
-webkit-transition: all 0.5s ease;
transition: all 0.5s ease;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="preloader">
<div class="preloader-inner"></div>
</div>
This is not really a question of a sort you need to ask. You need to understand the language bit more. My suggestion is if you are using a method which you didn't write find out what it does. e.g: setInterval()
The setInterval() method calls a function or evaluates an expression at specified intervals (in milliseconds).
Refer: https://www.w3schools.com/jsref/met_win_setinterval.asp
Your loader just increments numbers from 0 to 99 in a 20-millisecond interval. Just a loop.
There are enough libraries available to implement such functionality and with a lot of examples. Do your research.

Categories

Resources