How to add a *progressive* animation delay based on n-th position? - css

I'd like to animate a list of items. The first should animate with 0ms delay, the second should do the same animation with 50ms delay, third with 100ms delay and so on. The list is dynamic so I won't know the length.
Is this possible? Note: I don't need help with animations / keyframes specifically, but how to use nth-child or nth-of-type (or anything else?) to achieve a progressive animation delay based on relative position between siblings.
I'm using React / SASS / Webpack if that helps. I can use jQuery if necessary but I'd rather avoid it if possible.

Here's an example on how to do something like this with pure CSS.
You can easily alter it to bring it to your needs.
$(document).ready(function() {
$('.myList img').each(function(i){
var item = $(this);
setTimeout(function() {
item.toggleClass('animate');
}, 150*i);
})
});
#keyframes FadeIn {
0% {
opacity: 0;
transform: scale(.1);
}
85% {
opacity: 1;
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
.myList img {
float: left;
margin: 5px;
visibility: hidden;
}
.myList img.animate {
visibility: visible;
animation: FadeIn 1s linear;
animation-fill-mode:both;
animation-delay: .5s
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="myList">
<img src="http://placehold.it/350x30" />
<img src="http://placehold.it/350x30" />
<img src="http://placehold.it/350x30" />
<img src="http://placehold.it/350x30" />
<img src="http://placehold.it/350x30" />
</div>

Related

CSS Animation when Div is added in Vue v-for list

I had a vue list like below:
<div v-for="item in items">
<div class="animation">{{ item.name }}</div>
</div>
And my animation is
#keyframes loadingComment {
0% {
opacity: 0.6 !important;
}
99% {
opacity: 0.6 !important;
}
100% {
opacity: 1;
}
}
However when I add an animation to to item it starts the animation whenever the page loads even tho there are 0 items inside the array. I want the animation to play when the item is added to the items array. Any ideas? I assumed this is how it would work as default?
Thanks,
Jamie
first, you need to wrap your entire list section in a transition-group if you want to add animation to your list. Read more here
<transition-group name="list">
<div v-for="item in items" :key="item.id">
<div class="animation">{{ item.name }}</div>
</div>
</transition-group>
you need to specify a name for your transition. in that way you can control your animation style in CSS.<transition-group name="list">
If you only want to use fade animation you can use transitions for that. no need for keyframes.
something like this:
.list-enter-active, .list-leave-active {
opacity: 1;
transition: opacity .5s;
}
.list-enter, .list-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
but if you really want to use keyframes, in your example you can do something like this:
.list-enter-active, .list-leave-active {
animation: loadingComment 0.5s ease-in-out forwards;
}
#keyframes loadingComment {
0% {
opacity: 0.6;
}
100% {
opacity: 1;
}
}
also, you can see the result in this jsfiddle link jsfiddle demo

Animating div (enter and exit) in React

