How animate a slide off the screen when pressing next slide button? - javascript

I have a video slider on a page I am working on, but I would like a nice animation to occur when changing slides rather than just changing to the next slide. For example, animate the slide off the side of the screen and the next slide in from the other side.
var slideIndex = 1;
showDivs(slideIndex);
function plusDivs(n) {
showDivs(slideIndex += n);
}
function showDivs(n) {
var i;
var x = document.getElementsByClassName("mySlides");
if (n > x.length) {slideIndex = 1}
if (n < 1) {slideIndex = x.length}
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
x[slideIndex-1].style.display = "block";
}
<div class="video__container" style="display: flex; display: -webkit-flex; flex-direction: row; -webkit-flex-direction: row;">
<div class="arrow__container">
<div class="video__container--arrow arrow__back" onclick="plusDivs(-1)">
<img class="img__full" src="css/images/template_arrow.svg">
</div>
</div>
<div class="video__container--item">
<!-- Must include data-id, data-bg and optional video name -->
<div class="video__slide mySlides">
<div class="youtube-container template-youtube-container">
<div class="youtube-player" data-id="bqlzoxTvOkE" data-bg="css/images/pb/video1.jpg"><span class="video-name">Branding</span></div>
</div>
</div>
<div class="video__slide mySlides">
<div class="youtube-container template-youtube-container">
<div class="youtube-player" data-id="S-sJp1FfG7Q" data-bg="css/images/pb/video2.jpg"><span class="video-name">UX Design</span></div>
</div>
</div>
<div class="video__slide mySlides">
<div class="youtube-container template-youtube-container">
<div class="youtube-player" data-id="zVntJ21thpQ" data-bg="css/images/pb/video3.jpg"><span class="video-name">UI Design</span></div>
</div>
</div>
</div>
<div class="arrow__container">
<div class="video__container--arrow arrow__next" onclick="plusDivs(1)">
<img class="img__full" src="css/images/template_arrow.svg">
</div>
</div>
</div>

