Reputation: 23
with Christmas coming up, I thought that it would be the perfect time to code a Christmas countdown. I was able to get through the JavaScript and HTML fine, but started to have some trouble with the CSS. Here is all of my code:
//Gets the HTML Elements
var head = document.getElementById('head');
var subhead = document.getElementById('subhead');
var counter = document.getElementById('counter');
//finds Christmas
var christmas = new Date('December 25, 2016 00:00:00');
//Updates Timer
function updateTimer(christmas) {
var time = christmas - new Date();
//Gives what to find on update
return {
'days': Math.floor(time / (1000 * 60 * 60 * 24)),
'hours': Math.floor((time/(1000 * 60 * 60)) % 24),
'minutes': Math.floor((time / 1000 / 60) % 60),
'seconds': Math.floor((time / 1000) % 60),
'total': time
};
};
//Starts the timer
function startTimer(counter, christmas) {
var timerInterval = setInterval(function() {
var timer = updateTimer(christmas);
//Changes the text of the 'counter'
counter.innerHTML = '<span>' + timer.days + '</span>'
+ '<span>' + timer.hours + '</span>'
+ '<span>' + timer.minutes + '</span>'
+ '<span>' + timer.seconds + '</span>';
//if christmas
if(timer.total < 1) {
clearInterval(timerInterval);
counter.innerHTML = '<span>0</span><span>0</span><span>0</span><span>0</span>';
head.innerHTML = "It's Christmas!!!";
subhead.innerHTML = "Merry Christmas to all!!!";
}
//if christmas eve
else if (timer.days < 1){
subhead.innerHTML = "It is currently Christmas Eve! How much longer until Christmas Day???";
}
}, 1000); //timer updates every second
};
window.onload = function() {
startTimer(counter, christmas);
};
*:focus {
outline: none;
}
body {
background-color: #991f00;
text-shadow: 2px 2px 8px #000000;
}
header {
color: white;
text-align: center;
font-family: 'Cinzel Decorative', sans-serif;
}
#clock span {
float: left;
text-align: center;
margin: 0 2.5%;
padding: 20px;
width: 20%;
box-sizing: border-box;
color: white;
font-family: 'Mountains of Christmas', sans-serif;
font-size: 40px;
}
#counter span {
background-color: #000000;
border-radius: 100%;
animation-name: colorChange;
animation-duration: 6s;
animation-fill-mode: both;
animation-iteration-count: infinite;
}
@keyframes colorChange {
0%, 100% {
background-color: #42f471;
}
50% {
background-color: #ea524f;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Christmas Countdown</title>
<!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>!-->
<script type="text/javascript" src="scripts/script.js" async></script>
<!--<script type="text/javascript" src="scripts/color.js" async></script>!-->
<link rel="stylesheet" type="text/css" href="style.css">
<link href="https://fonts.googleapis.com/css?family=Cinzel+Decorative|Mountains+of+Christmas" rel="stylesheet">
</head>
<body>
<div id="wrapper">
<div id="clock">
<header>
<h1 id="head">Christmas Countdown!</h1>
<h4 id="subhead">How much longer until Christmas? Check the clock to find out!</h4>
</header>
<div id="count-container">
<div id="counter"></div>
<div id="labels">
<span>Days</span>
<span>Hours</span>
<span>Minutes</span>
<span>Seconds</span>
</div>
</div>
</div>
</div>
</body>
</html>
If you look at the code, then you will see that I tried to insert a CSS animation
using @keyframes
and all. I was trying to get the effect found here: https://kahoot.it/#/ , however only using 2 colors (#42f471
and #ea524f
). My thoughts were that I would make #42f471
as the starting color, which would then fade to #ea524f
which would also fade back to #42f471
. I started by trying set the duration of the animation to 6s
but when I loaded up the page, I found that the animation didn't even seem to go halfway, before suddenly flashing back to the first color. Trying an even longer duration, only makes it go through less before flashing back to that original color. Interestingly, though, shorter duration makes it go through more of the animation. At 1s
or less, it will go through the animation properly, but that speed is way too fast (I don't want to end up giving anyone a seizure :)). I've searched and searched the internet, but nothing I've tried has helped. I do not have much experience with animations, so almost all the stuff I used to make the animation I got from research on the internet.
Any answers are appreciated. I am also open to answers using JavaScript or Jquery, if necessary.
Upvotes: 1
Views: 75
Reputation: 18639
Notice that the animation is restarting every time the timer updates - this is because those DOM elements are being recreated by your JavaScript, thus the animation is starting over with them. Target your spans by giving them each IDs like this, and you'll see the animation keeps:
//Gets the HTML Elements
var head = document.getElementById('head');
var subhead = document.getElementById('subhead');
var counterDays = document.getElementById('days');
var counterHours = document.getElementById('hours');
var counterMinutes = document.getElementById('minutes');
var counterSeconds = document.getElementById('seconds');
//finds Christmas
var christmas = new Date('December 25, 2016 00:00:00');
//Updates Timer
function updateTimer(christmas) {
var time = christmas - new Date();
//Gives what to find on update
return {
'days': Math.floor(time / (1000 * 60 * 60 * 24)),
'hours': Math.floor((time/(1000 * 60 * 60)) % 24),
'minutes': Math.floor((time / 1000 / 60) % 60),
'seconds': Math.floor((time / 1000) % 60),
'total': time
};
};
//Starts the timer
function startTimer(counterDays, counterHours, counterMinutes, counterSeconds, christmas) {
var timerInterval = setInterval(function() {
var timer = updateTimer(christmas);
//Changes the text of the 'counter'
counterDays.innerHTML = timer.days;
counterHours.innerHTML = timer.hours;
counterMinutes.innerHTML = timer.minutes;
counterSeconds.innerHTML = timer.seconds;
//if christmas
if(timer.total < 1) {
clearInterval(timerInterval);
counterDays.innerHTML = 0;
counterHours.innerHTML = 0;
counterMinutes.innerHTML = 0;
counterSeconds.innerHTML = 0;
head.innerHTML = "It's Christmas!!!";
subhead.innerHTML = "Merry Christmas to all!!!";
}
//if christmas eve
else if (timer.days < 1){
subhead.innerHTML = "It is currently Christmas Eve! How much longer until Christmas Day???";
}
}, 1000); //timer updates every second
};
window.onload = function() {
startTimer(counterDays, counterHours, counterMinutes, counterSeconds, christmas);
};
*:focus {
outline: none;
}
body {
background-color: #991f00;
text-shadow: 2px 2px 8px #000000;
}
header {
color: white;
text-align: center;
font-family: 'Cinzel Decorative', sans-serif;
}
#clock span {
float: left;
text-align: center;
margin: 0 2.5%;
padding: 20px;
width: 20%;
box-sizing: border-box;
color: white;
font-family: 'Mountains of Christmas', sans-serif;
font-size: 40px;
}
#counter span {
background-color: #000000;
border-radius: 100%;
animation-name: colorChange;
animation-duration: 6s;
animation-fill-mode: both;
animation-iteration-count: infinite;
}
@keyframes colorChange {
0%, 100% {
background-color: #42f471;
}
50% {
background-color: #ea524f;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Christmas Countdown</title>
<!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>!-->
<script type="text/javascript" src="scripts/script.js" async></script>
<!--<script type="text/javascript" src="scripts/color.js" async></script>!-->
<link rel="stylesheet" type="text/css" href="style.css">
<link href="https://fonts.googleapis.com/css?family=Cinzel+Decorative|Mountains+of+Christmas" rel="stylesheet">
</head>
<body>
<div id="wrapper">
<div id="clock">
<header>
<h1 id="head">Christmas Countdown!</h1>
<h4 id="subhead">How much longer until Christmas? Check the clock to find out!</h4>
</header>
<div id="count-container">
<div id="counter">
<span id="days"> </span>
<span id="hours"> </span>
<span id="minutes"> </span>
<span id="seconds"> </span>
</div>
<div id="labels">
<span>Days</span>
<span>Hours</span>
<span>Minutes</span>
<span>Seconds</span>
</div>
</div>
</div>
</div>
</body>
</html>
Upvotes: 3
Reputation: 541
Your fundamental flaw is that you're recreating the DOM elements every second, while the animation is set to 6s.
Instead of recreating the DOM as you have done here:
counter.innerHTML = '<span>' + timer.days + '</span>'
+ '<span>' + timer.hours + '</span>'
+ '<span>' + timer.minutes + '</span>'
+ '<span>' + timer.seconds + '</span>';
You need to go and change the inner text of each span
individually, so the span itself isn't recreated.
Upvotes: 0