I want to build a simple "carousel" in React. I have a list of questions that I want the user to answer. When you click on next, it shows the next question. I want to also add a previous button in the future. Currently the animation for the item being revealed works.
However on mobile the screen jumps up when its animating from one div to another (with a slight delay)
The height of the parent div is always the same, so why would it jump?
JSX
{ this.state.activeIndex === 0 &&
<div className="surveyContainer--surveyList__animate">
<div>
<SelectField labels={data.meat.labels} value={this.props.survey.meat}/>
</div>
<div>
<Button handleClick={() => this.handleActiveIndex(2)} label="Next"/>
</div>
</div>
}
{this.state.activeIndex === 1 &&
<div className="surveyContainer--surveyList__animate">
<div>
<SelectField labels={data.energy.labels} value={this.props.survey.energy}/>
</div>
<div>
<Button handleClick={() => this.handleActiveIndex(2)} label="Next"/>
</div>
</div>
}
<SelectField/> and Button are both custom components.
CSS
.surveyContainer--surveyList__animate {
animation: slide-in 0.4s ease;
}
#keyframes slide-in {
0% {
opacity: 0;
transform: translateX(200px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
How do I fix the jumping? Also what might be a better approach to do this entire thing? If I want to add a previous button, then switching the animation will be a painstaking feature.
Edit:
For the jumping issue, try setting the parent's position to relative, then, for the child container:
.child {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
I recommend ReactTransitionGroup:
https://reactcommunity.org/react-transition-group/css-transition
Your code would look something like this:
import { CSSTranstion } from 'react-transition-group'
<CSSTranstion in={this.state.activeIndex === 0} timeout={200} classNames="survey-list" unmountOnExit>
<div className="survey-list">
<div>
<SelectField labels={data.meat.labels} value={this.props.survey.meat}/>
</div>
<div>
<Button handleClick={() => this.handleActiveIndex(2)} label="Next"/>
</div>
</div>
</CSSTransition>
<CSSTranstion in={this.state.activeIndex === 1} timeout={200} classNames="survey-list" unmountOnExit>
<div className="survey-list">
<div>
<SelectField labels={data.energy.labels} value={this.props.survey.energy}/>
</div>
<div>
<Button handleClick={() => this.handleActiveIndex(2)} label="Next"/>
</div>
</div>
</CSSTransition>
Then your CSS:
.survey-list {
opacity: 1;
transform: translateX(0);
}
.survey-list.survey-list-enter {
opacity: 0;
transform: translateX(200px);
}
.survey-list.survey-list-enter-active {
opacity: 1;
transform: translateX(0);
transition: opacity 200ms;
}
.survey-list.survey-list-exit {
opacity: 1;
}
.survey-list.survey-list-exit-active {
opacity: 0;
transform: translateX(-200px);
transition: opacity 200ms;
}
And I'm not sure entirely the breadth of your intention, but you may also want to look into TransitionGroup, since it will automate adding classes to an array of children as they're toggled in and out:
https://reactcommunity.org/react-transition-group/transition-group
As a sidenote, if you're using BEM for your CSS, you shouldn't (i.e. surveyContainer--survey-list) be using a modifier as a block. Just allow survey-list to be its own block if it has its own elements. It prevents long confusing classes.

css animation different timing forward and reverse

I'm trying to create a simple 3 image slide show by swapping the z-index of the 3 images. I'm giving each of them 4 seconds of time before the next image swaps in. It works fine for the first cycle, but there after the first image doesn't show up anymore.
<html>
<head>
<style>
.HPLIMG1 {
z-index: 0;
animation: move 4s linear 0s infinite alternate;
}
#keyframes move {
from { z-index: 100; }
to { z-index: 400; }
}
.HPLIMG2 {
z-index: 0;
animation: move1 4s linear 4s infinite alternate;
}
#keyframes move1 {
from { z-index: 100; }
to { z-index: 400; }
}
.HPLIMG3 {
z-index: 0;
animation: move2 4s linear 8s infinite alternate;
}
#keyframes move2 {
from { z-index: 100; }
to { z-index: 400; }
}
</style>
</head>
</body>
<div>
<img src="1.png" class="HPLIMG1" style="position:relative"/>
<img src="2.png" class="HPLIMG2" style="position:relative; left:-200px; margin-right:-200px"/>
<img src="3.png" class="HPLIMG3" style="position:relative; left:-200px; margin-right:-200px"/>
</div>
</body>
</html>
As you can see, I'm trying to stagger the start time of each animation by 4 seconds. I've come to realize that this is likely a timing (frequency) issue because it takes 4 seconds to switch z index, but then another 4 to switch it back. So now I'm wondering if there is a way to animate it slowly in one direction, and then quickly the other? Is there possibly a better solution such as having one animation trigger another or using transitions (not sure if transitions can be time triggered rather than event triggered) .
I'm completely new to CSS, and I haven't been able to find an answer to this in any of the other posts.

How to fade in and fade out text on a timer using css animations

