Как сделать подобный таймер на JS?

Есть какой-нибудь не сложный метод чтобы реализовать такой таймер? Без плагинов введите сюда описание изображения


Ответы (1 шт):

Автор решения: Leonid

Добавил еще миллисекунды.

document.querySelector('button').addEventListener('click', handleTimer);
let is_going = false;
let cur_anim = 0;
let timer_time = 0;
let last_time = 0;

const back_canvas = document.querySelector('canvas#background');
const timer_canvas = document.querySelector('canvas#timer');
const w = back_canvas.width = timer_canvas.width = 600;
const h = back_canvas.height = timer_canvas.height = 180;

const ctx = timer_canvas.getContext('2d');
ctx.lineWidth = 6;
ctx.strokeStyle = 'red';
ctx.font = "32px sans-serif";
ctx.textAlign = 'center';
ctx.textBaseline = 'alphabetic';

drawBack(back_canvas.getContext('2d'));
drawTimer(0);

function handleTimer(event){
    const button = event.target;
    is_going = !is_going;
    
    if(is_going){
        button.textContent = 'Stop';
        startTimer();
    } else {
        button.textContent = 'Start';
        stopTimer();
    }
}

function stopTimer(){
    cancelAnimationFrame(cur_anim);
}

function startTimer(){
    last_time = performance.now();
    cur_anim = requestAnimationFrame(animateTimer);
}

function animateTimer(){
    d_time = performance.now() - last_time;
    timer_time += d_time;
    last_time = performance.now();
    
    drawTimer(Math.floor(timer_time));
    
    cur_anim = requestAnimationFrame(animateTimer);
}

function drawTimer(time){
    const secs = time/1000;
    const min_angle = (secs * Math.PI / 3600) % Math.PI*2;
    const sec_angle = (secs * Math.PI / 60) % Math.PI*2;
    const mil_angle = (secs * Math.PI) % Math.PI*2;
    
    ctx.clearRect(0,0,w,h);

    ctx.beginPath();
    ctx.arc(100, 90, 80, 0, min_angle);
    ctx.stroke();
    
    ctx.beginPath();
    ctx.arc(300, 90, 80, 0, sec_angle);
    ctx.stroke();
    
    ctx.beginPath();
    ctx.arc(500, 90, 80, 0, mil_angle);
    ctx.stroke();

    ctx.fillText(Math.floor(secs/60), 100, 90);
    ctx.fillText((Math.floor(secs))%60, 300, 90);
    ctx.fillText(time%1000, 500,90);

}

function drawBack(ctx) {
    ctx.fillStyle = 'yellow';
    ctx.fillRect(0,0,w,h);
    ctx.lineWidth = 6;
    ctx.strokeStyle = 'white';

    ctx.beginPath();
    ctx.arc(100, 90, 80, 0, Math.PI*2);
    ctx.stroke();
    
    ctx.beginPath();
    ctx.arc(300, 90, 80, 0, Math.PI*2);
    ctx.stroke();
    
    ctx.beginPath();
    ctx.arc(500, 90, 80, 0, Math.PI*2);
    ctx.stroke();

    ctx.font = '18px sans-serif';
    ctx.textAlign = 'center';
    ctx.fillStyle = 'black';
    ctx.textBaseline = 'top';

    ctx.fillText('минут', 100, 95);
    ctx.fillText('секунд', 300, 95);
    ctx.fillText('миллисекунд', 500, 95);

}
    canvas, button {
        position: fixed;
        top: 0;
        left: 0;
    }

    button {
        z-index: 1;
    }
    <button>Start</button>
    <canvas id="background"></canvas>
    <canvas id="timer"></canvas>

→ Ссылка