I want to create simple text animation. When i click a button, text shifts from fully transparent to fully visible and reverts to transparent. I wrote code that does the animation but only once. The animation doesn't work anymore every time when i click the button:
function animation() {
$("span").removeClass("opacity-effect");
$("span").addClass("opacity-effect");
}
span{
opacity: 0;
}
.opacity-effect {
animation-name: animate-opacity-effect;
animation-duration: 1400ms;
animation-fill-mode: forwards;
opacity: 0;
}
#keyframes animate-opacity-effect {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span>Hello World!</span>
<button onClick="animation()">
Start animation
</button>
The animation does not repeat, because for animation to start CSS requires a frame when there was no class.
So, to solve this, you should delay adding class to the next frame
function animation() {
$("span").removeClass("opacity-effect");
requestAnimationFrame(()=>{
$("span").addClass("opacity-effect");
});
}
You need to reset the animation. There is a good and correct way to do this, using event animationend. In this event, you need to put the removal of the class opacity-effect.
function animation() {
$("span").addClass("opacity-effect");
$("span").on("animationend", function() {
$(this).removeClass("opacity-effect");
});
}
span {
opacity: 0;
}
.opacity-effect {
animation-name: animate-opacity-effect;
animation-duration: 1400ms;
animation-fill-mode: forwards;
opacity: 0;
}
#keyframes animate-opacity-effect {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span>Hello World!</span>
<button onClick="animation()">
Start animation
</button>
You need to add a small delay between the removeClass and the addClass. This can be done in two ways:
With a setTimeout
function animation() {
$("span").removeClass("opacity-effect")
setTimeout(() => {
$("span").addClass("opacity-effect");
}, 0);
}
span{
opacity: 0;
}
.opacity-effect {
animation-name: animate-opacity-effect;
animation-duration: 1400ms;
animation-fill-mode: forwards;
}
#keyframes animate-opacity-effect {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span>Hello World!</span>
<button onClick="animation()">
Start animation
</button>
With a cloning
function animation() {
const newEl = $("span").removeClass("opacity-effect").clone(true);
$("span").before(newEl);
$("span:last").remove();
newEl.addClass("opacity-effect");
}
span{
opacity: 0;
}
.opacity-effect {
animation-name: animate-opacity-effect;
animation-duration: 1400ms;
animation-fill-mode: forwards;
}
#keyframes animate-opacity-effect {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span>Hello World!</span>
<button onClick="animation()">
Start animation
</button>
$('span').addClass('opacity-effect');
setTimeout(function(){
$('span').removeClass('opacity-effect');
}, 1400);
Try this
1400 is your animation duration time
<!DOCTYPE html>
<html lang="en">
<head>
<title>Dropdown value from database</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
span{
opacity: 0;
}
.opacity-effect {
opacity: 0;
-webkit-animation: animate-opacity-effect 1400ms infinite;
-moz-animation: animate-opacity-effect 1400ms infinite;
-o-animation: animate-opacity-effect 1400ms infinite;
animation: animate-opacity-effect 1400ms infinite;
}
#keyframes animate-opacity-effect {
0% { opacity:1; }
50% { opacity:0; }
100% { opacity:1; }
}
#-o-keyframes animate-opacity-effect {
0% { opacity:1; }
50% { opacity:0; }
100% { opacity:1; }
}
#-moz-keyframes animate-opacity-effect {
0% { opacity:1; }
50% { opacity:0; }
100% { opacity:1; }
}
#-webkit-keyframes animate-opacity-effect {
0% { opacity:1; }
50% { opacity:0; }
100% { opacity:1; }
}
</style>
</head>
<body>
<span>Hello World!</span>
<button onClick="animation()">
Start animation
</button>
<script>
function animation() {
$("span").removeClass("opacity-effect");
$("span").addClass("opacity-effect");
}
</script>
</body>
</html>
Related
I am using keyframes but my h1 is not visible on button click. What am I doing wrong?
Here is my code:
function abc() {
document.querySelector('.h1cls').classList.add('fadeIn')
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.fadeIn {
animation-name: fadeIn;
animation-duration: 150ms;
animation-timing-function: linear;
animation-delay: 5000ms;
/*opacity:1;*/
}
.one .two .h1cls {
opacity: 0;
}
<div class="one">
<div class="two">
<h1 class="h1cls">hello</h1>
<div></div>
</div>
</div>
<button onclick="abc()">asd</button>
https://codesandbox.io/s/serene-lamport-12kgz?file=/index.html:0-994
actually I am using opacity . I am setting opacity to 1 after button click.
In your abc() function, you should also remove h1cls class due to the fact that it still applies opacity: 0 style.
function abc(){
document.querySelector('.h1cls').classList.add('fadeIn')
document.querySelector('.h1cls').classList.remove('h1cls')
}
It is animating but then disappearing immediately. You need to tell the system to keep the final state of the animation. You do this with animation-fill-mode: forwards
Note that the animation will only run on the first click of the button.
You have to add animation-fill-mode:forwards; property too in the fadeClass in order to make this work
function abc() {
document.querySelector('.h1cls').classList.add('fadeIn')
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.fadeIn {
animation-name: fadeIn;
animation-duration: 150ms;
animation-timing-function: linear;
/*animation-delay: 5000ms;*/
animation-fill-mode:forwards; // add this line
/*opacity:1;*/
}
.one .two .h1cls {
opacity: 0;
}
<div class="one">
<div class="two">
<h1 class="h1cls">hello</h1>
<div></div>
<button onclick="abc()">asd</button>
you can used the toggle class and transition
function abc() {
document.querySelector('.h1cls').classList.toggle('fadeIn')
}
.one .two .h1cls {
transition: opacity 150ms linear;
opacity: 0;
}
.one .two .h1cls.fadeIn {
opacity:1;
}
<div class="one">
<div class="two">
<h1 class="h1cls">hello</h1>
<div></div>
<button onclick="abc()">asd</button>
</div>
</div>
or with animation
function abc() {
document.querySelector('.h1cls').classList.toggle('fadeIn')
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.one .two .h1cls {
opacity: 0;
}
.one .two .h1cls.fadeIn {
animation-name: fadeIn;
animation-duration: 150ms;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
<div class="one">
<div class="two">
<h1 class="h1cls">hello</h1>
<div></div>
<button onclick="abc()">asd</button>
</div>
</div>
You've missed animation-fill-mode property in fadeIn CSS class.
Correct code:
.fadeIn {
animation-name: fadeIn;
animation-duration: 150ms;
animation-timing-function: linear;
animation-delay: 5000ms;
animation-fill-mode: forwards;
}
Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/animation-fill-mode
When we click on button it just adding class fadeIn and this class will animate from opacity 0 to opacity 1. But after animation completed it will again hide, so add opacity:1!important in .fadeIn class property.
In simple way just add opacity:1!important in fadeIn css property.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Static Template</title>
<style>
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.fadeIn {
animation-name: fadeIn;
animation-duration: 150ms;
animation-timing-function: linear;
animation-delay: 5000ms;
opacity:1 !important;
}
.one .two .h1cls {
opacity: 0;
}
</style>
</head>
<body>
<div class="one">
<div class="two">
<h1 class="h1cls">hello</h1>
<div>
</div>
<button onclick="abc()">asd</button>
<script>
function abc(){
document.querySelector('.h1cls').classList.add('fadeIn')
}
</script>
</body>
</html>
I have a heading <h1>I am Heading</h1> with animation properties and I want to display my <p>I am Paragraph</p> to display after heading fully loaded
Attach an animationend event listener to the h1 that shows the paragraph element in 5000 milliseconds with setTimeout:
const heading = document.querySelector('h1');
const paragraph = document.querySelector('p');
heading.addEventListener('animationend', function() {
console.log('showing paragraph in 5 seconds')
setTimeout(() => {
paragraph.style.display = "block"
}, 5000)
})
h1 {
animation: fadeIn 2s forwards;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
p {
display: none;
}
<h1>I am Heading</h1>
<p>I am Paragraph</p>
Try this. setTimeout() method can execute a piece of code after a certain amount of time has passed.
<!DOCTYPE html>
<html>
<head>
<title>CSS</title>
</head>
<body>
<h1>Hello</h1>
<p id="para">Hey this is saruque</p>
<style>
#keyframes show {
from{
opacity: 0;
}
to{
opacity: 1;
}
}
h1{
animation: show 5s forwards;
}
#para{
visibility: hidden;
}
</style>
<script>
setTimeout(function(params) {
document.getElementById('para').style.visibility = 'visible'
}, 5200);
</script>
</body>
</html>
You can add a delay to your animation:
p {
opacity: 0;
animation-name: fadeIn;
animation-duration: .4s;
animation-fill-mode: forwards;
animation-delay: 5s;
}
#keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
This is my animation:
.ani span {
animation: animation 1s infinite;
display: inline-table;
}
#keyframes animation {
0% {
transform: translateY(0px);
}
33.333% {
transform: translateY(-5px);
}
66.666% {
transform: translateY(5px);
}
100% {
transform: translateY(0px);
}
}
.ani span:nth-child(1) {
animation-delay: .1s;
}
.ani span:nth-child(2) {
animation-delay: .2s;
}
.ani span:nth-child(3) {
animation-delay: .3s;
}
.ani span:nth-child(4) {
animation-delay: .4s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="ani"><span>h</span><span>e</span><span>l</span><span>l</span><span>o</span></div>
I will have different texts (not only »hello«) that should have this animation. So it would be great to have it as jQuery function. There should be calculated the text length, automatically placed <span></span>, and a fitting animation-delay.
How is it possible to code that?
Would be sooooo thankful for help.
You could do it like this:
var div, aniDivs, i,j;
aniDivs = document.querySelectorAll("div.ani");
for (var i = 0, len = aniDivs.length; i < len; i++) {
div = document.querySelectorAll("div.ani")[i];
let span = "";
for (j = 0; j < div.innerText.length; j++) {
if (div.innerText[j] !== " ") {
span += "<span style='animation-delay:." + (j + 1) + "s'>";
span += div.innerText[j];
span += "</span>";
}
}
div.innerHTML = span;
}
.ani span {
animation: animation 1s infinite;
display: inline-table;
}
#keyframes animation {
0% {
transform: translateY(0px);
}
33.333% {
transform: translateY(-5px);
}
66.666% {
transform: translateY(5px);
}
100% {
transform: translateY(0px);
}
}
.ani span:nth-child(1) {
animation-delay: .1s;
}
.ani span:nth-child(2) {
animation-delay: .2s;
}
.ani span:nth-child(3) {
animation-delay: .3s;
}
.ani span:nth-child(4) {
animation-delay: .4s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="ani">Welcome</div>
<div class="ani">again</div>
For this answer I incorporated this answer How to wrap each character from a string in spans given by Danny Fardy Jhonston Bermúdez.
This should work for string of arbitrary length
$aniDivs = $('.ani'); // collect all the divs that have 'ani' class
//loop over each
$aniDivs.each(function(divIndex, div){
//HTML part
var divTxt = $(div).text();
// get the text that's inside the ani div (ie. "hello" )
var lettersArr = divTxt.split('');
// make an array of letters that constitute the word (ie. ["h", "e", "l", "l", "o"] )
var spanContent = '';
// a bucket to hold the spans that we create dynamically
$.each(lettersArr, function(letterIndex, letter){
spanContent+= '<span>'+letter+'</span>';
});
// Now we have <span>h</span><span>e</span><span>l</span><span>l</span><span>o</span>
$(div).html(spanContent);
// put it inside current ani <div>
//CSS part
var delay = 0.1;
//now we collect the the <spans> that we just created and appended and increment the animation-delay in a progression
$(div).find('span').each(function(spanIndex,span){
$(span).css('animation-delay', delay.toFixed(1)+'s' );
delay=delay+0.1; // displace every subsequent div to .1 second from previous
});
});
.ani span {
animation: animation 1s infinite;
display: inline-table;
}
#keyframes animation {
0% {
transform: translateY(0px);
}
33.333% {
transform: translateY(-5px);
}
66.666% {
transform: translateY(5px);
}
100% {
transform: translateY(0px);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="ani">Lopadotemachoselachogaleokranioleipsanodrimhypotrimmatosilphioparaomelitokatakechymenokichlepikossyphophattoperisteralektryonoptekephalliokigklopeleiolagoiosiraiobaphetraganopterygon</div>
I'm trying to make element dissapear at the end of animation but it doesn't work, can someone explain how to make exit animation with element dissappearing at the end of it?:
var test = document.getElementById("test");
test.addEventListener("click", displayOpacity);
function displayOpacity(event){
event.target.style.animation = "changeOpacity 1s linear";
if(event.target.style.opacity === 0){
event.target.style.display = "none";
}
}
.container .test {
text-align: center;
padding: 100px;
color: #fff;
background-color: #00f;
max-width: 500px;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
#-webkit-keyframes changeOpacity {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
#keyframes changeOpacity {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
<body>
<div class="container">
<div class="test" id="test">Custom Text</div>
</div>
<script src="main.js"></script>
</body>
Since you have tagged jQuery, wouldn't be it easier to do it with .fadeOut()? The display attribute of the element is being set to none just after the animation has ended.
$('#test').click(function(){
$(this).fadeOut();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='test'>Text</div>
Your issue is because the animation-fill-mode is not being respected as you're overwriting it by setting the animation rule directly on the element itself.
To fix this change your JS code to add a class on the element, and put the animation rule in there, along with the required fill mode:
var test = document.getElementById("test");
test.addEventListener("click", displayOpacity);
function displayOpacity(event) {
this.classList.add('changeOpacity');
}
.container .test {
text-align: center;
padding: 100px;
color: #fff;
background-color: #00f;
max-width: 500px;
}
.changeOpacity {
animation: changeOpacity 1s linear forwards;
}
#-webkit-keyframes changeOpacity {
0% { opacity: 1; }
100% { opacity: 0; }
}
#-webkit-keyframes changeOpacity {
0% { opacity: 1; }
100% { opacity: 0; }
}
#keyframes changeOpacity {
0% { opacity: 1; }
100% { opacity: 0; }
}
<div class="container">
<div id="test" class="test">
Test
</div>
</div>
The animation time is 1 second
event.target.style.animation = "changeOpacity 1s linear";
so just make a timeout
setTimeout(function(){
event.target.style.display = "none";
},1000)
How can I get a CSS Animation to play with a JavaScript onClick? I currently have:
.classname {
-webkit-animation-name: cssAnimation;
-webkit-animation-duration:3s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease;
-webkit-animation-fill-mode: forwards;
}
#-webkit-keyframes cssAnimation {
from {
-webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(100px);
}
to {
-webkit-transform: rotate(0deg) scale(2) skew(0deg) translate(100px);
}
}
How can I apply an onClick?
Are you sure you only display your page on webkit? Here is the code, passed on safari.
The image (id='img') will rotate after button click.
function ani() {
document.getElementById('img').className = 'classname';
}
.classname {
-webkit-animation-name: cssAnimation;
-webkit-animation-duration: 3s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease;
-webkit-animation-fill-mode: forwards;
}
#-webkit-keyframes cssAnimation {
from {
-webkit-transform: rotate(0deg) scale(1) skew(0deg) translate(100px);
}
to {
-webkit-transform: rotate(0deg) scale(2) skew(0deg) translate(100px);
}
}
<input name="" type="button" onclick="ani()" value="Click">
<img id="img" src="https://i.stack.imgur.com/vghKS.png" width="328" height="328" />
You just use the :active pseudo-class. This is set when you click on any element.
.classname:active {
/* animation css */
}
Found solution on css-tricks
const element = document.getElementById('img')
element.classList.remove('classname'); // reset animation
void element.offsetWidth; // trigger reflow
element.classList.add('classname'); // start animation
You can achieve this by binding an onclick listener and then adding the animate class like this:
$('#button').onClick(function(){
$('#target_element').addClass('animate_class_name');
});
CSS ONLY solution that works on every click and plays the animation to the end:
All you have to do is to add the animation to the :focus pseudo class and set it to none in :active pseudo class.
If your element isn't focusable add tabindex="0" attribute to the html element:
#keyframes beat {
0% {
-webkit-transform: scale(1, 1);
transform: scale(1, 1);
}
100% {
-webkit-transform: scale(0.8,0.8);
transform: scale(0.8, 0.8);
}
}
.className {
background-color:#07d;
color: #fff;
font-family: sans-serif;
font-size: 20px;
padding: 20px;
margin:5px;
-webkit-transform: scale(1, 1);
transform: scale(1, 1);
}
.className:focus {
-webkit-animation: beat 1s ease-in-out backwards;
animation: beat 1s ease-in-out backwards;
}
.className:active {
-webkit-animation: none;
animation: none;
}
body {
text-align: center;
}
<h3>Any element with tabindex="0", like a div:</h3>
<div tabindex="0" class="className"> Click me many times!</div>
<h3>Any focusable element like a button:</h3>
<button class="className"> Click me many times!</button>
var abox = document.getElementsByClassName("box")[0];
function allmove(){
abox.classList.remove("move-ltr");
abox.classList.remove("move-ttb");
abox.classList.toggle("move");
}
function ltr(){
abox.classList.remove("move");
abox.classList.remove("move-ttb");
abox.classList.toggle("move-ltr");
}
function ttb(){
abox.classList.remove("move-ltr");
abox.classList.remove("move");
abox.classList.toggle("move-ttb");
}
.box {
width: 100px;
height: 100px;
background: red;
position: relative;
}
.move{
-webkit-animation: moveall 5s;
animation: moveall 5s;
}
.move-ltr{
-webkit-animation: moveltr 5s;
animation: moveltr 5s;
}
.move-ttb{
-webkit-animation: movettb 5s;
animation: movettb 5s;
}
#keyframes moveall {
0% {left: 0px; top: 0px;}
25% {left: 200px; top: 0px;}
50% {left: 200px; top: 200px;}
75% {left: 0px; top: 200px;}
100% {left: 0px; top: 0px;}
}
#keyframes moveltr {
0% { left: 0px; top: 0px;}
50% {left: 200px; top: 0px;}
100% {left: 0px; top: 0px;}
}
#keyframes movettb {
0% {left: 0px; top: 0px;}
50% {top: 200px;left: 0px;}
100% {left: 0px; top: 0px;}
}
<div class="box"></div>
<button onclick="allmove()">click</button>
<button onclick="ltr()">click</button>
<button onclick="ttb()">click</button>
Add a
-webkit-animation-play-state: paused;
to your CSS file, then you can control whether the animation is running or not by using this JS line:
document.getElementById("myDIV").style.WebkitAnimationPlayState = "running";
if you want the animation to run once, every time you click. Remember to set
-webkit-animation-iteration-count: 1;
You can do that by using following code
$('#button_id').on('click', function(){
$('#element_want_to_target').addClass('.animation_class');});
Try this:
<div>
<p onclick="startAnimation()">Start</p><!--O botão para iniciar (start)-->
<div id="animation">Hello!</div> <!--O elemento que você quer animar-->
</div>
<style>
#keyframes animationName {
from {margin-left:-30%;}
}
</style>
<script>
function startAnimation() {
document.getElementById("animation").style.animation = "animationName 2s linear 1";
}
</script>
Add the animation and remove it after the animation-duration ends using setTimeout()
const elem = document.querySelector(".element");
elem.onclick = () => {
elem.style.animation="YOUR_ANIMATION";
setTimeout(()=>{
elem.style.animation="none";
},YOUR_ANIMATION_DURATION);
}