Add text with js after animation ends - javascript

I'm trying to add a text (that is a countdown ) made with JS that works, but only after another text (made with JS) has finished it's animation, but I'm struggling with it.
I've tried some methods but nothing worked for me, I'm new but I'm a quick learner.
Can someone help me out?
Here is a part of my code:
HTML
// Set the date we're counting down to
var countDownDate = new Date("Feb 1, 2019 11:59:20").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Display the result in the element with id="countdown"
document.getElementById("countdown").innerHTML = days + " days left " + hours + "h "
+ minutes + "m " + seconds + "s ";
// Add text to <h1 id="fade">
var comingSoon = document.getElementById("fade");
comingSoon.innerHTML = 'COMING SOON';
// If the count down is finished, write some text
if (distance < 0) {
clearInterval(x);
//document.getElementById("countdown").innerHTML = "Well.. what are you waiting for?";
// If countdown finished, remove the <p id="countdown">
var parent = document.getElementById("comingSoonContainer");
var child = document.getElementById("countdown");
parent.removeChild(child);
// Create new <p> with text
var para = document.createElement("p");
var node = document.createTextNode("New Paragraph works fine.");
para.appendChild(node);
var element = document.getElementById("comingSoonContainer");
element.appendChild(para);
// Replace <h1> with text
para = document.createElement("h1");
node = document.createTextNode("Enjoooooy !!");
para.appendChild(node);
parent = document.getElementById("comingSoonContainer");
child = document.getElementById("fade");
parent.replaceChild(para, child);
//document.getElementById("fade").innerHTML = "Enjoy !!";
}
}, 1000);
#countdown {
font-family: 'Raleway', sans-serif;
font-size: /*1.3em;*/ 3em;
color: #ffffff;
/*including fade animation*/
-webkit-animation-name: fade;
-webkit-animation-duration: 12s;
animation-name: fade;
animation-duration: 12s;
}
/* Fade animation */
#fade {
-webkit-animation-name: fade;
-webkit-animation-duration: 8s;
animation-name: fade;
animation-duration: 8s;
}
#-webkit-keyframes fade {
from {opacity: .0}
to {opacity: 1}
}
#keyframes fade {
from {opacity: .0}
to {opacity: 1}
}
<div id="comingSoonContainer">
<h1 id="fade"></h1>
<p id="countdown"></p>
</div>
Thanks

UPDATE:
First, the problem is with your CSS styles for the countdown paragraph . You set the paragraph color to white and since your body is white as well, that's why you never see the countdown. But if you change the color to black for instance, you'll see your countdown.
Second, I added an animationend event to your fade element and put the setInterval inside it.
Here is the CSS you need to change:
#countdown {
font-family: 'Raleway', sans-serif;
font-size: /*1.3em;*/ 3em;
color: #000; // Color was #ffffff
/*including fade animation*/
-webkit-animation-name: fade;
-webkit-animation-duration: 12s;
animation-name: fade;
animation-duration: 12s;
}
And here is the javascript:
// Set the date we're counting down to
var countDownDate = new Date("Feb 1, 2019 11:59:20").getTime();
// Add text to <h1 id="fade">
var comingSoon = document.getElementById("fade");
comingSoon.innerHTML = 'COMING SOON';
comingSoon.addEventListener('animationend', ()=>{
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date().getTime();
// Find the distance between now and the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Display the result in the element with id="countdown"
document.getElementById("countdown").innerHTML = days + " days left " + hours + "h "
+ minutes + "m " + seconds + "s ";
});
});
I removed the part where you check for distance just because it had nothing to do with what you asked for help. You can add it though.
But here is the working fiddle
https://jsfiddle.net/fwxL1sj4/33/

There is animation callbacks:
function callFunction(){
}
var element=document.getElementById('fade');
element.addEventListener("webkitAnimationEnd", callfunction,false);
element.addEventListener("animationend", callfunction,false);
element.addEventListener("onaimationend", callfunction,false);

Related

why my animation doesn't apply everywhere?

