Круглый анимированный progress bar. — PROG-TIME

Круглый анимированный progress bar.

09.08.2019
Содержание:

В новой записи мы с вами рассмотрим как сделать круглый анимированный progressbar с использованием JavaScript. Здесь мы будет использовать canvas для создания анимации. Прогресс бар очень простой с возможностью изменения размера и цвета через дополнительные атрибуты.

HTML

Элементы прогрессбаров добавляются с помощью элемента div и классом counter. Здесь же мы передаем специальные атрибуты для наших элементов. data-cp-percentage указывает процент который будет показывать progress bar, второй атрибут data-cp-color - задает цвет.

<div class="bg-style">
  <div>
     <div class="counter" data-cp-percentage="45" data-cp-color="#00bfeb"> </div>
  </div>
  <div>
     <div class="counter" data-cp-percentage="85" data-cp-color="#00bfeb"></div>
  </div>
</div>

CSS

.bg-style {
  display: flex;
  flex-direction: row;
}
.counter {
  display: inline-flex;
  cursor:pointer;
  width:150px;
  height:150px;
  max-width:100%;
  position:relative;
  justify-content:center;
  align-items:center;
  font-size: 25px;
  font-weight: 500;
  transition: height .2s ease-in-out;
  background: #fff;
  border-radius:50%;
}
.percentage {
  position:absolute;
  text-align:center;
  top:50%;
  left:0;
  right:0;
  vertical-align:middle;
  transform:translate3d(0,-50%,0);
}
canvas {
  position:absolute;
  top:0;
  left:0;
}

body {
  text-align:center;
}

JavaScript

document.addEventListener("DOMContentLoaded", function() {

  var circleProgress = (function(selector) {
    var wrapper = document.querySelectorAll(selector);
    Array.prototype.forEach.call(wrapper, function(wrapper, i) {
      var wrapperWidth,
        wrapperHeight,
        percent,
        innerHTML,
        context,
        lineWidth,
        centerX,
        centerY,
        radius,
        newPercent,
        speed,
        from,
        to,
        duration,
        start,
        strokeStyle,
        text;

      var getValues = function() {
        wrapperWidth = parseInt(window.getComputedStyle(wrapper).width);
        wrapperHeight = wrapperWidth;
        percent = wrapper.getAttribute('data-cp-percentage');
        innerHTML = '<span class="percentage"><strong>' + percent + '</strong> %</span><canvas class="circleProgressCanvas" width="' + (wrapperWidth * 2) + '" height="' + wrapperHeight * 2 + '"></canvas>';
        wrapper.innerHTML = innerHTML;
        text = wrapper.querySelector(".percentage");
        canvas = wrapper.querySelector(".circleProgressCanvas");
        wrapper.style.height = canvas.style.width = canvas.style.height = wrapperWidth + "px";
        context = canvas.getContext('2d');
        centerX = canvas.width / 2;
        centerY = canvas.height / 2;
        newPercent = 0;
        speed = 1;
        from = 0;
        to = percent;
        duration = 3000;
        lineWidth = 40;
        radius = canvas.width / 2 - lineWidth;
        strokeStyle = wrapper.getAttribute('data-cp-color');
        start = new Date().getTime();
      };

      function animate() {
        requestAnimationFrame(animate);
        var time = new Date().getTime() - start;
        if (time <= duration) {
          var x = easeInOutQuart(time, from, to - from, duration);
          newPercent = x;
          text.innerHTML = Math.round(newPercent) + " %";
          drawArc();
        }
      }

      function drawArc() {
        var circleStart = 1.5 * Math.PI;
        var circleEnd = circleStart + (newPercent / 50) * Math.PI;
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.beginPath();
        context.arc(centerX, centerY, radius, circleStart, 4 * Math.PI, false);
        context.lineWidth = lineWidth;
        context.strokeStyle = "#ddd";
        context.stroke();
        context.beginPath();
        context.arc(centerX, centerY, radius, circleStart, circleEnd, false);
        context.lineWidth = lineWidth;
        context.strokeStyle = strokeStyle;
        context.stroke();

      }
      var update = function() {
        getValues();
        animate();
      }
      update();

      var resizeTimer;
      window.addEventListener("resize", function() {
        clearTimeout(resizeTimer);
        resizeTimer = setTimeout(function() {
          clearTimeout(resizeTimer);
          start = new Date().getTime();
          update();
        }, 250);
      });
    });

    //
    // http://easings.net/#easeInOutQuart
    //  t: current time
    //  b: beginning value
    //  c: change in value
    //  d: duration
    //
    function easeInOutQuart(t, b, c, d) {
      if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
      return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
    }

  });

  circleProgress('.counter');

  // Gibt eine Zufallszahl zwischen min (inklusive) und max (exklusive) zurück
  function getRandom(min, max) {
    return Math.random() * (max - min) + min;
  }
});
На этом всё!
Больше интересных статей в нашей группе - https://vk.com/progtime
Вы так же можете разместить свой вопрос на нашем форуме, где другие программисты смогут вам помочь в решение вашей задачи - https://vk.com/prog_time
Так же прокачивайте свои навыки на нашем канале - https://www.youtube.com/c/ProgTime
Наши планы
  • Написание материала для курса по разработке ботов на Telegram
  • Разработка универсального парсера на PHP

Поддержите мой сайт!

Каждый переведённый донат, мотивирует на создание новых записей и уроков на YouTube

Контакты для связи

Технология на prog-time
Telegram
https://t.me/prog_time_bot