I have a CSS animation which is quite complex, ie. it's layered, or brings in two images, one a background image, then an <img> tag inside that, to overlay the original.
Demo is here: http://wdb.blazeoven.co.uk/
HTML:
<div class="container">
<a href="services.php">
<div class="col-sm-3 home-circle" id="one">
<img class="bottom" id="five" src="/assets/img/prop-consultants.png" alt="residential block in grounds">
</div>
</a>
<a href="services.php">
<div class="col-sm-3 home-circle" id="two">
<img class="bottom" id="six" src="/assets/img/chartered-surveyors.png" alt="old residential house doorways">
</div>
</a>
<a href="services.php">
<div class="col-sm-3 home-circle" id="three">
<img class="bottom" id="seven" src="/assets/img/managing-agents.png"
alt="row of shops">
</div>
</a>
<a href="services.php">
<div class="col-sm-3 home-circle" id="four">
<img class="bottom" id="eight" src="/assets/img/city-central.png" alt="City shop premises">
</div>
</a>
CSS:
#-webkit-keyframes fadeOut { from { opacity:1; } to { opacity:0; } }
#-moz-keyframes fadeOut { from { opacity:1; } to { opacity:0; } }
#keyframes fadeOut { from { opacity:1; } to { opacity:0; } }
#-webkit-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
#-moz-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
#keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
.home-banner .container a .col-sm-3 {
opacity:0;
-webkit-animation:fadeIn ease-in 1;
-moz-animation:fadeIn ease-in 1;
animation:fadeIn ease-in 1;
-webkit-animation-fill-mode:forwards;
-moz-animation-fill-mode:forwards;
animation-fill-mode:forwards;
-webkit-animation-duration:1s;
-moz-animation-duration:1s;
animation-duration:1s;
}
.home-banner #one {
background:url('/assets/img/propcons.svg') center no-repeat;
background-size: 100%;
-webkit-animation-delay: 0.4s;
-moz-animation-delay: 0.4s;
animation-delay: 0.4s;
}
.home-banner #two {
background:url('/assets/img/charsurv.svg') center no-repeat;
background-size: 100%;
-webkit-animation-delay: 0.8s;
-moz-animation-delay: 0.8s;
animation-delay: 0.8s;
}
.home-banner #three {
background:url('/assets/img/manage.svg') center no-repeat;
background-size: 100%;
-webkit-animation-delay: 1.4s;
-moz-animation-delay: 1.4s;
animation-delay: 1.4s;
}
.home-banner #four {
background:url('/assets/img/citycen.svg') center no-repeat;
background-size: 100%;
-webkit-animation-delay: 1.8s;
-moz-animation-delay: 1.8s;
animation-delay: 1.8s;
}
.grey-banner img.bottom {
opacity:1;
-webkit-animation:fadeOut ease-in 1;
-moz-animation:fadeOut ease-in 1;
animation:fadeOut ease-in 1;
// -webkit-animation-direction: alternate;
// -moz-animation-direction: alternate;
// animation-direction: alternate;
-webkit-animation-fill-mode:forwards;
-moz-animation-fill-mode:forwards;
animation-fill-mode:forwards;
-webkit-animation-duration:1s;
-moz-animation-duration:1s;
animation-duration:1s;
}
.grey-banner img#five {
-webkit-animation-delay: 6.8s;
-moz-animation-delay: 6.8s;
animation-delay: 6.8s;
}
.grey-banner img#six {
-webkit-animation-delay: 7.4s;
-moz-animation-delay: 7.4s;
animation-delay: 7.4s;
}
.grey-banner img#seven {
-webkit-animation-delay: 8s;
-moz-animation-delay: 8s;
animation-delay: 8s;
}
.grey-banner img#eight {
-webkit-animation-delay: 8.6s;
-moz-animation-delay: 8.6s;
animation-delay: 8.6s;
}
Trouble is, the client is requesting that it repeats again. That is, it plays in reverse, then starts again.
I have tried unsuccessfully to do this with CSS, is there a succinct way to do it with Javascript?
Thanks in advance for your comments.
Ben
You can repeat the animation using animation-iteration-count:
-moz-animation-iteration-count: 3; /* Firefox 5 -> 15 */
-webkit-animation-iteration-count: 3; /* Chrome, Safari, Opera */
animation-iteration-count: 3; /* Firefox 16, IE 10 */
Not supported in IE 9 and earlier.
You can also use the value infinite to repeat over and over.
Edit:
As I commented you can try with cubic-bezier:
Use no delay, and animation-duration:10s. You can try with these cubic-bezier values on the animation-timing-function for the four images:
animation-timing-function: cubic-bezier(0.2, 0.0, 0.0, 1.5);
animation-timing-function: cubic-bezier(0.4,-0.7, 0.4, 1.8);
animation-timing-function: cubic-bezier(0.7,-1.7, 0.7, 1.8);
animation-timing-function: cubic-bezier(0.9,-1.6, 0.8, 0.8);
I have not tried this myself, and I am not sure how well it works with the values that are < 0 and > 1 (which is not standard).
If you want to play around with how the cubic-bezier is set up, you can use the tool at http://cubic-bezier.com to help finding useful values.
You said the your client just wanted the animation to play normally, then play in reverse and then repeat.
It so happens that there is a CSS property called animation-direction. This property states whether the animation plays normally or in reverse. Use animation-direction: alternate; to – as the property value indicates – alternate between playing normally and in reverse.
Read more here: MDN: animation-direction
Hope this helps :)
Related
I want to make a headline on my website which would animate like one on this website: https://www.thisisbeyond.com/what-we-believe/
So I want the words to fade-up each with a little delay.
How could I do that? If it is possible with css only, that would be great. But javascript is also acceptable :)
I have tried splitting my words each into one column and then animating the columns (opacity: 0 to 1 transition), but it results in strange spacing between words AND I want them to fade-up, not only change the opacity. So I think the right way to do it is by just putting each word in a different span element and then animating the spans.
<h1 class="animated2">
<span>To</span> <span>show</span> <span>the</span> <span>power</span> <span>of</span>
<span class="highlight">humanity </span>
<span class="highlight">in</span>
<span class="highlight">business.</span>
</h1>
LINK to the website I am trying to achieve this: michalkuczek.pl
.highlight{
background: #fff;
}
#keyframes fadeInUpSmall{
0%{
opacity:0;
transform:translateY(10px)}
100%{
opacity:1;
transform:translateY(0)}
}
.animated2 span:nth-child(1) {
animation-delay: .1s;
}
.animated2 span {
animation-name: fadeInUpSmall;
}
.animated2 {
animation-duration: 1s;
animation-fill-mode: both;
animation-fill-mode: both;
}
You can achieve the opacity animation by creating keyframes that define the start and end states.
CSS:
#-webkit-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
#-moz-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
#keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
.fade-in {
opacity:0; /* make things invisible upon start */
-webkit-animation:fadeIn ease-in 1; /* call our keyframe named fadeIn, use animattion ease-in and repeat it only 1 time */
-moz-animation:fadeIn ease-in 1;
animation:fadeIn ease-in 1;
-webkit-animation-fill-mode:forwards; /* this makes sure that after animation is done we remain at the last keyframe value (opacity: 1)*/
-moz-animation-fill-mode:forwards;
animation-fill-mode:forwards;
-webkit-animation-duration:1s;
-moz-animation-duration:1s;
animation-duration:1s;
}
.fade-in.one {
-webkit-animation-delay: 0.7s;
-moz-animation-delay: 0.7s;
animation-delay: 0.7s;
}
.fade-in.two {
-webkit-animation-delay: 1.2s;
-moz-animation-delay:1.2s;
animation-delay: 1.2s;
}
.fade-in.three {
-webkit-animation-delay: 1.6s;
-moz-animation-delay: 1.6s;
animation-delay: 1.6s;
}
HTML:
<h1 class="animated2">
<span>To</span> <span>show</span> <span>the</span> <span>power</span> <span>of</span>
<span class="highlight fade-in one">humanity </span>
<span class="highlight fade-in two">in</span>
<span class="highlight fade-in three">business.</span>
</h1>
I'm making this site that plays our school hymn when the button "Play" is pressed and pauses when "Pause" is pressed. Alongside it the highlight animation 'per line' of the lyrics. However, I can't globally pause the animation. I wanted to pause the audio and the css animation but only the audio is the one that is actually paused so when I click the play button, the lyrics highlight and audio is not in sync anymore.
I've tried playing with animation-play-state in CSS but none of it worked great
Sorry if the code is long because I did 'per-line' lyrics but what I wanted to do is to pause any animations so that it is still in sync with the audio whenever I resume it.
.lyrics {
font-weight: lighter;
font-size: 1vw;
}
.l1.an {
animation: tae 1s;
animation-direction: alternate;
animation-duration: 5s;
animation-delay: 12s;
}
.l2.an {
animation: tae 1s;
animation-duration: 5s;
animation-fill-mode: alternate;
animation-delay: 15s;
}
.l3.an {
animation: tae 1s;
animation-duration: 8s;
animation-fill-mode: alternate;
animation-delay: 18s;
}
.l4.an {
animation: tae 1s;
animation-duration: 7s;
animation-fill-mode: alternate;
animation-delay: 24s;
}
.l5.an {
animation: tae 1s;
animation-duration: 8s;
animation-fill-mode: alternate;
animation-delay: 29s;
}
#keyframes tae {
0% {background: initial;}
30% {background: blue;}
60% {background: blue;}
100% {background: initial;}
}
<body>
<audio id="ad">
<source src = "pup.mp3" type="audio/mp3">
</audio>
<script type="text/javascript">
var song = document.getElementById("ad");
function togglePlay() {
song.play();
document.getElementByClassName("an").style.animationPlayState = "running"; //this is what I'm currently using in play button
}
function togglePause() {
song.pause();
document.getElementByClassName("an").style.animationPlayState = "paused"; //this is for the pause button
}
</script>
<div class="bg"></div>
<div class="bg-box">
<img src="PUPLogo.png">
<p class="PUP">Polytechnic University of the Philippines</p>
<h1>PUP HYMN</h1>
<p class="lyrics">
<div class="l1 an">Sintang Paaralan</div>
<div class="l2 an">Tanglaw ka ng bayan</div>
<div class="l3 an">Pandayan ng isip ng kabataan</div>
<div class="l4 an">Kami ay dumating nang salat sa yaman<br></div>
<div class="l5 an">Hanap na dunong ay iyong alay<br></div>
<!--I cut the lyrics here to make it shorter-->
<input type="button" value="Play" onclick="togglePlay()" class="but" ></input>
<input type="button" value="Pause" onclick="togglePause()" class="but"></input>
</div>
</body>
</html>
First there is type you need to use getElementsByClassName instead of getElementByClassName
The second note is that you have to loop through the elements when you select them by a class selector. So I wrote a loop on the elements with class "an":
var song = document.getElementById("ad");
function togglePlay() {
song.play();
Array.from(document.getElementsByClassName("an")).forEach(
function(element, index, array) {
element.style.animationPlayState = "running";
}
)
}
function togglePause() {
song.pause();
Array.from(document.getElementsByClassName("an")).forEach(
function(element, index, array) {
element.style.animationPlayState = "paused";
}
)
}
.lyrics {
font-weight: lighter;
font-size: 1vw;
}
.l1.an {
animation: tae 1s;
animation-direction: alternate;
animation-duration: 5s;
animation-delay: 12s;
}
.l2.an {
animation: tae 1s;
animation-duration: 5s;
animation-fill-mode: alternate;
animation-delay: 15s;
}
.l3.an {
animation: tae 1s;
animation-duration: 8s;
animation-fill-mode: alternate;
animation-delay: 18s;
}
.l4.an {
animation: tae 1s;
animation-duration: 7s;
animation-fill-mode: alternate;
animation-delay: 24s;
}
.l5.an {
animation: tae 1s;
animation-duration: 8s;
animation-fill-mode: alternate;
animation-delay: 29s;
}
#keyframes tae {
0% {background: initial;}
30% {background: blue;}
60% {background: blue;}
100% {background: initial;}
}
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="css1.css">
<meta charset="utf-8" content="width=device-width, initial-scale=1.0">
<meta http-equiv="refresh" content="106">
<title>PUP HYMN</title>
</head>
<body>
<audio id="ad">
<source src = "pup.mp3" type="audio/mp3">
</audio>
<div class="bg"></div>
<div class="bg-box">
<img src="PUPLogo.png">
<p class="PUP">Polytechnic University of the Philippines</p>
<h1>PUP HYMN</h1>
<p class="lyrics">
<div class="l1 an">Sintang Paaralan</div>
<div class="l2 an">Tanglaw ka ng bayan</div>
<div class="l3 an">Pandayan ng isip ng kabataan</div>
<div class="l4 an">Kami ay dumating nang salat sa yaman<br></div>
<div class="l5 an">Hanap na dunong ay iyong alay<br></div>
<!--I cut the lyrics here to make it shorter-->
<input type="button" value="Play" onclick="togglePlay()" class="but" ></input>
<input type="button" value="Pause" onclick="togglePause()" class="but"></input>
</div>
</body>
</html>
Use loop all of elemnt with class name an and set .style.animationPlayState to each one
also use getElementsByClassName() to get all elements with class name an
var song = document.getElementById("ad");
function togglePlay() {
song.play();
var items=document.getElementsByClassName("an");
for (var i=0; i < items.length; i++) {
items[i].style.animationPlayState = "running";
}
}
function togglePause() {
song.pause();
var items=document.getElementsByClassName("an");
for (var i=0; i < items.length; i++) {
items[i].style.animationPlayState = "paused";
}
}
.lyrics {
font-weight: lighter;
font-size: 1vw;
}
.l1.an {
animation: tae 1s;
animation-direction: alternate;
animation-duration: 5s;
animation-delay: 12s;
}
.l2.an {
animation: tae 1s;
animation-duration: 5s;
animation-fill-mode: alternate;
animation-delay: 15s;
}
.l3.an {
animation: tae 1s;
animation-duration: 8s;
animation-fill-mode: alternate;
animation-delay: 18s;
}
.l4.an {
animation: tae 1s;
animation-duration: 7s;
animation-fill-mode: alternate;
animation-delay: 24s;
}
.l5.an {
animation: tae 1s;
animation-duration: 8s;
animation-fill-mode: alternate;
animation-delay: 29s;
}
#keyframes tae {
0% {background: initial;}
30% {background: blue;}
60% {background: blue;}
100% {background: initial;}
}
<audio id="ad">
<source src = "pup.mp3" type="audio/mp3">
</audio>
<script type="text/javascript">
</script>
<div class="bg"></div>
<div class="bg-box">
<img src="PUPLogo.png">
<p class="PUP">Polytechnic University of the Philippines</p>
<h1>PUP HYMN</h1>
<p class="lyrics">
<div class="l1 an">Sintang Paaralan</div>
<div class="l2 an">Tanglaw ka ng bayan</div>
<div class="l3 an">Pandayan ng isip ng kabataan</div>
<div class="l4 an">Kami ay dumating nang salat sa yaman<br></div>
<div class="l5 an">Hanap na dunong ay iyong alay<br></div>
<!--I cut the lyrics here to make it shorter-->
<input type="button" value="Play" onclick="togglePlay()" class="but" />
<input type="button" value="Pause" onclick="togglePause()" class="but"/>
</div>
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Can anyone submit some tip how to do it? So instead of page load , it will make the animation after button click.
Therefore there is negative that every td has it's own class with own keyframe that styles it in certain time.
#-webkit-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
#-moz-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
#keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
.fade-in {
opacity:0;
-webkit-animation:fadeIn ease-in 1;
-moz-animation:fadeIn ease-in 1;
animation:fadeIn ease-in 1;
-webkit-animation-fill-mode:forwards;
-moz-animation-fill-mode:forwards;
animation-fill-mode:forwards;
-webkit-animation-duration:1s;
-moz-animation-duration:1s;
animation-duration:1s;
}
.fade-in.one {
-webkit-animation-delay: 0.7s;
-moz-animation-delay: 0.7s;
animation-delay: 1s; /* Start mezi jednotlivými elementy */
}
.fade-in.two {
-webkit-animation-delay: 0.7s;
-moz-animation-delay:0.7s;
animation-delay: 2s; /* Start mezi jednotlivými elementy */
}
.fade-in.three {
-webkit-animation-delay: 2.7s;
-moz-animation-delay: 2.7s;
animation-delay: 3s; /* Start mezi jednotlivými elementy */
</style>
<table width="100%" class="container">
<td width="33%" class="fade-in one">
<img width="100%" src="sekerko.png">
</td>
<td width="33%" class="fade-in two">
<img width="100%" src="miko.png">
</td>
<td width="33%" class="fade-in three">
<img width="100%" src="lakyrka.png">
</td>
</table>
You can use CSS animation-play-state Property. This property specifies whether the animation is running or paused.
CSS Syntax:
animation-play-state: paused | running | initial | inherit;
In JavaScript, this can be queried to determine whether or not the animation is currently running. In addition, you can use JavaScript to set its value to pause or resume playback of an animation.
Resuming a paused animation will start the animation from where it left off at the time it was paused, rather than starting over from the beginning of the animation sequence.
More information from MDN
Example:
function run() {
var list = document.getElementsByClassName( 'fade-in' );
list[0].style.animationPlayState = 'running';
list[1].style.animationPlayState = 'running';
list[2].style.animationPlayState = 'running'
}
#-webkit-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
#-moz-keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
#keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
.fade-in {
opacity: 0;
-webkit-animation: fadeIn ease-in 1;
-moz-animation: fadeIn ease-in 1;
animation: fadeIn ease-in 1;
-webkit-animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
animation-fill-mode: forwards;
-webkit-animation-duration: 1s;
-moz-animation-duration: 1s;
animation-duration: 1s;
/* Pause animation */
animation-play-state: paused
}
.fade-in.one {
-webkit-animation-delay: 0.7s;
-moz-animation-delay: 0.7s;
animation-delay: 1s /* Start mezi jednotlivými elementy */
}
.fade-in.two {
-webkit-animation-delay: 0.7s;
-moz-animation-delay:0.7s;
animation-delay: 2s /* Start mezi jednotlivými elementy */
}
.fade-in.three {
-webkit-animation-delay: 2.7s;
-moz-animation-delay: 2.7s;
animation-delay: 3s /* Start mezi jednotlivými elementy */
}
<input type="button" value="Click Me" onclick="run()"></input>
<table width="100%" class="container">
<td width="33%" class="fade-in one">
<img width="100%" src="http://www.google.com/intl/en_ALL/images/logo.gif">
</td>
<td width="33%" class="fade-in two">
<img width="100%" src="http://www.google.com/intl/en_ALL/images/logo.gif">
</td>
<td width="33%" class="fade-in three">
<img width="100%" src="http://www.google.com/intl/en_ALL/images/logo.gif">
</td>
</table>
So I have got different animations made in CSS, though the problem is that they start right away when the page loads (ofcourse). I do not want this though. Is there a way in Vanilla JavaScript to get the animation to fire up only when it is in the viewport?
I have searched in a lot of places, but I either find a plugin I need to use or jQuery.
HTML:
<div class="introduction">
<h1>I can do the following for you:</h1>
<ul>
<li>Create a custommade, new website.</li>
<li>Code a PSD template into a working website.</li>
<li>Rework an outdated website.</li>
<li>Clean up messy code of a website.</li>
</ul>
</div>
CSS:
#keyframes showOnLoad {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.introduction li {
list-style-type: none;
margin-bottom: 5px;
text-align: center;
opacity: 0;
-webkit-animation: showOnLoad;
animation: showOnLoad;
-webkit-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
.introduction li:nth-child(2) {
-webkit-animation-delay: 1s;
animation-delay: 1s;
}
.introduction li:nth-child(3) {
-webkit-animation-delay: 2s;
animation-delay: 2s;
}
.introduction li:nth-child(4) {
-webkit-animation-delay: 3s;
animation-delay: 3s;
}
This is the code you need.
window.addEventListener("scroll", onScroll);
function onScroll() {
for (var item of document.querySelectorAll(".introduction li")) {
elementVisible(item);
}
}
function elementVisible(el) {
let top = el.offsetTop;
let height = el.offsetHeight;
let bottom = top + height;
let IsOverBottom = top > (window.pageYOffset + window.innerHeight);
let IsBeforeTop = bottom < window.pageYOffset;
if (!IsOverBottom && !IsBeforeTop) {
el.classList.add("show");
}
}
And a bit of CSS
#keyframes slideIn {
0% {
opacity: 0;
transform: translateX(100%);
}
100% {
opacity: 1;
transform: translateX(0%);
}
}
.show {
animation: slideIn 5s ease-in-out;
}
This is a basic implementation but it gets you closer.
http://jsbin.com/hetapaj/1/edit?css,js,output
Thank you for reading my question
.ab {
position:absolute;left:50%;top:50%
}
.logo_img {
width:100px;
}
.logo_img:hover {
-webkit-animation: hvr 0.5s ease-out 1 0s;
-ms-animation: hvr 0.5s ease-out 1 0s;
animation: hvr 0.5s ease-out 1 0s;
}
#keyframes hvr {
0% { -webkit-transform: translateX(0px);transform: translateX(0px); }
50% { -webkit-transform: translateX(900px);transform: translateX(900px);}
51% { -webkit-transform: translateX(-900px);transform: translateX(-900px);}
100% {-webkit-transform: translateX(0px);transform: translateX(0px);}
}
<div class="ab"><img src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" class="logo_img" /></div>
Problem is when mouse goes on it, and image moves, then mouse is not on image and sometimes hover does not work!
Is there any way to do animation like this hover but if mouse is not on image... it keeps going?
Is it possible to user jQuery hover and add class on hover? And delete that class after animation ends?
You can create a container div for the image, wich always stays in the same place, and put the image inside this div. Then instead of checking, if the mouse is over the image, you can check if it is over the div.
#container {
border: 1px solid black;
}
.logo_img {
width:100px;
margin-left: calc(50% - 50px);
}
#container:hover .logo_img {
-webkit-animation: hvr 0.5s ease-out 1 0s;
-ms-animation: hvr 0.5s ease-out 1 0s;
animation: hvr 0.5s ease-out 1 0s;
}
#keyframes hvr {
0% { -webkit-transform: translateX(0px);transform: translateX(0px); }
50% { -webkit-transform: translateX(900px);transform: translateX(900px);}
51% { -webkit-transform: translateX(-900px);transform: translateX(-900px);}
100% {-webkit-transform: translateX(0px);transform: translateX(0px);}
}
<div id="container">
<img src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" class="logo_img">
</div>
var duration = 500;
$('img').mouseenter(function() {
$(this).addClass('hvr').delay(duration).queue(function() {
$(this).removeClass('hvr');
$(this).dequeue();
});
});
CODEPEN
If you mean to make animation work without hover then add this animation-iteration-count to infinite.
.logo_img {
-webkit-animation: hvr 5s ease-out;
-ms-animation: hvr 5s ease-out;
animation: hvr 5s ease-out infinite;
}
Updated another answer using jQuery,
<img src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"/>
$(document).ready(function(){
$("img").on("mouseenter",function(){
$(this).addClass("logo_img");
});
$("img").on("mouseleave",function(){
$(this).removeClass("logo_img");
});
});