Круговой таймер
by AJIEKCEU
HTML
<div class="apm-db-bonus-experience apm-db-bonus__experience"><h3 class="apm-db-bonus-experience__title">
Отыгрыш: 1750 RUB
</h3> <svg width="0" height="0" class="apm-db-bonus-experience__gradient">
<linearGradient id="linear-gradient" x1y2="50%" gradientUnits="userSpaceOnUse"><stop stop-color="hsl(28, 99%, 53%)"></stop> <stop offset="1" stop-color="hsl(28, 93%, 41%)"></stop></linearGradient></svg> <div id="bonus_experience_474067217" data-val="40" data-max-val="1750"><div class="apm-db-bonus-experience__circle"><svg xmlns="http://www.w3.org/2000/svg" width="80" height="80"><path fill="transparent" stroke="hsl(223, 16%, 22%)" stroke-width="11" d="M 39.99297327447252 5.500000715577855 A 34.5 34.5 0 1 1 39.95208019213653 5.500033279841929 Z" class="circles-maxValueStroke"></path><path fill="transparent" stroke="url(#linear-gradient)" stroke-width="11" d="M 39.99297327447252 5.500000715577855 A 34.5 34.5 0 0 1 44.90974788795331 5.851143859907431 " class="circles-valueStroke"></path></svg><div class="apm-db-bonus-experience__text">40</div></div></div></div>
SCSS
.kjoker-time {
display: flex;
align-items: center;
justify-content: center;
width: 63px;
height: 63px;
&__label {
position: relative;
font-size: 18px;
color: #fff;
z-index: 50;
}
&__svg {
--stroke-offset: 0;
position: absolute;
width: 63px;
height: 63px;
}
&__bg {
fill: #122A70;
}
&__stroke {
stroke: url(#stroke-gradient_1);
stroke-width: 5px;
stroke-dasharray: 181 181;
stroke-dashoffset: var(--stroke-offset);
stroke-linecap: round;
transition: 1s linear all;
}
&__border {
stroke: url(#stroke-gradient_2);
stroke-opacity: .2;
stroke-width: 5px;
stroke-linecap: round;
}
&__circle {
fill: #fff;
// 1.98 = 360deg / 181 (max-dashoffset)
transform: rotate(calc(var(--stroke-offset) * (-1.98deg)));
transform-origin: 50% 50%;
transition: 1s linear all;
}
}
JavaScript
// Credit: Mateusz Rybczonec
const FULL_DASH_ARRAY = 181;
const TIME_LIMIT = 10;
let timePassed = 0;
let timeLeft = TIME_LIMIT;
let timerInterval = null;
document.getElementsByClassName("kjoker-time__label")[0].innerHTML = `
${formatTime(timeLeft)}
`;
startTimer();
function onTimesUp() {
clearInterval(timerInterval);
}
function startTimer() {
timerInterval = setInterval(() => {
timePassed = timePassed += 1;
timeLeft = TIME_LIMIT - timePassed;
document.getElementsByClassName("kjoker-time__label")[0].innerHTML = formatTime(timeLeft);
setCircleDasharray();
(timeLeft);
if (timeLeft === 0) {
onTimesUp();
}
}, 1000);
}
function formatTime(time) {
const minutes = Math.floor(time / 60);
let seconds = time % 60;
if (seconds < 10) {
seconds = `0${seconds}`;
}
return `${minutes}:${seconds}`;
}
function calculateTimeFraction() {
const rawTimeFraction = (timeLeft - 1) / (TIME_LIMIT - 1);
return FULL_DASH_ARRAY - FULL_DASH_ARRAY * (rawTimeFraction);
}
function setCircleDasharray() {
let pos = (calculateTimeFraction()).toFixed(0);
if(pos >= FULL_DASH_ARRAY){
pos = FULL_DASH_ARRAY;
}
document.getElementsByClassName("kjoker-time__stroke")[0].style.setProperty('--stroke-offset', -pos);
document.getElementsByClassName("kjoker-time__circle")[0].style.setProperty('--stroke-offset', -pos);
}