I'm making my React app and I made an image carousel using setInterval which changes img src every 2 seconds.
Now I'd like to animate the change of img using transition. (CSSTransitionGroup is unclear to me).
However I have a problem with attaching transition to any measureable element. Can I somehow "grab" the setInterval source-changing event using css?
So far, I've tried adding "opacity: 1" style to images set to opacity: 0, but the opacity: 1 stays beyonod every iteration of interval, thus only the first image gets transition and the new ones have a "opacity:1" styling by default.
I'm talking about the " NavLink to ="/about_us"> " section
Here's my code. Any ideas? I've wasted 5hours on this:
import React, {
Component
} from 'react';
import {
NavLink
} from "react-router-dom";
class Radzikowskiego_S2_Staff extends Component {
constructor(props) {
super(props);
this.state = {
spanText: 'Zabawy',
text: ["Rozwoju", "Odpoczynku", "Śmiechu", "Zabawy"],
staffImg: "Aleksandra_Brozyna",
staff: ["Dominika_Serwa", "Dorota_Szastak", "Joanna_Wozniak", "Alicja_Kwasny", "Kinga_Kaczmarek", "Monika_Garula", "Maria_Kaczmarek", "Natalia_Kiczura", "Violetta_Wojas"],
index: 0,
indexStaff: 0,
}
}
componentDidMount() {
this.changeSpan();
this.changeStaff();
}
changeSpan = () => {
this.interval = setInterval(() => {
this.setState({
spanText: this.state.text[this.state.index],
index: this.state.index >= this.state.text.length - 1 ? 0 : this.state.index + 1
});
}, 2000);
};
changeStaff = () => {
this.interval = setInterval(() => {
this.setState({
staffImg: this.state.staff[this.state.indexStaff],
indexStaff: this.state.indexStaff >= this.state.staff.length - 1 ? 0 : this.state.indexStaff + 1,
});
}, 2000);
};
showImg = () => {
// console.log(event.target.style.opacity='0.5');
// console.log(this.refs.img_src.style.opacity='1')
this.refs.img_src.classList.add('show_images')
};
componentWillUpdate() {
this.showImg();
this.removeImg();
}
removeImg = () => {
// console.log(event.target.style.opacity='0.5');
// console.log(this.refs.img_src.style.opacity='1')
// console.log(this.refs.img_src.classList)
this.refs.img_src.classList.remove('show_images')
};
render() {
return (
<
div id = 'staff' >
<
div className = 'row' >
<
div className = 'col-12 text-center mb-3' >
<
h3 > Krakowiaczek to miejsce do </h3> <
h6 id = "staff_span"
className = "animate_span" > {
this.state.spanText
} < /h6> <
h6 class = "mt-3" > W Przedszkolu Krakowiaczek nie ma czasu na nudę. < /h6>
<
/div> <
/div>
<
div class = 'row align-items-center ' >
<
div className = 'col-md-2 col-md-offset-1 section_2_thumbnail' >
<
NavLink to = "/our_philosophy" >
<
img src = 'images/filozofia.svg'
className = 'section_2_thumbnail_img' / >
<
p class = "pt-2" > Nasza Filozofia < /p> <
/NavLink> <
/div> <
div className = 'col-md-2 col-md-offset-1 section_2_thumbnail' >
<
NavLink to = "/extended_offer" >
<
img src = 'images/what_we_offer.svg'
className = 'section_2_thumbnail_img' / >
<
p className = "pt-2" > Co oferujemy < /p> <
/NavLink> <
/div> <
div className = 'col-md-2 col-md-offset-1 section_2_thumbnail' >
<
NavLink to = "/enrollment" >
<
img src = 'images/zapisy.svg'
className = 'section_2_thumbnail_img' / >
<
p className = "pt-2" > Zapisy < /p> <
/NavLink> <
/div>
<
div className = 'col-md-3 col-md-offset-1 section_2_thumbnail' >
<
NavLink to = "/about_us" >
<
img src = {
`images/teachers/${this.state.staffImg}.jpg`
}
className = 'section_2_thumbnail_staff pb-2'
id = 'staffIcon'
onLoad = {
this.showImg
}
ref = 'img_src' / >
<
p className = "mt-2 mb-3" > Kadra < /p> <
/NavLink> <
/div> <
/div>
<
/div>
)
}
}
export default Radzikowskiego_S2_Staff;
Ok, I used the crossfade functionality to get the issue done. I used map to render all img srcs from an array and then used animation to generate the image shift.
I think I'll incorporate some sort of sass loop to simplify the scss once I do some refactor although a little tip would be nice
<div class="staff_img_wrapper">
{
this.state.staff.map(element => {
return (
<img src={`images/teachers/${element}.jpg`} className='section_2_thumbnail_staff pb-2' id='staffIcon' />
)
})
}
</div>
CSS
.staff_img_wrapper {
height: 20vh;
img:nth-child(1) {
position: absolute;
opacity: 1;
left: 0;
right: 0;
margin: 0 auto;
animation: fadeOut 3s;
animation-fill-mode: forwards;
z-index:10;
}
img:nth-child(2) {
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
opacity: 1;
animation: fadeOut 3s;
animation-delay: 3s;
animation-fill-mode: forwards;
z-index: 9;
}
img:nth-child(3) {
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
opacity: 1;
animation: fadeOut 3s;
animation-delay: 6s;
animation-fill-mode: forwards;
z-index: 8;
}
img:nth-child(4) {
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
opacity: 1;
animation: fadeOut 3s;
animation-delay: 9s;
animation-fill-mode: forwards;
z-index: 7;
}
img:nth-child(5) {
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
opacity: 1;
animation: fadeOut 3s;
animation-delay: 12s;
animation-fill-mode: forwards;
z-index: 6;
}
img:nth-child(5) {
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
opacity: 1;
animation: fadeOut 3s;
animation-delay: 15s;
animation-fill-mode: forwards;
z-index: 5;
}
img:nth-child(6) {
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
opacity: 1;
animation: fadeOut 3s;
animation-delay: 18s;
animation-fill-mode: forwards;
z-index: 4;
}
img:nth-child(7) {
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
opacity: 1;
animation: fadeOut 3s;
animation-delay: 21s;
animation-fill-mode: forwards;
z-index: 3;
}
img:nth-child(8) {
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
opacity: 1;
animation: fadeOut 3s;
animation-delay: 24s;
animation-fill-mode: forwards;
z-index: 2;
}
img:nth-child(9) {
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
opacity: 1;
animation: fadeOut 3s;
animation-delay: 27s;
animation-fill-mode: forwards;
z-index: 1;
}
img:nth-child(10) {
position: absolute;
left: 0;
right: 0;
margin: 0 auto;
opacity: 1;
animation: fadeOut 3s;
animation-delay: 30s;
animation-fill-mode: forwards;
z-index: 0;
}
}
#keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0
}
}
Related
I have this animation, I would like to randomize the translateX value with a specific range.
#peperone{
position: relative;
z-index: 7;
animation: droppepper 4s linear forwards;
animation-iteration-count: infinite ;
}
#keyframes droppepper{
from {
transform: translateY(-400px) translateX(-90%) rotate(0deg);
}
to {
transform : translateY(1000%) translateX(-30%) rotate(180deg);
}
}
I saw a lot of answers here on stackoverflow and other pages as well, but I can't put it to work..
I tried with
.random(#min, #max) {
#random: `Math.round(Math.random() * (#{max} - #{min}) + #{min})`;
}
and adding .random(-100, -20); into #peperone, but then I don't know how to use that number inside the transform translateX().
Is this doable or am I pretending too much? :P
If so, can you help me out?
Thanks
You can generate a random number with Javascript and update a set css variable, I included an example below.
const randomInt = Math.floor(Math.random() * (100 - 20 + 1) + 20)
console.log('translateX will animate to: ',randomInt*-1 + "%");
const root = document.documentElement;
root.style.setProperty('--random-int', randomInt*-1 + "%");
document.getElementById('guide').style.width = randomInt + "%";
document.getElementById('guide').textContent = randomInt + "%";
:root {
--random-int: -50%;
}
html, body {
margin: 0;
}
#peperone{
position: relative;
z-index: 7;
animation: droppepper 4s linear forwards;
animation-iteration-count: infinite;
width: 100px;
line-height: 100px;
background: #333;
color: #fff;
font-size: 0.9rem;
position: relative;
margin: 2rem 0;
height: 100px;
}
#guide {
position: absolute;
top: 0;
left: 0;
background: red;
height: 100%;
}
#keyframes droppepper{
from {
transform: translateX(100%);
}
to {
transform: translateX(var(--random-int));
}
}
<div id="peperone"><div id="guide"></div></div>
I'm fairly new to SCSS so hopefully someone can help me out.
I'm trying to move particles in the same direction (down), but because all the particles are placed randomly their destination also ends up random.
I would like to keep random placement, but once they are placed I want them all going in the same direction (down) and not in the random direction. I don't know how to do that without loosing random positioning generated with steps.
I know how to do this in CSS, but that would require specifying every path manually, which will be my final solution if I can get it to work with SCSS, unless someone can help me out?
Here is JSFiddle to show how it's behaving, but this is the part where random steps are created:
SCSS
#for $i from 1 through $dot-count {
&:nth-of-type(#{$i}) {
animation-name: move-path-#{$i};
&:before {
animation-duration: random(5000) + 5000ms, random(1000) + 7000ms;
animation-delay: random(6000) + 500ms, 0s;
}
}
$steps: random(15) + 10;
#keyframes move-path-#{$i} {
#for $step from 0 through $steps {
#{$step / $steps * 100%} {
transform: translateX(random(100) - 50vw)
translateY(random(100) - 50vh)
scale(random(70) / 100 + 0.3);
}
}
}
}
You could define a random variable common to all your particles, use it to position your particles and then move them according to their step number and not randomly.
html {
font-size: 30vmax / 1920 * 100;
font-family: "Quicksand", sans-serif;
background-color: #000;
margin: 0;
padding: 0;
#media (max-width: 768px) {
font-size: 50px;
}
}
// Stars
$dot-color: #fff;
$dot-count: 35;
#milky-way {
width: 100%;
}
.sky {
position: fixed;
width: 100%;
height: 100%;
z-index: 10;
pointer-events: none;
}
.dot {
position: absolute;
width: 0.08rem;
height: 0.08rem;
top: 50%;
left: 50%;
animation: 160s ease both infinite alternate;
&:before {
content: "";
display: block;
width: 100%;
height: 100%;
border-radius: 50%;
background-color: $dot-color;
transform-origin: -1rem;
animation: lighting ease both infinite, auto-rotating ease both infinite;
}
#for $i from 1 through $dot-count {
// Random variable common to all particles
$random: random(100);
&:nth-of-type(#{$i}) {
animation-name: move-path-#{$i};
&:before {
animation-duration: random(5000) + 5000ms, random(1000) + 7000ms;
animation-delay: random(6000) + 500ms, 0s; // less than max duration
}
}
$steps: random(15) + 10;
#keyframes move-path-#{$i} {
#for $step from 0 through $steps {
#{$step / $steps * 100%} {
// first translation is depending on a common random, second is depending on the step number
transform: translateX($random - 50vw) translateX($step * $step * 150px)
translateY($random - 50vh) translateY($step * $step * 150px)
scale(random(70) / 100 + 0.3);
}
}
}
}
}
#keyframes lighting {
0%,
30%,
100% {
opacity: 0;
}
5% {
opacity: 1;
box-shadow: 0 0 0.3rem 0.05rem $dot-color;
}
}
#keyframes auto-rotating {
to {
transform: rotate(0deg);
}
}
I'm trying to create a visual transition between content changes in a toy SPA I'm writing. To that end, I define a simple class for animating the opacity of an element.
.fade {
transition: opacity 1.5s;
}
In my render function, I now change the opacity of my outlet div after content changes like so:
function render(content) {
var outlet = document.getElementById("outlet");
outlet.classList.remove("fade");
outlet.style.opacity = 0;
outlet.innerHTML = content;
outlet.classList.add("fade");
outlet.style.opacity = 1;
}
Unfortunately, the animation never fires. When I delay changing the opacity to 1 via setTimeout for 10ms, say, it works sometimes if I don't change the content again while the animation is still running, indicating a timing issue/race condition.
I used a similar approach in the past to fade out messages, but there I intentionally delayed changing the opacity by a few seconds so users could read the message before it starts fading out.
Pure CSS animation fadeIn
li {
position: absolute;
top: 50%;
left: 50%;
margin-top: -75px;
}
.logo {
width: 300px;
height: 150px;
background: red;
margin-left: -150px;
z-index: 30;
-webkit-animation: fade-in-slogan 4s .2s ease-in forwards;
-moz-animation: fade-in-slogan 4s .2s ease-in forwards;
animation: fade-in-slogan 4s .2s ease-in forwards;
}
.menu {
width: 600px;
height: 150px;
background: blue;
margin-left: -300px;
opacity: 0;
-webkit-animation: fade-in-menu 3s 4s ease-out forwards;
-moz-animation: fade-in-menu 3s 4s ease-out forwards;
animation: fade-in-menu 3s 4s ease-out forwards;
}
#-webkit-keyframes fade-in-slogan {
0% { opacity: 0; }
30% { opacity: 1; }
50% { opacity: 1; }
70% { opacity: 1; }
100% { opacity: 0; }
}
#-webkit-keyframes fade-in-menu {
0% { display: block; opacity: 0; }
30% { display: block; opacity: .3; }
60% { display: block; opacity: .6; }
80% { display: block; opacity: .8; }
100% { display: block; opacity: 1; }
}
<ul class"main">
<li class="logo"></li>
<li class="menu"></li>
</ul>
Try this, I hope this will solve the issue
.fade{
animation-name: example;
animation-duration: 4s;}
#keyframes example {
from {opacity:1}
to {opacity:0;}
}
div{
width:200px;
height:200px;
background:#000;
}
<html>
<head>
</head>
<body>
<div class="fade"></div>
</body>
</html>
I've solved it now inspired by Muhammad's answer. I defined the fade class as follows:
.fade {
animation-name: fadein;
animation-duration: 1.25s;
#keyframes fadein {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
Then in the render function, I do
function render(content) {
outlet.classList.remove("fade");
outlet.innerHTML = "";
setTimeout(() => {
outlet.classList.add("fade");
outlet.appendChild(content);
}, 100);
}
Even though this adds an additional delay before the new content actually starts to fade in, it seems the most elegant and concise solution to me.
This should be so simple, but I've been breaking my head over this for days. I'm trying to animate my page transitions. The problem is the docs SUCK. I've followed them over and over and tried every which way, but can't get it to work.
What I want to do is slide my pages gracefully either right or left, and fade the one that is unmounting gracefully out behind it. Simple right? I am NOT using React Router for my pages.
I've tried a variety of solutions for this, but the problem seems to be on the unmounting. When the page is replaced, the existing page gets unmounted before it can transition out. I'm posting my attempt with react-transition-group, though at this point, I'll accept any other solution that works. I'm not sure react-transition-group is being actively maintained actually, because there are numerous other postings for help with 0 responses.
So on my app container I want to put something like this:
<App>
<PageSlider>
<Page key={uniqueId} /> <==this will be "swapped" through (Redux) props
</PageSlider>
So, from what I've read, I have to use a TransitionGroup container as my PageSlider for this, so that it will manage the entering and exiting of my page. So here goes:
class PageSlider extends Component {
constructor(props) {
super(props);
}
render() {
return (
<TransitionGroup
component="div"
id="page-slider"
childFactory={child => React.cloneElement(child,
{classNames: `page-${this.props.fromDir}`, timeout: 500}
)}
>
{this.props.children}
</TransitionGroup>
);
}
}
I also read I need to do a "child Factory" to enable the exiting stuff. There was absolutely no example of this I could find in the docs. Since the pages will come from different directions, I will pass to this the direction from which I want to slide the page, which will tell the page what class it gets.
Now, as for the page itself, I have wrapped it in a CSSTransition like so. There were no good examples in the docs of how this all gets passed down, so I'm really confused what to do here:
class Page extends Component {
constructor(props) {
super(props);
}
render() {
return (
<CSSTransition> <==????????
{this.props.children} Do props get passed down?
</CSSTransition> Which ones?
); Does "in" get taken care of?
}
}
And just to finish the styles will be applied in CSS something like this:
.page {
display: flex;
flex-direction: column;
height: 100%;
position: absolute;
top: 0;
bottom: 0;
-webkit-transition: all 500ms ease-in-out;
transition: all 500ms ;
}
//go from this
.page-right-enter {
-webkit-transform: translate3d(100%, 0, 0);
transform: translate3d(100%, 0, 0);
}
//to this
.page-right-enter-active {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
//exiting go from this
.page-right-exit {
opacity: 1;
}
//to this
.page-right-exit-active {
opacity: 0;
}
All of these components will be connected through Redux so they know when a new page has been triggered and which direction has been called.
Can someone PLEEEEASE help me on this? I've literally spent days and tried every library out there. I'm not wedded to react-transition-group! Any library that works on the unmount I'll try. Why is this not easier?
OK. Well, I struggled with this for WAAAAY too long. I finally dumped react-transition-group, and went pure CSS. Here's my solution.
PageSlider.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';
require('./transitions.scss');
const BlankPage = (props) => <div className="placeholder"></div>;
class PageSlider extends Component {
constructor(props) {
super(props);
this.state = {
nextRoute: props.page,
pages: {
A: {key: 'A', component: BlankPage, className: 'placeholder'},
B: {key: 'B', component: BlankPage, className: 'placeholder'},
},
currentPage: 'A'
};
}
componentDidMount() {
//start initial animation of incoming
let B = {key: 'b', component: this.state.nextRoute, className: 'slideFromRight'}; //new one
let A = Object.assign({}, this.state.pages.A, {className: 'slideOutLeft'}); //exiting
this.setState({pages: {A: A, B: B}, currentPage: 'B'});
}
componentWillReceiveProps(nextProps) {
if (nextProps.page != this.state.nextRoute) {
this.transition(nextProps.page, nextProps.fromDir);
}
}
transition = (Page, fromDir) => {
if (this.state.nextRoute != Page) {
let leavingClass, enteringClass;
let pages = Object.assign({}, this.state.pages);
const current = this.state.currentPage;
const next = (current == 'A' ? 'B' : 'A');
if (fromDir == "right") {
enteringClass = 'slideFromRight';
leavingClass = 'slideOutLeft';
} else {
enteringClass = 'slideFromLeft';
leavingClass = 'slideOutRight';
}
pages[next] = {key: 'unique', component: Page, className: enteringClass};
pages[current].className = leavingClass;
this.setState({pages: pages, nextRoute: Page, currentPage: next});
}
}
render() {
return (
<div id="container" style={{
position: 'relative',
minHeight: '100vh',
overflow: 'hidden'
}}>
{React.createElement('div', {key: 'A', className: this.state.pages.A.className}, <this.state.pages.A.component />)}
{React.createElement('div', {key: 'B', className: this.state.pages.B.className} , <this.state.pages.B.component />)}
</div>
);
}
}
PageSlider.propTypes = {
page: PropTypes.func.isRequired,
fromDir: PropTypes.string.isRequired
};
export default PageSlider;
transition.scss
.placeholder {
position: absolute;
left: 0;
width: 100vw;
height: 100vh;
background: transparent;
-webkit-animation: slideoutleft 0.5s forwards;
-webkit-animation-delay: 10;
animation: slideoutleft 0.5s forwards;
animation-delay: 10;
}
.slideFromLeft {
position: absolute;
left: -100vw;
width: 100vw;
height: 100vh;
-webkit-animation: slidein 0.5s forwards;
-webkit-animation-delay: 10;
animation: slidein 0.5s forwards;
animation-delay: 10;
}
.slideFromRight {
position: absolute;
left: 100vw;
width: 100vw;
height: 100vh;
-webkit-animation: slidein 0.5s forwards;
-webkit-animation-delay: 10;
animation: slidein 0.5s forwards;
animation-delay: 10;;
}
.slideOutLeft {
position: absolute;
left: 0;
width: 100vw;
height: 100vh;
-webkit-animation: slideoutleft 0.5s forwards;
-webkit-animation-delay: 10;
animation: slideoutleft 0.5s forwards;
animation-delay: 10;
}
.slideOutRight {
position: absolute;
left: 0;
width: 100vw;
height: 100vh;
-webkit-animation: slideoutright 0.5s forwards;
-webkit-animation-delay: 10;
animation: slideoutright 0.5s forwards;
animation-delay: 10;
}
#-webkit-keyframes slidein {
100% { left: 0; }
}
#keyframes slidein {
100% { left: 0; }
}
#-webkit-keyframes slideoutleft {
100% { left: -100vw; opacity: 0 }
}
#keyframes slideoutleft {
100% { left: -100vw; opacity: 0}
}
#-webkit-keyframes slideoutright {
100% { left: 100vw; opacity: 0}
}
#keyframes slideoutright {
100% { left: 100vw; opacity: 0}
}
Passing in the next component, which is my react Page component, called like so:
app.js
<div id="app">
<PageSlider page={this.state.nextRoute} fromDir={this.state.fromDir}/>
</div>
$(function() {
$('.text1').delay(1000).fadeIn(1500);
$('.text1').delay(600).fadeOut(1500);
$('.text2').delay(5000).fadeIn(1500);
$('.text2').delay(600).fadeOut(1500);
$('.text3').delay(10000).fadeIn(1500);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="text1">Lorem Ipsem</div>
<div class="text2">Lorem Ipsem</div>
<div class="text3">Lorem Ipsem</div>
Above is my simple jQuery animation; simple delay -> fadeIn -> delay -> fadeOut. However I find when trying to create a loop, for my animations to run continuously my code becomes way to large and bulky. I am wondering if it's at all possible to rewrite what I have above with CSS3 only, and then using the infinite option CSS allows.
I've gotten close with CSS below code however, I need to completely hide or fadeOut each line of text before new text shows.
#-webkit-keyframes slider {
0% { opacity: 0.4; }
100% { opacity: 1; }
}
#-moz-keyframes slider {
0% { opacity: 0.4; }
100% { opacity: 1; }
}
#-ms-keyframes slider {
0% { opacity: 0.4; }
100% { opacity: 1; }
}
.slider {
-webkit-animation: slider 1s alternate infinite;
-moz-animation: slider 1s alternate infinite;
-ms-animation: slider 1s alternate infinite;
}
<div class="slider">Lorem Ipsum</div>
As stated in other answers you can not achieve what you are asking using pure CSS solutions.
You can a solution like to an extensible approach (in case you want have many more child elements).
$("#fadeinout div").on("animationend", function() {
_this = jQuery(this);
// remove animation class
_this.removeClass("animate");
// If there is no next element then go to first one otherwise choose next element
var next = (_this.next().length < 1) ? _this.prevAll(':first-child') : _this.next();
// Add class to the new element
next.addClass("animate");
});
#fadeinout div {
width: 100px;
height: 100px;
background: red;
opacity: 0;
margin: 5px;
}
.animate {
animation-name: fadeinout;
animation-duration: 4s;
animation-delay: 0s;
}
#keyframes fadeinout {
50% {
opacity: 1;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="fadeinout">
<div class='animate'></div>
<div></div>
<div></div>
<div></div>
</div>
This is the same example with many child elements animated: https://jsfiddle.net/j4zdgopr/1/
You can't really time the animation of multiple elements in css only. Well you could probably fake it with something like:
div {
width: 50px;
height: 50px;
background: #f00;
opacity: 0;
}
#d1 {
animation: d1 10s infinite;
}
#d2 {
animation: d2 10s infinite;
}
#d3 {
animation: d3 10s infinite;
}
#d4 {
animation: d4 10s infinite;
}
#keyframes d1 {
0% { opacity: 0; }
5% { opacity: 1; }
20% { opacity: 1; }
25% { opacity: 0; }
}
#keyframes d2 {
25% { opacity: 0; }
30% { opacity: 1; }
45% { opacity: 1; }
50% { opacity: 0; }
}
#keyframes d3 {
50% { opacity: 0; }
55% { opacity: 1; }
70% { opacity: 1; }
75% { opacity: 0; }
}
#keyframes d4 {
75% { opacity: 0; }
80% { opacity: 1; }
95% { opacity: 1; }
100% { opacity: 0; }
}
<div id="d1"></div>
<div id="d2"></div>
<div id="d3"></div>
<div id="d4"></div>
...but I would recommend against it. First of all I don't think the timing will be reliable - ie. it will get out of sync. Second your code will most likely be even more bulky than what you have.
So I would recommend a combination of simple CSS transitions and JS like this:
var curslide = 0;
var slides = $("#slider div");
var nextslide = function() {
slides.removeClass('shown');
if (curslide >= slides.length) curslide = 0;
slides.eq(curslide).addClass('shown');
curslide++;
setTimeout(nextslide, 3000);
}
nextslide();
#slider div {
width: 50px;
height: 50px;
background: #f00;
opacity: 0;
transition: opacity .5s linear;
}
#slider div.shown {
opacity: 1;
transition: opacity .5s .5s linear;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="slider">
<div id="d1"></div>
<div id="d2"></div>
<div id="d3"></div>
<div id="d4"></div>
</div>
With this solution you can add as many frames as needed without modifying the css or js.
I'd try playing with animation-delay, but I think it only applies to the first time the animation is run. After that, unless you write one animation for each .text element, they'll all fade in/out with the same frequency.
Would:
setInterval(function(){
$('.text1').delay(5000).fadeIn(1500);
$('.text2').delay(5000).fadeIn(1500);
$('.text3').delay(5000).fadeIn(1500);
$('.text1').delay(1000).fadeOut(1500);
$('.text2').delay(5000).fadeOut(1500);
}, 11500);
get you somewhere close?