I want to apply an animation to multiple items using a keyframe and the javascript animation method so that when the timer goes to 0 on each individual timer it will flash yellow , I have 12 in total:
const allAreas = [
createArea('area-1', 60 * 60),
createArea('area-2', 10* 60),
createArea('area-3', 10 * 60),
createArea('area-4', 10* 60),
createArea('area-5', 40* 60),
createArea('area-6', 50 * 60),
createArea('area-7', 90 * 60),
createArea('area-8', 20 * 60),
createArea('area-9', 30 * 60),
createArea('area-10', 90 * 60),
createArea('area-12', 120 * 60),
];
function updateTimer() {
let uiBarContainer = document.querySelector('.area-wrapper');
for (const area of allAreas) {
const time = area.getTime()
if (time > 0) {
area.setTime(time - elapsedSecondsPerInterval);
if (area.getTime() === 0) {
area.ui.time.innerHTML = "Finished"
uiBarContainer.style.animation="timeOut 4s linear infinite";
//if the timer gets to 0, the areawrapper will flash yellow.
}
CSS
#keyframes timeOut {
0% { background-color: FFFF80; -webkit-box-shadow: 0 0 3px FFFF80; }
50% { background-color: E6E600; -webkit-box-shadow: 0 0 10px E6E600; }
100% { background-color: FFFF80; -webkit-box-shadow: 0 0 3px FFFF80; }
}
HTML
<div class="area-wrapper">
<div class="area-1-timer">
<span id="time-area-1"></span>
</div>
</div>
at the moment it only flashes yellow in one of the 12 areas, or if one of the timers goes to 0 in any area, it will only flash in the first area, how can I fix this?

How to pass element to anonymus function in jquery?

I'm creating a countdown element and I want to pass each element to setinterval function to update it each second
var countDownDate = new Date($(this).data('date')).getTime();
setInterval(function() {
var now = new Date().getTime();
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
$(this).find('.days').text(days);
$(this).find('.hours').text(hours);
$(this).find('.minutes').text(minutes);
$(this).find('.seconds').text(seconds);
}, 1000);
});
thanks in advance
Your questions don't describe what you really wanted, but there are a few ways to access these elements inside the function.
Using an arrow function
setInterval(() => {
/*
your code goes here without changes
*/
}, 1000)
Passing parameters
setInterval(function(days, hours, minutes, seconds) {
/*
your code goes here without changes
*/
days.text(days);
hours.text(hours);
minutes.text(minutes);
seconds.text(seconds);
}, 1000, $(this).find('.days'), $(this).find('.hours'), $(this).find('.minutes'), $(this).find('.seconds'))
Binding
setInterval((function() {
/*
your code goes here without changes
*/
}).bind(this), 1000)
You could just also pass this as an argument.
I would use the arrow function since it's a more modern approach.

JavaScript Analog Clock

I was creating a Analog Clock using javascript for practice and went through a code but I am not able to understand why we need to divide second by 60, min+sec/60 and and hour+min/12 could you please make me understand how this algorithm works? my code is
const hour = document.getElementById('hour');
const minute = document.getElementById('minute');
const second = document.getElementById('second');
setInterval(updateClock,1000);
function updateClock() {
let date = new Date()
let sec = date.getSeconds()/60
let min = (date.getMinutes() + sec) / 60;
let hr = (date.getHours() + min) / 12;
hour.style.transform = "rotate(" + (hr * 360) + "deg)";
minute.style.transform ="rotate(" + (min * 360) + "deg)";
second.style.transform = "rotate(" + (sec * 360) + "deg)";
}
updateClock()
You basically divide date.getSeconds() by 60 so that you can add it easier to minutes. A better solution would be this:
const hour = document.getElementById('hour');
const minute = document.getElementById('minute');
const second = document.getElementById('second');
setInterval(updateClock);
function updateClock() {
let date = new Date()
let sec = date.getSeconds()
let min = date.getMinutes() + sec/60;
let hr = date.getHours() + min/60; // you could also add + sec/3600 but that would barely make any difference
hour.style.transform = `rotate(${hr * 30}deg)`;
minute.style.transform =`rotate(${min * 6}deg)`;
second.style.transform = `rotate(${sec * 6}deg)`;
}
This gets rid of the bad division that is actually pretty useless as it's only used once.
The multiplication at the end (hr * 30, min*6 and sec*6) are pretty straight-forward. Degrees goes from 0 to 360, but mins and secs only go from 0 to 60. So we multiply them by 6.
Hours go from 0 to 12 so we multiply them by 30.
Also you don't need to call updateClock() at the bottom as it is in the interval.
At the end you should call your interval more often than every second. You can just remove the number so it will be as fast as possible. Or use 100 to make it 1/10th of a second accurate.
Hope I could help you.
You have your circle, which has 360 degrees in total. The algorithm you have calculates how much degrees it should turn to show the correct time by dividing the current amount of seconds by the total amount of seconds in a minute. For example.
const currentSeconds = 45;
const totalSecondsInMinute = 60;
currentSeconds / totalSecondsInMinute;
// Result should be 0.75
The example here says we currently have 45 seconds, which is 0.75 or 75% of a minute. This number will indicate how much the seconds pointer on the clock must turn in degrees.
const secondHandPosition = 360 * 0.75;
// Result should be 270
So at 45 seconds the second hand position should be at 270 degrees on the clock. And the same applies to the minute and hour position.

