Long story short, why doesn't this work? It seems to be running the setTimeout line once, but it won't repeat. It's supposed to decrease the alpha of the target element's background color by 0.1 every 500ms until it reaches zero, but by my reckoning it only makes it to 0.9 before the function stops... It's insanely simple but I can't find any info here or elsewhere which addresses something like this.
EDIT: Thanks for the answers, got it working with setInterval. CSS definitely provides a more elegant solution, but I should have mentioned that this is for an assignment in which we're supposed to use javascript instead.
function highlight(which){
var target=document.getElementById(which);
var a_value=1.0;
if(a_value<0){
return;
}
target.style.backgroundColor="rgba(255,255,0,"+a_value+")";
setTimeout(function(){target.style.backgroundColor="rgba(255,255,0,"+(a_value -= 0.1)+")";}, 500);
}
setTimeout only fires once. If you want something to keep repeating at an interval, then you should call setInterval instead. However, you should remember to cancel this repeating timer when your animation has finished.
When you call setInterval it returns a number that is essentially a handle to your timer. You can then cancel the timer later by passing this number to clearInterval().
Here's a revised function:
function highlight(which)
{
var target = document.getElementById(which);
var a_value = 1.0;
target.style.backgroundColor = "rgba(255,255,0," + a_value + ")";
let handle = setInterval(function ()
{
if (a_value < 0)
{
clearInterval(handle);
return;
}
target.style.backgroundColor = "rgba(255,255,0," + (a_value -= 0.1) + ")";
}, 500);
}
However, the comments on this question are correct in pointing out that it doesn't really make sense to do this type of animation with JavaScript anymore. You should look into CSS transitions.
If You're asking about running same code periodically so - read about setInterval, clearInterval or make a method and call setTimeout inside of function again via passing period.
But if You're asking question about how to animate somethings, so - use css animations and don't "reinvent the wheel" (:
function fadeIn(which){
document.getElementById(which).classList.add("fadeIn");
}
fadeIn('fadeitin');
function fadeOut(which){
document.getElementById(which).classList.add("fadeOut");
}
fadeOut('fadeitout');
#fadeitin {
position: absolute;
left: 0; top: 0;
width: 200px;
height: 200px;
background: #f00;
opacity: 0;
}
#fadeitout {
position: absolute;
right: 0; top: 0;
width: 200px;
height: 200px;
background: #00f;
opacity: 1;
}
#-webkit-keyframes fadeIn {
0% {opacity: 0;}
100% {opacity: 1;}
}
#keyframes fadeIn {
0% {opacity: 0;}
100% {opacity: 1;}
}
.fadeIn {
-webkit-animation-name: fadeIn;
animation-name: fadeIn;
-webkit-animation-duration: 5s;
animation-duration: 5s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
#-webkit-keyframes fadeOut {
0% {opacity: 1;}
100% {opacity: 0;}
}
#keyframes fadeOut {
0% {opacity: 1;}
100% {opacity: 0;}
}
.fadeOut {
-webkit-animation-name: fadeOut;
animation-name: fadeOut;
-webkit-animation-duration: 5s;
animation-duration: 5s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
<div id="fadeitin"></div>
<div id="fadeitout"></div>
p.s. You can use jQuery and fadeIn, fadeOut methods.
As stated, setTimeout() only counts up to the time and fires the callback function once. But, you can make it run multiple times with a recursive function call. This is sometimes preferred over setInterval() because of the performance differences between the two.
var a_value = 1.0; // Needs to be outside of function to only be used once
function highlight(which){
if(a_value < 0){ return; }
// Instead of changing only the alpha of an RGB, just change the opacity
which.style.opacity = (a_value -= 0.1);
setTimeout(function(){
highlight(which); // recursive call
}, 500);
}
highlight(document.getElementById("test"));
#test {
height:100px;
background-color:yellow;
}
<div id="test"></div>
But really, this can all be done with a CSS animation and no JavaScript:
#test {
height:100px;
background-color:yellow;
animation-name: fade;
animation-duration: 3s;
animation-iteration-count: 1;
}
#keyframes fade {
from { opacity:1; }
to { opacity:0 }
}
<div id="test"></div>
Related
I've been trying to find an answer to my problem but I haven't been able to find one.
I want to be able to clear an interval once it's done, but then be able to restart it.
My current code doesn't let me do that: once the interval stops, you can't run it again.
Here's my code:
function about() {
var about = document.getElementById("about")
about.classList.add("about-mi")
var moreinfo = setInterval (function() {
about.classList.remove("about-mi")
}, 2000)
clearInterval(moreinfo)
}
.about-mi {
animation-name: moreinfo;
animation-duration: 2s;
}
#keyframes moreinfo {
0% {color: black;}
50% {color: red; transform: translateY(-20px);}
100% {color: black;}
}
<a onclick="about()">▼</a>
<h2 id=about>About</h2>
I would prefer solutions that only require HTML, CSS, or JavaScript, but I am also open to try solutions that require jQuery.
Actually setInterval doesn't do anything here. You don't need to use interval for that, just use setTimeout.
function about() {
var about = document.getElementById("about")
about.classList.add("about-mi")
var moreinfo = setTimeout(function() {
about.classList.remove("about-mi")
}, 2000)
}
.about-mi {
animation-name: moreinfo;
animation-duration: 2s;
}
#keyframes moreinfo {
0% {
color: black;
}
50% {
color: red;
transform: translateY(-20px);
}
100% {
color: black;
}
}
<a onclick="about()">▼</a>
<h2 id=about>About</h2>
Also you can do this with only CSS
.about-mi {
animation: moreinfo 2s, reset 2.1s;
}
a:active+.about-mi {
animation: anything, reset 2.1s;
}
#keyframes moreinfo {
0% {
color: black;
}
50% {
color: red;
transform: translateY(-20px);
}
100% {
color: black;
}
}
#keyframes reset {
from,
to {
color: black;
transform: unset;
}
}
<p>Wait for the animation to finish before first clicking (2.1s). because the animation starts when the page loads.</p>
▼
<h2 id="about" class="about-mi">About</h2>
As you use the interval timeout to remove the class about-mi to match with the 2 seconds you have defined in your css with animation-duration: 2s; it gets hard to mantain when you start changing one of those values you always have to keep in mind ooooh I also have to update the other one say javascript value and css value
That given, in this case another approach is remove the class based on HTMLElement: animationend event like so:
var aboutElement = document.getElementById("about")
function about() {
aboutElement.classList.add("about-mi")
}
aboutElement.addEventListener("animationend", function(){
aboutElement.classList.remove("about-mi");
});
.about-mi {
animation-name: moreinfo;
animation-duration: 2s;
}
#keyframes moreinfo {
0% {color: black;}
50% {color: red; transform: translateY(-20px);}
100% {color: black;}
}
<a onclick="about()">▼</a>
<h2 id=about>About</h2>
In your specific case, it looks like you only need to run the code once, and not multiple times at intervals, so as #dgknca mentioned, all you need is a setTimeout.
How to restart an interval in general
Answering this in case other users comes across this post. The best you can do (as far as I'm aware) is to define a non-anonymous function with the functionality you want, and then use that in the interval:
function doSomething() {
// your logic here
console.log('I am doing something.');
}
// execute doSomething every 1 second
var interval = setInterval(doSomething, 1000);
Like so, you can cancel the interval using:
clearInterval(interval);
To "restart" the interval, you would need to assign interval to a new interval:
interval = setInterval(doSomething, 1000);
I am making a label pop up for the user, if the user tries to drag and drop an element that has already been dragged.
Problem is, that the animations only happens once, and at the end of the animation, it will have an opacity of 0 forever.
CSS
#keyframes smooth {
0% { opacity: 1;}
100% { opacity: 0;}
}
.o_tip{
position: absolute;
z-index: 999;
display: none;
opacity: 0;
-webkit-animation: smooth 2s ease-in;
-moz-animation: smooth 2s ease-in;
-o-animation: smooth 2s ease-in;
-ms-animation: smooth 2s ease-in;
animation: smooth 2s ease-in;
}
To illustrate my problem, if I 'end' the animation on opacity: 0.2 instead of opacity: 0:
#keyframes smooth {
0% { opacity: 1;}
100% { opacity: 0.2;}
}
... then the label will reappear for each event - but it will not fade out again, which I want to do.
You can put the animation rule in a specific css class rule, and then on clicking add that class again. Just keep these points in mind:
You need to remove the animation class first before adding it again to have any effect.
Even if you follow first point, removing the class and adding it back right then won't have any visual effect. To trigger reflow, you can use this statement: void targetDiv.offsetWidth;.
document.querySelector("#start-animation").onclick = function(e){
var targetDiv = document.querySelector("#mydiv");
targetDiv.className = "";
void targetDiv.offsetWidth; // this triggers UI reflow
targetDiv.classList.add("o_tip");
}//onclick
#keyframes smooth {
0% { opacity: 1;}
100% { opacity: 0;}
}
.o_tip{
z-index: 999;
animation: smooth 2s ease-in forwards;
}
#mydiv{
background-color: yellow;
height: 50px;
width: 100px;
}
#mydiv.o_top{
display: block;
}
<div id="mydiv"></div>
<button id="start-animation">Start animation</button>
I am making an photography website and i am stuck. I am looking for somebody to rescue me.
My problem is the next one : I wanna translate the next code from CSS into javascript.
img#image {
margin: 0px;
background-repeat: none;
background-size: 100% 100%;
}
#-webkit-keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
#keyframes fade {
from {opacity: .4}
to {opacity: 1}
}
I have'd made until now :
function Rotate(randomImage) {
document.getElementById('image').src = randomImage;
document.getElementById('image').setAttribute("style","height: 100%; width: 100%; position:relative; z-index:-1; -webkit-animation-name: fade;-webkit-animation-duration: 1.5s;animation-name: fade;animation-duration: 1.5s;");
}
I need to add #-webkit-keyframes fade and #keyframes fade to my javascript code. Thank you !
There are better ways then using JS, however you can use the following :
<div id ="myImg" style="width:100px;height:100px;background:blue;"></div>
<script>
function fadeIn(from,to,duration) {
var elem = document.getElementById("myImg");
var step = (to-from)/duration;
var opacity = from;
var id = setInterval(frameFade, 5);
function frameFade() {
if (opacity >= to) {
clearInterval(id);
} else {
opacity+=step;
elem.style.opacity = opacity;
elem.innerHtml = opacity;
}
}
}
fadeIn(0.4,1.0,500);
</script>
plunker example
If you need a Dom animation use like this
document.getElementById('image').animation='fade 1.5s'
document.getElementById('image').WebkitAnimation='fade 1.5s'
For changing more number of style Better use with classList.add() for pure javascript
function Rotate(randomImage) {
document.getElementById('image').src = randomImage;
document.getElementById('image').classList.add('animation_class')
}
For jquery addClass()
function Rotate(randomImage){
$('img').attr('src',randomImage).addClass('animation_class')
}
Css
.animation_class {
height: 100%;
width: 100%;
position: relative;
z-index: -1;
-webkit-animation-name: fade;
-webkit-animation-duration: 1.5s;
animation-name: fade;
animation-duration: 1.5s;
}
I want to fade in all boxes at my site . But not like it works already. I want that first the last box fades in and then is moving down by the info box etc. so the boxes appears after each other.
The fadein effect is currently made with:
.content {
-webkit-animation: fadein 3s;
-moz-animation: fadein 3s;
-ms-animation: fadein 3s;
-o-animation: fadein 3s;
animation: fadein 3s;
background: rgba(49,54,59,0.8);
*zoom: 1;
}
#keyframes fadein {
0% { opacity: 0; }
75% { opacity: 0.3; }
100% { opacity: 1; }
}
#-moz-keyframes fadein {
0% { opacity: 0; }
100% { opacity: 1; }
}
#-webkit-keyframes fadein {
0% { opacity: 0; }
100% { opacity: 1; }
}
#-o-keyframes fadein {
0% { opacity: 0; }
100% { opacity: 1; }
}
It is possible to use jQuery, JavaScript and Css.
I hope you'll ahve a solution.
The jQuery fadeIn function (and most animations) has a "complete" option. You can pass another animation call to it and chain them in order to achieve the proper order.
For instance, you can do:
$( "#box1" ).fadeIn( "slow", function() {
// Animation complete
$( "#box2" ).fadeIn( "slow", function() {
// Animation complete
});
});
You can use animation-delay to delay the animations so the boxes fade one after another.
div {
/* Will cause animation to start after 2 second delay */
-webkit-animation-delay: 2s;
animation-delay: 2s;
}
Best solution:
<script type="text/javascript">
$(document).ready(function() {
$(".content:hidden:last").delay(500).slideDown(1000, function() {
$(".content:hidden:last").delay(500).slideDown(1000, function() {
$(".content:hidden:last").delay(500).slideDown(1000, function() {
//nothing
});
});
});
});
</script>
For fading just replace slideDown with fadeIn
You can do this with just css using something like stagger.css
http://digitalfio.github.io/Stagger.css/
Include the css file in your <head>, apply the animation classes to each div then add a timing class to each div in the form of an underscore followed by an incrementing number - e.g.
<div class="animated slideIn _1"></div>
<div class="animated slideIn _2"></div>
<div class="animated slideIn _3"></div>
<div class="animated slideIn _4"></div>
so you get something like this: http://output.jsbin.com/cusuz/4
I'm working on a game and just found out about -webkit-animation-play-state CSS attribute. I want certain text to show itself as a short animation, then hide and show when called again (in javascript).
I figured out how to start animation when I want to in javascript, but after its finished, the text stays on the screen, which I don't want to.
HTML:
<p id="INFO">
TEST
</p>
CSS:
#-webkit-keyframes pulse {
from {
opacity: 0.0;
font-size: 100%;
}
to {
opacity: 1.0;
font-size: 400%;
}
}
#INFO {
position: absolute;
left: 400px;
top: 200px;
-webkit-animation-name: pulse;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-play-state:paused;
visibility: hidden;
}
JS:
var INFO = document.getElementById("INFO");
INFO.innerHTML = "WRONG";
INFO.style.color = "RED";
INFO.style.webkitAnimationPlayState = "running";
INFO.style.visibility = "visible";
I read some questions/answers about -webkit-animation-play-state on this site, but none regarding the issue I am having.
One thing I read about was that animation goes to its default values when its ended. But my default values say that animation is "hidden" ? source: how to stop my webkit frame animation?
If anyone can point me in the right direction I'd be grateful.
If I was not clear enough, ask for more info please.
Thank you
For what you are trying to do, you don't need to use -webkit-animation-play-state.
Instead, try starting the animation by applying a class with the animation properties set. Then use a JavaScript event listener to remove the class once the animation finishes.
You should also keep the element hidden with opacity instead of visibility:hidden since you are manipulating the opacity in the animation.
CSS:
#-webkit-keyframes pulse {
from {
opacity: 0.0;
font-size: 100%;
}
to {
opacity: 1.0;
font-size: 400%;
}
}
#INFO {
opacity:0;
position: absolute;
left: 400px;
top: 200px;
}
.pulse {
-webkit-animation-name: pulse;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in-out;
}
JS:
var INFO = document.getElementById("INFO");
INFO.innerHTML = "WRONG";
INFO.style.color = "RED";
INFO.addEventListener('webkitAnimationEnd', function (e) {
this.classList.remove('pulse');
});
DEMO >> CodePen