Построить индикатор полукруга с закругленными углами и тенью в сценарии Java и CSS

Я много искал и ничего не нашел на нем. Я хочу сделать прогресс-бар с закругленными углами. Прогресс-бар должен иметь тень. Все, что я сделал на данный момент, здесь:

$(".progress-bar").each(function(){
  
  var bar = $(this).find(".bar");
  var val = $(this).find("span");
  var per = parseInt( val.text(), 10);

  $({p:0}).animate({p:per}, {
    duration: 3000,
    easing: "swing",
    step: function(p) {
      bar.css({
        transform: "rotate("+ (45+(p*1.8)) +"deg)"
      });
      val.text(p|0);
    }
  });
});
body{
  background-color:#3F63D3;  
}

.progress-bar{
  position: relative;
  margin: 4px;
  float:left;
  text-align: center;
}
.barOverflow{ 
  position: relative;
  overflow: hidden; 
  width: 150px; height: 70px; 
  margin-bottom: -14px;
}
.bar{
  position: absolute;
  top: 0; left: 0;
  width: 150px; height: 150px; 
  border-radius: 50%;
  box-sizing: border-box;
  border: 15px solid gray;       
  border-bottom-color: white; 
  border-right-color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="progress-bar">
  <div class="barOverflow">
    <div class="bar"></div>
  </div>
  <span>100</span>%
</div>

Я хочу сделать углы круглыми и иметь тень. ниже данное изображение представляет то, что я на самом деле хочу. Тени не хватает, потому что я не умею рисовать.:

Я также пробовал Progressbar.js, но не очень разбираюсь в SVG. Любой ответ будет оценен.

3 ответа

Решение

@jaromanda для предложения изучения SVG.

Да, это выглядит очень трудно добиться от границы радиуса. Так что я заглянул в SVG и нашел его довольно удобным. Вот мой фрагмент:

// progressbar.js@1.0.0 version is used
// Docs: http://progressbarjs.readthedocs.org/en/1.0.0/

var bar = new ProgressBar.SemiCircle(container, {
  strokeWidth: 10,
  color: 'red',
  trailColor: '#eee',
  trailWidth: 10,
  easing: 'easeInOut',
  duration: 1400,
  svgStyle: null,
  text: {
    value: '',
    alignToBottom: false
  },
  
  // Set default step function for all animate calls
  step: (state, bar) => {
    bar.path.setAttribute('stroke', state.color);
    var value = Math.round(bar.value() * 100);
    if (value === 0) {
      bar.setText('');
    } else {
      bar.setText(value+"%");
    }

    bar.text.style.color = state.color;
  }
});
bar.text.style.fontFamily = '"Raleway", Helvetica, sans-serif';
bar.text.style.fontSize = '2rem';

bar.animate(0.45);  // Number from 0.0 to 1.0
#container {
  width: 200px;
  height: 100px;
}

svg {
  height: 120px;
  width: 200px;
  fill: none;
  stroke: red;
  stroke-width: 10;
  stroke-linecap: round;
  -webkit-filter: drop-shadow( -3px -2px 5px gray );
  filter: drop-shadow( -3px -2px 5px gray );
  }
<script src="https://rawgit.com/kimmobrunfeldt/progressbar.js/1.0.0/dist/progressbar.js"></script>
<link href="https://fonts.googleapis.com/css?family=Raleway:400,300,600,800,900" rel="stylesheet" type="text/css">
<div id="container"></div>

Я хочу предложить какое-то глупое, но быстрое решение, так как вы уже используете position: absolute. Вы можете добавить цвет фона к кругу, когда ваша анимация запускается.

HTML:

<div class="progress-bar">
    <div class="left"></div>
    <div class="right"><div class="back"></div></div>
    <div class="barOverflow">
        <div class="bar"></div>
    </div>
    <span>0</span>%
</div>

CSS:

/** all your css here **/
body{
    background-color:#3F63D3;  
}

.progress-bar{
    position: relative;
    margin: 4px;
    float: left;
    text-align: center;
}
.barOverflow{ 
    position: relative;
    overflow: hidden; 
    width: 150px; height: 70px; 
    margin-bottom: -14px;
}
.bar{
    position: absolute;
    top: 0; left: 0;
    width: 150px; height: 150px; 
    border-radius: 50%;
    box-sizing: border-box;
    border: 15px solid gray;       
    border-bottom-color: white; 
    border-right-color: white;
    transform: rotate(45deg);
}
.progress-bar > .left {
    position: absolute;
    background: white;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    left: 0;
    bottom: -4px;
    overflow: hidden;
}
.progress-bar > .right {
    position: absolute;
    background: white;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    right: 0;
    bottom: -4px;
    overflow: hidden;
}
.back {
    width: 15px;
    height: 15px;
    background: gray;
    position: absolute;
}

JQuery:

$(".progress-bar").each(function(){
    var bar = $(this).find(".bar");
    var val = $(this).find("span");
    var per = parseInt( val.text(), 10);
    var $right = $('.right');
    var $back = $('.back');

$({p:0}).animate({p:per}, {
    duration: 3000,
    step: function(p) {
        bar.css({
            transform: "rotate("+ (45+(p*1.8)) +"deg)"
        });
    val.text(p|0);
    }
}).delay( 200 );

if (per == 100) {
    $back.delay( 2600 ).animate({'top': '18px'}, 200 );
}

if (per == 0) {
    $('.left').css('background', 'gray');
}
});

https://jsfiddle.net/y86qs0a9/7/

Как и в ответах выше, мне было намного проще реализовать использование SVG вместо чистого CSS.

Однако я не смог найти ни одной упрощенной реализации, использующей только HTML и CSS или, по крайней мере, без библиотек, внешних скриптов или зависимостей. Я обнаружил, что, учитывая математику, которую необходимо рассчитать, чтобы преобразовать SVG для представления процента, необходимо включить JS (если кто-то знает, как добиться этого только с помощью HTML и CSS, я хотел бы узнать, как это сделать). Но то, что делает сценарий JS, недостаточно длинное или сложное, чтобы оправдать накладные расходы на добавление еще одной зависимости в мою кодовую базу.

  • Расчеты JS довольно просты после прочтения. Вам необходимо вычислить координату конечной точки датчика в системе координат SVG. так что основной триггер.

  • Большая часть CSS даже не нужна, и я добавил ее только для того, чтобы стилизовать и сделать ее красивой. Вы можете добавить тень или градиенты так же, как и с любой чистой HTML-формой.

  • Вот codePen https://codepen.io/naticaceres/pen/QWQeyGX

Вы можете легко изменить этот код, чтобы получить любую форму круглого датчика (полный круг, нижняя половина полукруга или любой вариант, включая эллипсис).

Надеюсь, это полезно.

Другие вопросы по тегам