Today we're building a super useful widget - a countdown timer! Watch a narrated timelapse of coding the widget from scratch in our YouTube video below, and grab the final source code at the bottom of this article. You can customize it, change the font, tweak the CSS, and make it fit your channel!
This timer counts down to the top of the next hour, by default. This works great for most events - you can just start your stream ~10 minutes early, queue up this scene, and it counts down to the hour! But you can also set a custom target time - there's an example in the code near var target.
To use this widget in OBS:
<!DOCTYPE>
<html style="background:none">
<head>
<!-- https://fonts.google.com/specimen/Paytone+One -->
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Paytone+One&display=swap" rel="stylesheet">
<style>
body {
color:#fff;
font-family: "Paytone One";
opacity:0;
transition: opacity 0.2s ease;
text-align:center;
font-size:20vw;
}
/* You'll need to adjust these 1.3 and 0.7 widths if you change the font */
span.section {
display: inline-block;
width: 1.3em;
max-width: 1.3em;
}
span.section.half {
width: 0.7em;
max-width: 0.7em;
}
span.section.wunset {
width:unset;
max-width:unset;
}
</style>
</head>
<body>
</body>
<script>
setTimeout(function() {
document.body.style.opacity = "1";
}, 1500);
// Uncomment this line to count to a specific time:
//var target = "Tue Jan 12 2021, 8:38 pm MST";
var target = ""; // empty means top of the next hour
var tgt;
if (target=="") {
tgt = new Date(); // now
tgt.setMinutes(0); // start of this last hour
tgt.setSeconds(0); // start of this last hour
tgt = new Date(tgt.getTime()+3600*1000); // Plus an hour
} else {
tgt = new Date(target); // Whatever time you specify
}
function double_zero(i) {
return i<10 ? "0"+i : i;
}
function get_section(v, dz, align) {
var v = dz==false ? v : double_zero(v);
var cls = (dz==false && v<10) ? "section half" : "section";
if (v==0) cls += " wunset";
return "<span class='"+cls+"' style='text-align:"+align+"'>"+v+"</span>";
}
setInterval(function() {
var now = new Date();
// Countdown
var dt = Math.floor((tgt.getTime() - now.getTime())/1000);
var d_s = dt;
var d_m = Math.floor(d_s / 60);
d_s = d_s % 60;
var d_h = Math.floor(d_m / 60);
d_m = d_m % 60;
// Stick at zero:
if (dt < 0) {
d_h = 0; d_m = 0; d_s = 0;
}
var hours = d_h > 0 ? get_section(d_h, false, "right") + ":" : "";
var minutes = hours=="" ? get_section(d_m, false, "right") + ":" : get_section(d_m, true, "center") + ":";
document.body.innerHTML = hours + minutes + get_section(d_s, true, "left");
}, 1000);
</script>
</html>