Как сделать подобный таймер на 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>