Ok, yeah, it's a lot, but what we are doing here is avoiding JavaScript easing animations. If you do want to use easing use the following link, because I can't explain it as well as this does.
https://www.kirupa.com/html5/introduction_to_easing_in_javascript.htm
If you still want to skip the whole learning process of easing (like me) there is a way around it.
I'll give you the short version, and if you're still confused I have a nice, long example. First, you have to make a div container to hold your slides. Basically, you are going to use JavaScript function to assign a class to that container. You'll make two for every slide except for the first and last (one to go forward, one to go back). When you're doing this, make sure to reset the animation by assigning another class to act as a null, or else... Those classes you just made will hold the animations, except in the null class. Add your animations, some styling, and html, making sure to include a button with the function from earlier. Mine is really basic, but you can really decorate it however you want.
/*This is the Javascript. What we are doing here is bypassing the complexity of
Javascript animations and instead changing the class of what we want to move.
This allows us to still use the onclick function in our html, while at
the same time using css3 animations*/
function magicbtnf() {
document.getElementById('container').className = "magicslide";
}
function magicbtnb() {
document.getElementById('container').className = "magicslide2";
}
/*This is css. Most of it is styling, but I will point out importants in
comments.*/
body,
html {
width: 100%;
margin: 0;
border: 0;
font-family: "century gothic", "Arial";
font-size: 18px;
}
#container {
/*This is the container, make it 100% x the number of slides you have.
This will allow each slide to fill 100% of the screen*/
width: 200%;
overflow: hidden;
position: fixed;
display: flex;
}
#container>div {
display: inline-block;
text-align: center;
vertical-align: top;
}
#slide1 {
/* You can insert your first slide CSS in here , just make sure the width
is 1/the amount of slides you have. % is recommended, but I'm sure there
is a way to use vw.*/
height: 400px;
width: 50%;
background-color: red;
float: right;
position: relative;
}
.magicslide {
/*This is one of two classes for the animation. We will use javascript to
set and unset the classes to the slides*/
-webkit-animation: switch 4s 1;
-o-animation: switch 4s 1;
-moz-animation: switch 4s 1;
animation: switch 4s 1;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
-o-animation-fill-mode: forwards;
}
#-moz-keyframes switch {
0% {
margin-left: 0px;
}
25% {
margin-left: 0px;
}
50% {
margin-left: -60%;
}
100% {
margin-left: -100%;
}
}
#-o-keyframes switch {
0% {
margin-left: 0px;
}
25% {
margin-left: 0px;
}
50% {
margin-left: -60%;
}
100% {
margin-left: -100%;
}
}
#-webkit-keyframes switch {
0% {
margin-left: 0px;
}
25% {
margin-left: 0px
}
50% {
margin-left: -60%;
}
100% {
margin-left: -100%;
}
}
#keyframes switch {
0% {
margin-left: 0px;
}
25% {
margin-left: 0px
}
50% {
margin-left: -60%;
}
100% {
margin-left: -100%;
}
}
.notsomagic {
/*This is basically a void element. This resets the animation so when
you go back a slide, you can continue again.*/
height: 400px;
width: 100%;
}
#slide2 {
/*Same thing here as the earlier slide!*/
height: 400px;
width: 50%;
background-color: lightblue;
float: left;
position: relative;
}
.magicslide2 {
/*This is the same animation sequence as before, but backwards*/
-webkit-animation: switchb 4s 1;
-o-animation: switchb 4s 1;
-moz-animation: switchb 4s 1;
animation: switchb 4s 1;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
-o-animation-fill-mode: forwards;
}
#keyframes switchb {
0% {
margin-left: -100%;
}
25% {
margin-left: -100%;
}
50% {
margin-left: -40%
}
100% {
margin-left: 0%;
}
}
#-moz-keyframes switchb {
0% {
margin-left: -100%;
}
25% {
margin-left: -100%;
}
50% {
margin-left: -40%
}
100% {
margin-left: 0%;
}
}
#-o-keyframes switchb {
0% {
margin-left: -100%;
}
25% {
margin-left: -100%;
}
50% {
margin-left: -40%
}
100% {
margin-left: 0%;
}
}
#-webkit-keyframes switchb {
0% {
margin-left: -100%;
}
25% {
margin-left: -100%;
}
50% {
margin-left: -40%
}
100% {
margin-left: 0%;
}
}
<!--This is just some boring old html. It's esentially placing everything where it needs to go. The most noticable part is the input, which states our function from the javascript onclick -->
<!DOCTYPE html>
<html>
<head>
<title>Slide</title>
<link rel="stylesheet" type="text/css" href="change_slides.css">
<script type="text/javascript" src="change_slides.js"></script>
</head>
<body>
<div id="container">
<div id="slide1">
Hello! This is my slideshow!
<br>
<input type="button" id="change" value="Click Me!" onclick="magicbtnf()">
</div>
<div id="slide2">
This is slide #2!
<br>
<input type="button" id="change2" value="Click Me Too!" onclick="magicbtnb()">
</div>
</div>
</body>
</html>
If you don't feel like making your own animations, there are free downloads. I recommend Animate.css. It come chalked full of really smooth animations, and with a couple quick edits, you can make them work really well with your slideshow. The link is: https://daneden.github.io/animate.css/
I hope this helps! :D

Related

How to stop a text animation from moving the logo when the text appears

