JSFiddle - React, Tailwind, and code Playground
by bvotcode
HTML
<div id="container-one">
CSS
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: sans-serif;
}
body {
min-height: 100vh;
background: #2f363e;
}
#timer-wrapper {
display: flex;
justify-content: center;
align-items: center;
gap: 32px;
margin: 0 auto 1.5rem auto;
}
#timer-wrapper .circle {
position: relative;
width: 150px;
height: 150px;
display: flex;
justify-content: center;
align-items: center;
}
#timer-wrapper .circle svg {
position: relative;
width: 150px;
height: 150px;
transform: rotate(270deg);
}
#timer-wrapper .circle svg circle {
width: 100%;
height: 100%;
fill: transparent;
stroke-linecap: round;
stroke-width: 8;
stroke: #282828;
transform: translate(3px, 3px);
}
#timer-wrapper .circle svg circle:nth-child(2) {
stroke: var(--clr);
stroke-dasharray: 440;
stroke-dashoffset: 440;
}
#timer-wrapper div {
position: absolute;
text-align: center;
color: #fff;
font-weight: 300;
font-size: 1.5em;
}
#timer-wrapper div span {
position: absolute;
transform: translateX(-50%) translateY(0px);
font-size: 0.35em;
text-transform: uppercase;
font-weight: 300;
letter-spacing: 0.1em;
}
#timer-wrapper .dots {
position: absolute;
width: 150px;
height: 150px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: flex-start;
z-index: 1000;
}
#timer-wrapper .dots::before {
content: "";
position: absolute;
right: 0;
left: 0;
top: -1px;
margin: 0 auto;
width: var(--dot-width);
height: var(--dot-width);
background: var(--clr);
border-radius: 50%;
box-shadow: 0 0 20px var(--clr), 0 0 60px var(--clr);
}
.message-wrapper {
display: none;
}
.message-wrapper span {
display: block;
text-transform: uppercase;
text-align: center;
color: #fff;
}
.message-wrapper .title {
font-size: 4rem;
line-height: normal;
font-weight: 600;
}
.message-wrapper .sub-title {
font-size: 3rem;
line-height: normal;
font-weight: 500;
}
JavaScript
class CountdownTimer {
constructor(containerId, startDate, endDate, percentage = 100, title, subtitle) {
this.startDate = new Date(startDate).getTime();
this.endDate = new Date(endDate).getTime();
this.container = document.getElementById(containerId);
this.percentage = percentage / 100;
this.containerWidth = 150 * this.percentage;
this.circleRadius = (70 * this.percentage);
this.circleCircumference = Math.ceil(2 * Math.PI * this.circleRadius);
this.dotDiameter = 20 * this.percentage;
// Dynamically create and append required HTML elements
this.createHTMLStructure(title, subtitle);
this.timerContainer = this.container.querySelector('#timer-wrapper');
this.startMessageContainer = this.container.querySelector('.start-message-wrapper');
this.endMessageContainer = this.container.querySelector('.end-message-wrapper');
this.daysElement = this.container.querySelector('#days');
this.hoursElement = this.container.querySelector('#hours');
this.minutesElement = this.container.querySelector('#minutes');
this.secondsElement = this.container.querySelector('#seconds');
this.daysStroke = this.container.querySelector('#dd');
this.hoursStroke = this.container.querySelector('#hh');
this.minutesStroke = this.container.querySelector('#mm');
this.secondsStroke = this.container.querySelector('#ss');
this.dayDot = this.container.querySelector('.day_dot');
this.hourDot = this.container.querySelector('.hr_dot');
this.minuteDot = this.container.querySelector('.min_dot');
this.secondDot = this.container.querySelector('.sec_dot');
this.previousDays = null;
this.previousHours = null;
this.previousMinutes = null;
this.previousSeconds = null;
this.scaleElements(); // Apply scaling based on the percentage value
this.countdownInterval =...