Круговой индикатор с реакцией - PullRequest
0 голосов
/ 02 мая 2020

В своем приложении реакции я использую круговой индикатор выполнения, чтобы показать оставшееся время. Индикатор выполнения использует bootstrap 3. Код работает нормально, когда значение жестко запрограммировано, но когда я даю процентное значение из переменной состояния, индикатор выполнения не отображается. Я скопировал этот код из net, и он использует bootstrap 3. Я хочу использовать его, чтобы показать обратный таймер. Так что процент изначально равен 100 и уменьшается каждую секунду. Вначале кружок показывает начальное значение, но как только значение процента изменяется, кружок теряет цвет и показывает базовый c серый цвет.

код в рендере -

constructor(props){
        super(props);

        this.state = {
            hours: 2,
            min: 0,
            secs: 0,
            fin: false,
            percent: 100
        }
    }

    componentDidMount(){
        this.myInterval = setInterval(() => {
            var {hours,min,secs,fin,percent} = this.state;

            if(secs > 0){
                secs--;
            } else {
                secs = 59;
                if(min > 0){
                    min--;
                    percent = Math.floor(percent - 0.8);
                } else {
                    min = 59;
                    percent = Math.floor(percent - 0.8);
                    hours--;
                    if(hours < 0){
                        fin = true;
                        hours = min = secs = 0;
                    }
                }
            }



            this.setState(prevState => ({
                hours, min , secs , fin, percent
            }))    
        }, 1000);
    }

<div className="container">
          <div className="row">
              <div className="col-sm-3 col-md-2">
                  <div className="progress" data-percentage={this.state.percent}>
                      <span className="progress-left">
                          <span className="progress-bar"></span>
                      </span>
                      <span className="progress-right">
                          <span className="progress-bar"></span>
                      </span>
                      <div className="progress-value">
                          <div>
                          {this.state.hours}:{this.state.min}<br/>
                              <span>Time Left</span>
                          </div>
                      </div>
                  </div>
              </div></div></div>

SASS

$borderWidth: 7px;
$animationTime: 1.5s;
$border-color-default: #eee;
$border-color-fill: #ffb43e;
$size: 150px;

//Create how many steps
$howManySteps: 10; //this needs to be even. 
//for fun try using 20 and changine in the HTML the data-percentage to 15 or 85

.progress {
  width: $size;
  height: $size;
  line-height: $size;
  background: none;
  margin: 0 auto;
  box-shadow: none;
  position: relative;
  &:after {
    content: "";
    width: 100%;
    height: 100%;
    border-radius: 50%;
    border: $borderWidth solid $border-color-default;
    position: absolute;
    top: 0;
    left: 0;
  }
  > span {
    width: 50%;
    height: 100%;
    overflow: hidden;
    position: absolute;
    top: 0;
    z-index: 1;
  }
  .progress-left {
    left: 0;
  }
  .progress-bar {
    width: 100%;
    height: 100%;
    background: none;
    border-width: $borderWidth;
    border-style: solid;
    position: absolute;
    top: 0;
    border-color: $border-color-fill;
  }
  .progress-left .progress-bar {
    left: 100%;
    border-top-right-radius: ($size/2);;
    border-bottom-right-radius: ($size/2);;
    border-left: 0;
    -webkit-transform-origin: center left;
    transform-origin: center left;
    //animation: loading-2 1.5s linear forwards 1.8s;
  }
  .progress-right {
    right: 0;
    .progress-bar {
      left: -100%;
      border-top-left-radius: ($size/2);;
      border-bottom-left-radius: ($size/2);;
      border-right: 0;
      -webkit-transform-origin: center right;
      transform-origin: center right;
      //animation: loading-1 1.8s linear forwards;
    }
  }
  .progress-value {
    display: flex;
    border-radius: 50%;
    font-size: 28px;
    text-align: center;
    line-height: 20px;
    align-items: center;
    justify-content: center;
    height: 100%;
    //font-family: $work-sans;
    font-weight: 300;
    div {
      margin-top: 10px;
    }
    span {
      font-size: 12px;
      text-transform: uppercase;
    }
  }
}

/* This for loop creates the    necessary css animation names 
Due to the split circle of progress-left and progress right, we must use the animations on each side. 
*/
@for $i from 1 through $howManySteps {
    $stepName: ($i*(100 / $howManySteps));

    //animation only the left side if below 50%
    @if $i <= ($howManySteps/2) { 
        .progress[data-percentage="#{$stepName}"] {
            .progress-right .progress-bar {
                 animation: loading-#{$i} $animationTime linear forwards;
            }
            .progress-left .progress-bar {animation: 0;}
        }
    }
    //animation only the right side if above 50%
    @if $i > ($howManySteps/2)  {  
        .progress[data-percentage="#{$stepName}"] {
            .progress-right .progress-bar {
                animation: loading-#{($howManySteps/2)} $animationTime linear forwards; //set the animation to longest animation
            }
            .progress-left .progress-bar {
      animation: loading-#{$i - ($howManySteps/2)} $animationTime linear forwards $animationTime;
    }
        }
    }
}

//animation
@for $i from 1 through ($howManySteps/2) { 
    $degrees: (180/($howManySteps/2));
    $degrees: ($degrees*$i);
    @keyframes loading-#{$i}{
    0%{
        -webkit-transform: rotate(0deg);
        transform: rotate(0deg);
    }
    100%{
        -webkit-transform: rotate($degrees);
            transform: rotate(#{$degrees}deg);
    }
    }
}
//additional styling
.progress {
        margin-bottom: 1em;
    }
...