I am making a mental health website. on the homepage of the website I have chosen to make a text that is animated as opposed to being static, just to make the website more lively and appealing.
this is what it looks like when the text appears.
The horizontal overflow is hidden, so the logo on the side is out of the page because the text has stretched.
How can I fix this?
// sets the interval for which the function will run, in this case 8 seconds, (8000)
setInterval(function() {
// grab all elements with class 'sub-head' and stores it in the elems const.
const elems = document.querySelectorAll('.sub-head')
// loop through the found elements
elems.forEach(e => {
// check if the element has a class 'inactive', if there is one, remove it
if (e.classList.contains('inactive')) e.classList.remove('inactive')
// if not, add it. This is how it creates a loop.
else e.classList.add('inactive');
});
}, 8000)
/* The animation text*/
.intro {
display: inline-flex;
overflow: hidden;
white-space: nowrap;
}
.intro1 {
animation: showup 7s;
font-family: Arial, Helvetica, sans-serif;
font-size: 40px;
color: purple;
}
.intro2 {
width: 0px;
animation: reveal 7s infinite;
}
.inactive {
display: none;
}
.sub-head {
margin-left: -355px;
animation: slidein 7s infinite;
font-size: 30px;
font-family: Arial, Helvetica, sans-serif;
}
#keyframes showup {
0% {
opacity: 0;
}
20% {
opacity: .4;
}
80% {
opacity: .8;
}
100% {
opacity: 1;
}
}
#keyframes slidein {
0% {
margin-left: -800px;
}
20% {
margin-left: -800px;
}
35% {
margin-left: 0px;
}
100% {
margin-left: 0px;
}
}
#keyframes reveal {
0% {
opacity: 0;
width: 0px;
}
20% {
opacity: 1;
width: 0px;
}
30% {
width: 800px;
}
80% {
opacity: 1;
}
100% {
opacity: 0;
width: 800px;
}
}
<div class="first-box">
<div class="intro intro1">Welcome!</div>
<div class="intro intro2">
<span class="sub-head "> We care about you</span>
<span class="sub-head inactive">becuase you matter</span>
<!-- lol dramatic effect-->
</div>
</div>
I think the problem was you're setting so much width that the image/logo will also be affected by the width that you have set.
SOLUTION:
Set a static width on your .intro2 class for example 300px or reasonable width that will only fit your static content.
.intro2 {
width: 300px;
animation: reveal 7s infinite;
}
You can check on this pen https://codepen.io/Preygremmer15/pen/MWoJBzv

HTML - Second IMG hover issue

I have 2 semicircles stuck next to each other forming a circle. When I hover on the left semicircle, the right one lowers it's opacity (which is what is supposed to do) but when I hover on the right one, the opacity doesn't change at all.
HTML:
<div id="animation-components">
<img src="leftball.svg" alt="" class="animation-item-01">
<img src="rightball.svg" alt="" class="animation-item-02">
</div>
CSS:
#animation-components {}
.animation-item-01 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(631px,80px);
height: 320px;
transition: opacity ease 0.5s;
}
.animation-item-02 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(627px,80px);
height: 320px;
transition: opacity ease 0.5s;
}
.animation-item-01:hover + .animation-item-02{
opacity: 50%;
}
.animation-item-02:hover + .animation-item-01{
opacity: 50%;
}
What can I alter to make this work?
The issue is that you can only select the next sibling with the adjacent sibling selector.
.element-1 + .element-2 /* good */
.element-2 + .element-1 /* not so good */
Since .animation-item-02 comes after .animation-item-01, there is no way to select the previous .animation-item-01 from .animation-item-02
Doing the following will fix the issue:
#animation-components:hover > div {
opacity: 50%;
}
#animation-components > div:hover {
opacity: 100%;
}
CSS Combinators can't be used to apply styles to elements before target element.
The adjacent sibling selector (+) will aply to all adjacent elements, not to it's opposite elements.
CSS It's in the name: Cascading Style Sheets only supports styling in cascading direction, not up.
To achieve the desired, you can do the folowwing:
#animation-components:hover img {
opacity: .5;
}
#animation-components img:hover{
opacity: 1;
}
<div id="animation-components">
<img src="https://via.placeholder.com/150.png/ff0000" alt="" class="animation-item-01">
<img src="https://via.placeholder.com/150.png/ff0000" alt="" class="animation-item-02">
</div>
It might just be me but I find it heaps easier to throw in just a little bit of javascript and avoid messy css combinators. Heres my fix, script goes anywhere in your html file, I put it after the closing body tag.
<script>
function fadeOut(obj) {
document.getElementById(obj).style.animationName = "fadeOut";
}
function fadeIn(obj) {
document.getElementById(obj).style.animationName = "fadeIn";
}
</script>
#item1 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(631px,80px);
height: 320px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
#item2 {
display: inline;
position: relative;
margin-bottom: 240px;
margin-top: 100px;
transform: translate(627px,80px);
height: 320px;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
#keyframes fadeOut {
0%{opacity: 1;}
100%{opacity: 0.5;}
}
#keyframes fadeIn {
0%{opacity: 0.5;}
100%{opacity: 1;}
}
<div id="animation-components">
<img src="leftball.svg" alt="" id="item1" onmouseover="fadeOut('item1')" onmouseout="fadeIn('item1')">
<img src="rightball.svg" alt="" id="item2" onmouseover="fadeOut('item2')" onmouseout="fadeIn('item2')">
</div>
Also its just a me thing, but you have class attributes where id attributes should be. If your applying seperate styles to two completely seperate elements its a good idea to use id, but if your applying same style to two elements