jquery date difference trouble

I made this little function from code snippets around the net. It does what its expected to do except that it decreased by 2 seconds every countdown tick instead of one, if i refresh the page it goes back to the original time again. Can you guys see what the problem is?
jQuery.countdown = function(selector, datevalue) {
var amount = datevalue*1000;
var curdate = new Date();
curdate = curdate.getTime();
var difference = amount - curdate;
if(amount < 0 || curdate >= amount){
$(selector).html("Done");
}
else{
datevalue--;
var daysRemaining = Math.floor(difference / 1000 / 60 / 60 / 24);
var hoursRemaining = Math.floor(difference / 1000 / 60 / 60 - (24 * daysRemaining));
var minutesRemaining = Math.floor(difference / 1000 / 60 - (24 * 60 * daysRemaining) - (60 * hoursRemaining));
var secondsRemaining = Math.floor(difference / 1000 - (24 * 60 * 60 * daysRemaining) - (60 * 60 * hoursRemaining) - (60 * minutesRemaining));
$(selector).html(daysRemaining+':'+hoursRemaining+':'+minutesRemaining+':'+secondsRemaining);
setTimeout(function() {
$.countdown(selector, datevalue);
}, 1000);
}
};
$.countdown('.date', 1332239568);
Remove datevalue--;
What you're doing now is to count down to a specific epoch time datevalue. But, you are decreasing it by one second each tick. Meanwhile, current time passes in setTimeout so you are both moving in time forward and pulling the target to yourself.
Either keep the original curdate of first call, saved somewhere. Or remove datevalue--;.

Calculate number of weeks , days and hours from milliseconds

There were many similar questions around but none addressed this calculation. Using javascript i it is easy to find the number of milliseconds diff b/w 2 dates for ex:
var mil = Math.floor(new Date("1/1/2012") - new Date("1/7/2012"))
mil is assigned 518400000
to get weeks i would do below
var weeks = mil / (1000*7*24*60*60);
in the above example it exactly fits 1 week. For other possible inputs i would like to get output as ex:
n Weeks, y days , z hours
So i did mil % (1000*7*24*3600) to get the modulus and from the remainder calculate number of days. but astonishingly this was answer i got from console
1 weeks , 6 days seems the week calculated before is also accounted for days again.
How should i calculate these correctly?
var seconds = (mil / 1000) | 0;
mil -= seconds * 1000;
var minutes = (seconds / 60) | 0;
seconds -= minutes * 60;
var hours = (minutes / 60) | 0;
minutes -= hours * 60;
var days = (hours / 24) | 0;
hours -= days * 24;
var weeks = (days / 7) | 0;
days -= weeks * 7;
Assuming mils is non-negative, this leaves mils in the range [0, 1000), leaves minutes and seconds in the range [0, 60), leaves hours in the range [0, 24), and leaves days in the range [0, 7).
There should be 6 days between them, not one week. Your weeks calculation needs to round down:
var weeks = Math.floor(mil / (1000 * 7 * 24 * 60 * 60));
Also, your milliseconds are negative; you want either
var mil = new Date("1/7/2012") - new Date("1/1/2012");
or
var weeks = Math.floor(Math.abs(mil) / (1000 * 7 * 24 * 60 * 60));

Categories

Resources