Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Круговой прогресс бар с таймером? (https://javascript.ru/forum/misc/83990-krugovojj-progress-bar-s-tajjmerom.html)

Katy93 09.05.2022 02:51

Круговой прогресс бар с таймером?
 
Делаю прогресс бар с таймером. Начиная с точки старта progress bar должен делать круговой оборот, и вернуться на исходную позицию (по часовой стрелки). При этом учитывая скорость ползунка которая зависит от таймера. Предположим дано три минуты, за это время нужно успеть сделать круг.

Мои попытки не увенчались успехом, для начала я решила попробовать нарисовать круг и посмотреть, как он двигается по орбите. Сделала я так как показано ниже, здесь angle1, производит расчет где по истечению таймера, будет совершен один оборот вокруг центра.

circle.x = Math.sin(angle1) * distance + offset.x;
circle.y = Math.cos(angle1) * distance + offset.y;
  
c.arc(circle.x, circle.y, circle.r, 0, Math.PI * 2);


Этот вариант мне не подходит так круг движется по орбите а мне нужен прогресс бар. Второй вариант, это обойтись без синусов и косинусов и все сделать с помощью Math.PI, вот так.

c.arc( posX, posY, 70, (Math.PI/180) * (270 - angle),(Math.PI/180)*270 );


Здесь следует angle присваивать конкретно цифру например уменьшать угол на единицу. Поэтому сделать по времени не получается.

Как сделать так чтобы прогресс бар начиная свой путь с точки X делал оборот и заканчивал там же по истечению времени?
Вот мой код:

<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
<style>
:root {
  background: #fff;
}

span#procent {
  display: block;
  position: absolute;
  left: 50%;
  top: 50%;
  font-size: 50px;
  transform: translate(-50%, -50%);
  color: #3949AB;
}

span#procent::after {
  content: '%';
}

.canvas-wrap {
  position: relative;
  width: 300px;
  height: 300px;
}

</style>
<script>

window.onload = function() {
  var can = document.getElementById('canvas'),
      spanProcent = document.getElementById('procent'),
       c = can.getContext('2d');
 
  var posX = can.width / 2,
      posY = can.height / 2,
      fps = 1000 / 200,
      procent = 0,
      oneProcent = 360 / 100,
      result = oneProcent * 100;
  
  c.lineCap = 'round';
  
  
  ArcX = 10;
  ArcY = 10;
  ArcCX = ArcX + 50;
  ArcCY = ArcY + 50;
  
  minisec = 1000;
  sec1 = 180;
  //TimerMSec = (0*60 + sec1) * 1000;
  
  
  //console.log(TimerMSec);
  
 // https://stackoverflow.com/questions/8297886/flash-as3-draw-a-donut-wedge-arc-with-inner-and-outer-radius-using-curveto

  var StartMSec = Math.floor(new Date().getTime());
  TimerMSec = (0*60 + sec1) * 1000; // Засекаем: Минуты * 60 + секунды
  
  var circle = {x: 10, y: 10, r: 10};
  var angle3 = 0; // radian
  var offset = {x: 140, y: 140};
  var distance = 90;
  var angle = 360;
  temp = angle / sec1 / 100;
 arcMove();
  function arcMove(){
    var angle = 360;
    
   
    var acrInterval = setInterval (function() {
      ct = Math.floor(new Date().getTime());
      rt = (StartMSec + TimerMSec - ct); // Миллисекунд до окончания
      
      
      angle1 = rt/TimerMSec * 2 * Math.PI;
      
      angle -= angle1;
      c.clearRect( 0, 0, can.width, can.height );
      procent = angle / oneProcent;

      spanProcent.innerHTML = procent.toFixed();
      c.save();
      c.beginPath();
      c.arc( posX, posY, 70, (Math.PI/180) * 270, (Math.PI/180) * (270 + 360) );
      c.strokeStyle = '#b1b1b1';
      c.lineWidth = '10';
      c.stroke();
      c.restore();
       c.save();
      c.beginPath();
      
    
      c.strokeStyle = '#3949AB';
      c.lineWidth = '10';
      
    //  
     // circle.x = Math.sin(angle / 180 * Math.PI) * distance + offset.x;
      //circle.y = Math.cos(angle / 180 * Math.PI) * distance + offset.y;
      var sinus = Math.sin((Math.PI * angle1 / 180) / 2);
      var cos = Math.cos((Math.PI * angle1 / 180) / 2);
      
      c.arc( posX, posY, 70, (Math.PI/180) * (270 - angle),(Math.PI/180)*270 );
      
      circle.x = Math.sin(angle1) * distance + offset.x;
      circle.y = Math.cos(angle1) * distance + offset.y;
  
      
     
      
      c.arc(circle.x, circle.y, circle.r, 0, Math.PI * 2);
      c.fill();
     
     
      c.stroke();
      
      document.getElementById("timer").innerHTML="<span style='font-size:48px;'>"+Math.floor(rt / 60000)+":"+ Math.floor((rt / 1000) % 60)+"</span>";
     
    }, 63);
    
  }
}

</script>
</head>
<body>
<div id="timer"></div>
<div class="canvas-wrap">
  <canvas id="canvas" width="300" height="300"></canvas>
  <span id="procent"></span>
</div>
</body>

рони 09.05.2022 07:39

Katy93,
https://javascript.ru/forum/events/4...tml#post277850

Katy93 10.05.2022 03:12

Это не то. Здесь таймер подгоняется под progress bar, а мне нужно наоборот, чтобы прогресс бар двигался со скоростью временного интервала, чем больше времени установлено тем медленнее двигается progress bar..

Таймер это секунды. Когда я пытаюсь увеличить значение, допустим 300 секунд = 5минут, то вижу как цифра в fillText, начинает ускоряться.

<!DOCTYPE HTML>
<html>
<head>
  <title>Untitled</title>
</head>
<body>
<canvas id="myCanvas" ></canvas>
<script>
  var myCanvas = document.getElementById("myCanvas"),
    context = myCanvas.getContext("2d"),
    timeLimit = 15E3,
    timeStart = (new Date).getTime(),
    canvasSize = 200,
    lineWidth = 24,
    drawX = drawY = radius = canvasSize / 2;
    radius -= lineWidth / 2;
    
    console.log(timeLimit);
    myCanvas.width = canvasSize;
    myCanvas.height = canvasSize;
    sec1 = 300;
    degrees = 2;
    
    
function go() {
    context.beginPath();
    context.lineWidth = lineWidth;
    context.lineCap = "round";
    context.strokeStyle = "rgb(0, 255, 0)";
    var a = ((new Date).getTime() - timeStart) / timeLimit;
    context.clearRect(0, 0, canvasSize, canvasSize);
    context.font = '24px "Tahoma"';
    context.fillText((sec1 - a*sec1)|0, radius, drawY);
    context.arc(drawX, drawY, radius, -Math.PI / 2 + degrees * Math.PI * a, -Math.PI / 2, !1);
    context.stroke();
    1 < a && (timeStart = (new Date).getTime());
    timer = window.setTimeout(go, 50)
}
go();
</script>
</body>
</html>

рони 10.05.2022 10:52

Цитата:

Сообщение от Katy93
5минут,

строка 11
timeLimit = 5 * 60 * 1000;

Katy93 11.05.2022 23:06

Все работает, спасибо.


Часовой пояс GMT +3, время: 02:08.