CSS transition fade in only the background not the child divs

I have this situation:
setTimeout(function() {
// Set BG image
var bg_content = document.querySelector('.content_top');
bg_content.style.background = "linear-gradient(0deg,#000 0,rgba(0,0,0,.7) 35%,rgba(0,0,0,.4) 50%,rgba(0,0,0,0) 100%),url(https://upload.wikimedia.org/wikipedia/commons/8/8f/Example_image.svg) no-repeat";
bg_content.style.backgroundSize = "cover";
bg_content.style.backgroundPosition = "center";
bg_content.classList.add("fade-in");
}, 1500);
.fade-in {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.5s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.main_header {
color: blue;
text-align: center;
font-size: 30px;
}
.content_top {
height: 300px;
}
<div class="content_top">
<div class="main_header"><span class="vertical_line"></span>
<p data-transkey="main_header_notrans"><span class="tino">Some header</span> <br> some text</p>
</div>
</div>
.content_top has a background-image, which I want to fade in when the page loads, but I do not want the .main_header to be affected aswell. Currently this leads to a flicker effect of the text in .main_header and looks bad.
Here is a working example: JsFiddle
Move the background to a new div inside of the .content_top element. This will create a new layer which we can animate without affecting the content.
Give .content_top and .main_header a position: relative value. This will make the .content_top a relative container, and give .main_header the possibility to use the z-index.
In the snippet below I've added a new element: .main_bg. This element will get the background image and the animation.
Give the .main_bg element a position: absolute;. This will allow you to overlay elements on top of each other, in this case .main_bg and .main_header.
setTimeout(function() {
// Set BG image
var bg_content = document.querySelector('.main_bg');
bg_content.style.background = "linear-gradient(0deg,#000 0,rgba(0,0,0,.7) 35%,rgba(0,0,0,.4) 50%,rgba(0,0,0,0) 100%),url(https://upload.wikimedia.org/wikipedia/commons/8/8f/Example_image.svg) no-repeat";
bg_content.style.backgroundSize = "cover";
bg_content.style.backgroundPosition = "center";
bg_content.classList.add("fade-in");
}, 1500);
.fade-in {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.5s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.main_bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.main_header {
position: relative;
color: blue;
text-align: center;
font-size: 30px;
z-index: 1;
}
.content_top {
height: 300px;
position: relative;
}
<div class="content_top">
<div class="main_bg"></div>
<div class="main_header"><span class="vertical_line"></span>
<p data-transkey="main_header_notrans"><span class="tino">Some header</span> <br> some text</p>
</div>
</div>

automatic cookie bar pure css works fine but need delay

I added this pure css cookie bar to my website and all works fine, the only problem is that when you enter in the site, you can see FIRST the cookie bar, AND the cookie bar go up and go down at the end.
How can see my cookie bar only go down when i enter in my site, i thought to change de thenimation delay, add set time out .... but nothing change !!
here is the original codepen and you can see what i want to change in it
www.codepen.io/natewiley/pen/uGtcD
HERE IS MY CODE
<input class="checkbox-cb" id="checkbox-cb" type="checkbox" />
<div class="cookie-bar">
<div class="message">
This website uses cookies to give you an incredible experience. By using
this website you agree to the
<div class="buttoncookies-container">
<a style="letter-spacing: 1px;" class="buttoncookies" id="modalcookieslinken" onclick="toggleOverlay()">terms</a>
</div>
</div>
<div class="mobile">
This website uses cookies,
<div class="buttoncookies-container">
<a style="letter-spacing: 1px;" class="buttoncookies" id="modalcookiesshortlink" onclick="toggleOverlay()">
learn more
</a>
</div>
</div>
<label for="checkbox-cb" class="close-cb">X</label>
</div>
</div>
HERE IS MY CSS
.cookie-bar { z-index:9996; position: fixed; width: 100%; top: 0; right: 0; left: 0; height: auto; padding: 20px; line-height:20px; text-align: center; background: #d2c6af; transition: .8s; animation: slideIn .8s; animation-delay: .8s; display: inline-block; }
.mobile { display: none; }
#keyframes slideIn { 0% { transform: translateY(-1000px); } 100% { transform: translateY(0); } }
.close-cb { border: none; background: none; position: absolute; display: inline-block; right: 20px; top: 10px; cursor: pointer; }
.close-cb:hover { color:#fff;; }
.checkbox-cb { display: none;}
#checkbox-cb:checked + .cookie-bar { transform: translateY(-1000px); }
Removing the line in css
animation-delay: .8s;
will give you the result
Make the animation last longer.
animation: slideIn 4s;
Plus add some trick to animation flow:
0% {
transform: translateY(-50px);
}
50% {
transform: translateY(-50px);
}
100% {
transform: translateY(0);
}

Smoothly sliding HTML divs up to replace each other

I'll try to explain what I'm trying to do but I think checking out the jsfiddle link would make the point more clearly.
It's a number of phrases (HTML divs) stacked vertically on each other. When the button is clicked, the top phrase disappears while the lower phrases appear to slide up to take the place of the phrase previously above themselves.
Is there a better way to do this? It looks really ugly as it is.
EDIT: also note that the code only works once, then you have to hit 'run' again since the list of phrases is not infinite like in my actual application
https://jsfiddle.net/deddnbrh/1/
HTML:
<br>
<br>
<br>
<div id="phrase1" style="font-size:50px;color:black">Phrase 1</div>
<div id="phrase2" style="font-size:25px;color:gray">Phrase 2</div>
<div id="phrase3" style="font-size:25px;color:gray">Phrase 3</div>
<div id="phrase4" style="font-size:25px;color:gray;opacity:0">Phrase 4</div>
<br>
<br>
<br>
<button id="button" onclick="myFunc2()" onmousedown="myFunc()">CLICK ME</button>
javascript:
document.getElementById('phrase2').addEventListener("webkitAnimationEnd", switchPhraseText);
function switchPhraseText() {
document.getElementById('phrase1').innerHTML = "Phrase 2";
document.getElementById('phrase2').innerHTML = "Phrase 3";
document.getElementById('phrase3').innerHTML = "Phrase 4";
document.getElementById('phrase4').innerHTML = "Phrase 5";
}
function myFunc2() {
document.getElementById('phrase1').style.webkitAnimationName = 'phrase1Anim';
document.getElementById('phrase2').style.webkitAnimationName = 'phrase2Anim';
document.getElementById('phrase3').style.webkitAnimationName = 'phrase3Anim';
document.getElementById('phrase4').style.webkitAnimationName = 'phrase4Anim';
}
function myFunc() {
document.getElementById('phrase1').style.webkitAnimationName = "";
document.getElementById('phrase2').style.webkitAnimationName = "";
document.getElementById('phrase3').style.webkitAnimationName = "";
document.getElementById('phrase4').style.webkitAnimationName = "";
}
css:
#phrase1 {
position: relative;
-webkit-animation-duration: .8s;
}
#phrase2 {
position: relative;
-webkit-animation-duration: 1s;
}
#phrase3 {
position: relative;
-webkit-animation-duration: 1s;
}
#phrase4 {
position: relative;
-webkit-animation-duration: 1s;
}
#-webkit-keyframes phrase1Anim {
0% {left:0px;}
100% {left:250px; opacity:0}
}
#-webkit-keyframes phrase2Anim {
0% {font-size:25px; top:0px;}
100% {color:black; font-size:50px; top:-50px;}
}
#-webkit-keyframes phrase3Anim {
0% {top:0px;}
100% {top:-50px;}
}
#-webkit-keyframes phrase4Anim {
0% {top:0px;}
100% {top:-50px; opacity:1;}
}
This will support an indefinite amount of elements inside of the list. Of course, it's not perfect, and you have to tweak it to your needs, but hopefully it'll get you started. The code is pretty self explanatory, I think.
This will only work with Chrome, in its current state, but for it to work in other browsers, all you need to do is add the relevant vendor-prefixes to the CSS rules and to the animation events. For multi-browser support, just add the relevant CSS fallbacks and listener fixes.
It animates (right/fade-out) the element with class active
It clones said element and pushes it to the bottom, fading it in.
It removes the clone and appends the original one (as the clone was just for aesthetics)
It animates (up, font-size, color) the element next to active.
jsFiddle for Chrome
jsFiddle for Firefox (apparently, FF is awesome and doesn't need vendor prefixes).
Finally, this is the Chrome version in snippet form:
var phrases = document.getElementById('phrases'),
next = document.getElementById('next'),
ongoing = false;
function animList() {
var active = document.getElementsByClassName('active')[0],
next = active.nextElementSibling,
clone;
if(ongoing) return;
ongoing = true;
function animationStart() {
clone = this.cloneNode(true);
clone.id = '_tmp';
clone.className = '';
clone.style.transition = 'opacity 1s';
clone.style.opacity = '0';
setTimeout(function () { clone.style.opacity = '1' }, 50);
phrases.appendChild(clone);
this.removeEventListener('webkitAnimationStart', animationStart);
}
function animationEnd() {
clone.parentNode.removeChild(clone);
phrases.appendChild(active);
this.classList.remove('active', 'animActive', 'slideUp');
this.removeEventListener('webkitAnimationEnd', animationEnd);
this.removeEventListener('webkitAnimationStart', animationStart);
next.classList.remove('slideUp');
next.classList.add('active');
ongoing = false;
}
active.classList.add('animActive');
next.classList.add('slideUp');
active.addEventListener('webkitAnimationStart', animationStart);
active.addEventListener('webkitAnimationEnd', animationEnd);
}
next.onclick = animList;
#next {
position: relative;
display: inline-block;
top: 2.5em;
background: transparent;
border: 0;
font-size: 2em;
}
#phrases {
display: inline-block;
vertical-align: top;
max-height: 11em;
}
#phrases div {
font-size: 2em;
color: gray;
position: relative;
}
#phrases div.active {
font-size: 3em;
color: black;
}
.animActive {
-webkit-animation: animActive 1s ease-in-out;
}
.slideUp {
-webkit-animation: slideUp 1s;
}
#phrases div.slideUp ~ div:nth-child(n+3) {
-webkit-animation: slideUpRest 1s;
}
#-webkit-keyframes animActive {
0% {
left: 0;
}
100% {
left: 4em;
opacity: 0
}
}
#-webkit-keyframes slideUp {
0% {
top: 0;
}
100% {
top: -1.15em;
font-size: 3em;
color: black;
}
}
#-webkit-keyframes slideUpRest {
0% {
top: 0;
}
100% {
top: -1.7em;
}
}
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet"/>
<div id="phrases">
<div id="phrase1" class="active">Phrase 1</div>
<div id="phrase2">Phrase 2</div>
<div id="phrase3">Phrase 3</div>
<div id="phrase4">Phrase 4</div>
<div id="phrase5">Phrase 5</div>
</div>
<button id="next">
<i class="fa fa-angle-right"></i>
</button>

Categories