I am needing to fadeIn a list of text and then fade each one out individually using css. Here is an example I did using javascript. Any help would be appreciated. I have read some examples of how to animate stuff with css but do not know the best practices or anything to complex.
I am thinking I need to create a wrapper div with a overflow of hidden and a separate div with all the text that is position absolute in the wrapper. Then animate the .text div up or down to show the text. I have no experience with css animations.
Here is what I want to do but with css not javascript:
http://jsfiddle.net/trav5567/8ejqsywu/
Here is my javascript:
var quotes = $(".whoiam").find('h2');
var quoteIndex = -1;
quotes.hide();
function showNextQuote() {
++quoteIndex;
console.log(quoteIndex);
if(quoteIndex === quotes.length){
console.log($(this));
//console.log('index greater than or equal to h2 length');
//$(this).fadeIn('200');
}else{
console.log('Kepp going');
quotes.eq(quoteIndex % quotes.length)
.fadeIn(500)
.delay(500, checkIndex(quoteIndex,quotes.length))
.fadeOut(500, showNextQuote);
}
}showNextQuote();
function checkIndex(index, length){
var length = length-1
if(index === length){
console.log('check good');
end();
}
}
Here is my HTML:
<div id="splash-wrapper">
<div class="row">
<div class="small-12 columns">
<h1>Travis M. Heller</h1>
<div class='whoiam'>
<h2>Front End Developer</h2>
<h2>Illustrator</h2>
<h2>Web Master</h2>
<h2>Front End Developer</h2>//This value will be the last to show on loop.
</div>
<button class="btn center gotoPortfolio">ENTER</button>
</div>
</div>
</div>
An experiment with just css animations: http://jsfiddle.net/8ejqsywu/6/
There is one animation which moves the text list verticaly, and another which fades in and out the text. The difficulty was to synchronize them!
#container{
overflow:hidden;
height:48px;
}
.whoiam{
-webkit-animation: move;
position:relative;
-webkit-animation-duration: 8s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: step-start;
-webkit-animation-delay: 0.5s
}
h2{ height:48px;margin:0;padding:0}
#-webkit-keyframes move {
0% { margin-top: 0em; }
25% { margin-top: -48px; }
50% {margin-top: -96px;}
75% {margin-top: -144px; }
100% {margin-top: 0;}
}
h2{
-webkit-animation: fade;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
}
#-webkit-keyframes fade {
0% { opacity: 1; }
50% { opacity: 0; }
100% { opacity: 1; }
}

how to add transitions to a slideshow made with javascript

I know this question has been asked before but I can't get mine working. I have a javascript array in the head of my html document which makes the images change to the next one in the array, but I can't make transitions work. I've tried using css properties and I've very briefly tried jquery but as I haven't used jquery before I don't know how to do anything with it.
I have this for javascript:
<script type="text/javascript">
image2 =new Array("images/product1_thumb.png", "images/product2_thumb.png", "images/product3_thumb.png"
, "images/product4_thumb.png")
num =0;
imgNum =image2.length;
function rotate()
{
if(document.images)
{
if(num ==imgNum)
{
num = 0;
}
}
document.getElementById('image2').src = image2[num];
num++;
setTimeout("rotate()",4000);
}
</script>
This is the html:
<section id="right">
<img src="images/product1_thumb.png" ID="image2" alt="" title="" />
</section>
And this css is what I've used to try to make the transitions:
#image2{
margin-left:100px;
position:inherit;
-moz-transition: all 2s ease-in-out 2s;
-webkit-transition: all 2s ease-in-out 2s;
transition: all 2s ease-in-out 2s; /* opacity 5s ease-in-out; */
}
#right{
padding-top:10%;
margin-left:70%;
width:30%;
background-image:url('images/watermark50.png');
background-repeat:no-repeat;
background-position:center;
height:100%;
}
#right img{
margin-left: 30%;
}
I'd be grateful for any help but if it uses jquery you'd have to start at the beginning as I have no idea how it works.

Resources