Как правильно вычисляется шаг?

Мне в пятом классе задали контрольную: нарисовать окружность ровно за 4 секунды. Я нарисовал за полторы, но не понял почему... если расстояние / на на время = скорость, а расстояние я узнал разогнув кружок вот так: Math.PI * 2 * radius, то почему в коде ниже это ничего не работает?

var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')
canvas.width = innerWidth
canvas.height = innerHeight

var clicked = false
var angle = 0
var radius = 40
var time = 4000

addEventListener('click', () => {
  if (clicked) return

  clicked = true
  setTimeout(() => {
    angle = 0
    clicked = false
  }, time)
})

function draw() {
  requestAnimationFrame(draw)
  ctx.clearRect(0, 0, innerWidth, innerHeight)

  if (clicked) {
    angle += Math.PI * 2 * radius / time
    ctx.beginPath()
    ctx.arc(innerWidth / 2, innerHeight / 2, radius, 0, angle, false)
    ctx.stroke()
  }
}

requestAnimationFrame(draw)
html,
body {
  margin: 0;
}

#canvas {
  display: block
}
<canvas id="canvas"></canvas>

var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')
canvas.width = innerWidth
canvas.height = innerHeight

var clicked = false
var angle = 0
var radius = 40
var duration = 4000
var startTime = 0

addEventListener('click', () => {
  if (clicked) return

  startTime = Date.now()
  clicked = true

  setTimeout(() => {
    angle = 0
    clicked = false
  }, duration)
})

function draw() {
  requestAnimationFrame(draw)
  ctx.clearRect(0, 0, innerWidth, innerHeight)

  if (clicked) {
    var v = Math.PI * 2 * radius / duration
    var t = (Date.now() - startTime) / duration
    angle += t * v
    ctx.beginPath()
    ctx.arc(innerWidth / 2, innerHeight / 2, radius, 0, angle, false)
    ctx.stroke()
  }
}

requestAnimationFrame(draw)
html,
body {
  margin: 0;
}

#canvas {
  display: block;
}
<canvas id="canvas"></canvas>

var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')
canvas.width = innerWidth
canvas.height = innerHeight

var clicked = false
var angle = 0
var radius = 40
var duration = 4000
var startTime = 0

addEventListener('click', () => {
  if (clicked) return

  startTime = Date.now()
  clicked = true

  setTimeout(() => {
    angle = 0
    clicked = false
  }, duration)
})

function draw() {
  requestAnimationFrame(draw)
  ctx.clearRect(0, 0, innerWidth, innerHeight)

  if (clicked) {
    var v = Math.PI * 2 * radius / duration
    var t = (Date.now() - startTime) / duration
    angle = t * v * 100
    ctx.beginPath()
    ctx.arc(innerWidth / 2, innerHeight / 2, radius, 0, angle, false)
    ctx.stroke()
  }
}

 requestAnimationFrame(draw)
html,
body {
  margin: 0;
}

#canvas {
  display: block;
}
<canvas id="canvas"></canvas>


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

Автор решения: Stranger in the Q
  1. В формуле для угла - радиус явно лишний

  2. Время уже Вам передается первым аргументом, если Вы используете requestAnimationFrame:

var ctx = canvas.getContext('2d')
var radius = 50;

function draw(t) { // тут передается время в мс
  
  t /= 4000; // t станет больше одного, через 4000 мс
             // соответственно 1 = полный круг
  
  ctx.clearRect(0, 0, innerWidth, innerHeight);
  ctx.beginPath();
  ctx.arc(150, 75, radius, 0, Math.PI * 2 * t, false);
  ctx.stroke();
  
  t < 1 && requestAnimationFrame(draw)
  
}

requestAnimationFrame(draw)
<canvas id="canvas"></canvas>

→ Ссылка