Created
October 19, 2018 09:35
-
-
Save HamzaAnis/adada3a7aef17fa76f5cd5b19a48ff8b to your computer and use it in GitHub Desktop.
Countdown timer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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>Timer</title> | |
<link rel="stylesheet" href="style.css"> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script> | |
<script src="index.js"></script> | |
</head> | |
<body> | |
<div class="wrap"> | |
<div class="countdown"> | |
<div class="bloc-time hours" data-init-value="24"> | |
<span class="count-title">Hours</span> | |
<div class="figure hours hours-1"> | |
<span class="top">2</span> | |
<span class="top-back"> | |
<span>2</span> | |
</span> | |
<span class="bottom">2</span> | |
<span class="bottom-back"> | |
<span>2</span> | |
</span> | |
</div> | |
<div class="figure hours hours-2"> | |
<span class="top">4</span> | |
<span class="top-back"> | |
<span>4</span> | |
</span> | |
<span class="bottom">4</span> | |
<span class="bottom-back"> | |
<span>4</span> | |
</span> | |
</div> | |
</div> | |
<div class="bloc-time min" data-init-value="0"> | |
<span class="count-title">Minutes</span> | |
<div class="figure min min-1"> | |
<span class="top">0</span> | |
<span class="top-back"> | |
<span>0</span> | |
</span> | |
<span class="bottom">0</span> | |
<span class="bottom-back"> | |
<span>0</span> | |
</span> | |
</div> | |
<div class="figure min min-2"> | |
<span class="top">0</span> | |
<span class="top-back"> | |
<span>0</span> | |
</span> | |
<span class="bottom">0</span> | |
<span class="bottom-back"> | |
<span>0</span> | |
</span> | |
</div> | |
</div> | |
<div class="bloc-time sec" data-init-value="0"> | |
<span class="count-title">Seconds</span> | |
<div class="figure sec sec-1"> | |
<span class="top">0</span> | |
<span class="top-back"> | |
<span>0</span> | |
</span> | |
<span class="bottom">0</span> | |
<span class="bottom-back"> | |
<span>0</span> | |
</span> | |
</div> | |
<div class="figure sec sec-2"> | |
<span class="top">0</span> | |
<span class="top-back"> | |
<span>0</span> | |
</span> | |
<span class="bottom">0</span> | |
<span class="bottom-back"> | |
<span>0</span> | |
</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$(document).ready(function () { | |
// Create Countdown | |
var Countdown = { | |
// Backbone-like structure | |
$el: $(".countdown"), | |
// Params | |
countdown_interval: null, | |
total_seconds: 0, | |
// Initialize the countdown | |
init: function () { | |
// DOM | |
this.$ = { | |
hours: this.$el.find(".bloc-time.hours .figure"), | |
minutes: this.$el.find(".bloc-time.min .figure"), | |
seconds: this.$el.find(".bloc-time.sec .figure") | |
}; | |
// Init countdown values | |
this.values = { | |
hours: this.$.hours.parent().attr("data-init-value"), | |
minutes: this.$.minutes.parent().attr("data-init-value"), | |
seconds: this.$.seconds.parent().attr("data-init-value") | |
}; | |
// Initialize total seconds | |
this.total_seconds = | |
this.values.hours * 60 * 60 + | |
this.values.minutes * 60 + | |
this.values.seconds; | |
// Animate countdown to the end | |
this.count(); | |
}, | |
count: function () { | |
var that = this, | |
$hour_1 = this.$.hours.eq(0), | |
$hour_2 = this.$.hours.eq(1), | |
$min_1 = this.$.minutes.eq(0), | |
$min_2 = this.$.minutes.eq(1), | |
$sec_1 = this.$.seconds.eq(0), | |
$sec_2 = this.$.seconds.eq(1); | |
this.countdown_interval = setInterval(function () { | |
if (that.total_seconds > 0) { | |
--that.values.seconds; | |
if (that.values.minutes >= 0 && that.values.seconds < 0) { | |
that.values.seconds = 59; | |
--that.values.minutes; | |
} | |
if (that.values.hours >= 0 && that.values.minutes < 0) { | |
that.values.minutes = 59; | |
--that.values.hours; | |
} | |
// Update DOM values | |
// Hours | |
that.checkHour(that.values.hours, $hour_1, $hour_2); | |
// Minutes | |
that.checkHour(that.values.minutes, $min_1, $min_2); | |
// Seconds | |
that.checkHour(that.values.seconds, $sec_1, $sec_2); | |
--that.total_seconds; | |
} else { | |
clearInterval(that.countdown_interval); | |
} | |
}, 1000); | |
}, | |
animateFigure: function ($el, value) { | |
var that = this, | |
$top = $el.find(".top"), | |
$bottom = $el.find(".bottom"), | |
$back_top = $el.find(".top-back"), | |
$back_bottom = $el.find(".bottom-back"); | |
// Before we begin, change the back value | |
$back_top.find("span").html(value); | |
// Also change the back bottom value | |
$back_bottom.find("span").html(value); | |
// Then animate | |
TweenMax.to($top, 0.8, { | |
rotationX: "-180deg", | |
transformPerspective: 300, | |
ease: Quart.easeOut, | |
onComplete: function () { | |
$top.html(value); | |
$bottom.html(value); | |
TweenMax.set($top, { | |
rotationX: 0 | |
}); | |
} | |
}); | |
TweenMax.to($back_top, 0.8, { | |
rotationX: 0, | |
transformPerspective: 300, | |
ease: Quart.easeOut, | |
clearProps: "all" | |
}); | |
}, | |
checkHour: function (value, $el_1, $el_2) { | |
var val_1 = value.toString().charAt(0), | |
val_2 = value.toString().charAt(1), | |
fig_1_value = $el_1.find(".top").html(), | |
fig_2_value = $el_2.find(".top").html(); | |
if (value >= 10) { | |
// Animate only if the figure has changed | |
if (fig_1_value !== val_1) this.animateFigure($el_1, val_1); | |
if (fig_2_value !== val_2) this.animateFigure($el_2, val_2); | |
} else { | |
// If we are under 10, replace first figure with 0 | |
if (fig_1_value !== "0") this.animateFigure($el_1, 0); | |
if (fig_2_value !== val_1) this.animateFigure($el_2, val_1); | |
} | |
} | |
}; | |
// Let's go ! | |
Countdown.init(); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
background-color: #ffffff; | |
} | |
.wrap { | |
position: absolute; | |
bottom: 0; | |
top: 0; | |
left: 0; | |
right: 0; | |
margin: auto; | |
height: 310px; | |
} | |
a { | |
text-decoration: none; | |
color: #ffffff; | |
} | |
h1 { | |
margin-bottom: 60px; | |
text-align: center; | |
font: 300 2.25em "Lato"; | |
text-transform: uppercase; | |
} | |
h1 strong { | |
font-weight: 400; | |
color: #ffffff; | |
} | |
h2 { | |
margin-bottom: 80px; | |
text-align: center; | |
font: 300 0.7em "Lato"; | |
text-transform: uppercase; | |
} | |
h2 strong { | |
font-weight: 400; | |
} | |
.countdown { | |
width: 720px; | |
margin: 0 auto; | |
} | |
.countdown .bloc-time { | |
float: left; | |
margin-right: 45px; | |
text-align: center; | |
} | |
.countdown .bloc-time:last-child { | |
margin-right: 0; | |
} | |
.countdown .count-title { | |
display: block; | |
margin-bottom: 15px; | |
font: normal 0.94em "Lato"; | |
color: #1a1a1a; | |
text-transform: uppercase; | |
} | |
.countdown .figure { | |
position: relative; | |
float: left; | |
height: 110px; | |
width: 100px; | |
margin-right: 10px; | |
background-color: #000000; | |
border-radius: 8px; | |
-moz-box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.2), inset 2px 4px 0 0 rgba(255, 255, 255, 0.08); | |
-webkit-box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.2), inset 2px 4px 0 0 rgba(255, 255, 255, 0.08); | |
box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.2), inset 2px 4px 0 0 rgba(255, 255, 255, 0.08); | |
} | |
.countdown .figure:last-child { | |
margin-right: 0; | |
} | |
.countdown .figure>span { | |
position: absolute; | |
left: 0; | |
right: 0; | |
margin: auto; | |
font: normal 5.94em/107px "Lato"; | |
font-weight: 700; | |
color: #ffffff; | |
} | |
.countdown .figure .top:after, | |
.countdown .figure .bottom-back:after { | |
content: ""; | |
position: absolute; | |
z-index: -1; | |
left: 0; | |
bottom: 0; | |
width: 100%; | |
height: 100%; | |
border-bottom: 1px solid rgba(0, 0, 0, 0.1); | |
} | |
.countdown .figure .top { | |
z-index: 3; | |
background-color: #000000; | |
transform-origin: 50% 100%; | |
-webkit-transform-origin: 50% 100%; | |
-moz-border-radius-topleft: 10px; | |
-webkit-border-top-left-radius: 10px; | |
border-top-left-radius: 10px; | |
-moz-border-radius-topright: 10px; | |
-webkit-border-top-right-radius: 10px; | |
border-top-right-radius: 10px; | |
-moz-transform: perspective(200px); | |
-ms-transform: perspective(200px); | |
-webkit-transform: perspective(200px); | |
transform: perspective(200px); | |
} | |
.countdown .figure .bottom { | |
z-index: 1; | |
} | |
.countdown .figure .bottom:before { | |
content: ""; | |
position: absolute; | |
display: block; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 50%; | |
background-color: rgba(0, 0, 0, 0.02); | |
} | |
.countdown .figure .bottom-back { | |
z-index: 2; | |
top: 0; | |
height: 50%; | |
overflow: hidden; | |
background-color: #000000; | |
-moz-border-radius-topleft: 10px; | |
-webkit-border-top-left-radius: 10px; | |
border-top-left-radius: 10px; | |
-moz-border-radius-topright: 10px; | |
-webkit-border-top-right-radius: 10px; | |
border-top-right-radius: 10px; | |
} | |
.countdown .figure .bottom-back span { | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
margin: auto; | |
} | |
.countdown .figure .top, | |
.countdown .figure .top-back { | |
height: 50%; | |
overflow: hidden; | |
-moz-backface-visibility: hidden; | |
-webkit-backface-visibility: hidden; | |
backface-visibility: hidden; | |
} | |
.countdown .figure .top-back { | |
z-index: 4; | |
bottom: 0; | |
background-color: #000000; | |
-webkit-transform-origin: 50% 0; | |
transform-origin: 50% 0; | |
-moz-transform: perspective(200px) rotateX(180deg); | |
-ms-transform: perspective(200px) rotateX(180deg); | |
-webkit-transform: perspective(200px) rotateX(180deg); | |
transform: perspective(200px) rotateX(180deg); | |
-moz-border-radius-bottomleft: 10px; | |
-webkit-border-bottom-left-radius: 10px; | |
border-bottom-left-radius: 10px; | |
-moz-border-radius-bottomright: 10px; | |
-webkit-border-bottom-right-radius: 10px; | |
border-bottom-right-radius: 10px; | |
} | |
.countdown .figure .top-back span { | |
position: absolute; | |
top: -100%; | |
left: 0; | |
right: 0; | |
margin: auto; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment