Css和js圈倒计时进度

时间:2018-05-03 11:32:18

标签: jquery html css

我希望创建一个在计时器倒计时时填充的圆圈,因此如果计时器在10秒后设置为刷新并且还剩5秒,则只会填充半个圆圈。它越接近100%,圆圈就越多。我的代码显示填充的圆圈,不应该100%填充,当计时器倒计时,圆圈移动看起来像一个中心圈。



	var interval = null;
	var secondsInHour = 60 * 60;
	var secondsInMinute = 60;

	$('#refresh-rate-chooser').change(function() {

	    if (interval) {
	        clearInterval(interval);
	    }
	    var countdownSeconds = $(this).find("option:selected").val();
	    var countdownSecondsOriginal = countdownSeconds;
	    
	    if (countdownSeconds && countdownSeconds > 0) {

	        interval = setInterval(function() {
	            countdownSeconds--;
	            var latestCountdownSeconds = $(this).find("option:selected").val();
	            var percent = (countdownSecondsOriginal - countdownSeconds) / countdownSecondsOriginal * 100;
				console.log("countdownSeconds " + countdownSeconds);
				if (percent == undefined) {
					percent = 0;
				}
				var deg = 360 * percent/100;
				if (percent > 50) {
					$(".progress-circle").addClass('gt-50');
				}
	            $(".progress-circle").find('.progress-circle-fill').css('transform','rotate('+ deg +'deg)');
	    
	            if (countdownSeconds == 0) {
	                var formElements = $('form').serialize();

	                if (window.location.href.indexOf("?") < 0) {
	                    window.location.href = encodeURI(window.location.href + "?refreshrate=" + copyCountdownSeconds + "&" + formElements);
	                } else {
	                    var currentHref = replaceUrlParam(window.location.href, "refreshrate", copyCountdownSeconds);
	                    $('form input, form select').each(
	                        function(index) {
	                            var input = $(this);
	                            currentHref = replaceUrlParam(currentHref, input.attr('name'), input.val());
	                        }
	                    );
	                    window.location.href = currentHref;
	                }
	            }

	        }, 1000);
	    } else {


	    }
	});
	
&#13;
.countdown-progress {
    content: "";
    position: relative;
    margin: 1em;
    background-color: #81CE97;
    overflow: hidden;
}

.progress-circle .progress-circle-fill {
    content: "";
    position: absolute;
    border-radius: 50%;
    -webkit-transform-origin: 50% 100%;
    -moz-transform-origin: 50% 100%;
    -ms-transform-origin: 50% 100%;
    transform-origin: 50% 100%;
    -webkit-transform: rotate(140deg);
    -moz-transform: rotate(140deg);
    -ms-transform: rotate(140deg);
    transform: rotate(140deg);
    width: 4em;
    height: 4em;
    background: #81CE97;
}

.gt-50 .progress-circle {
    clip: rect(0, 2em, 4em, 0);
}

.gt-50 .progress-circle .progress-circle-fill {
    clip: rect(0, 4em, 4em, 2em);
    background: #E5E5E5;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="refresh-rate">
    <select id="refresh-rate-chooser" name="refreshRateChooser">
        <option value="0" selected>-</option>
        <option value="10">10 secs</option>
        <option value="30">30 secs</option>
        <option value="60">1 min</option>
        <option value="120">2 mins</option>
        <option value="300">5 mins</option>
        <option value="600">10 mins</option>
    </select>
    <input type="hidden" id="refreshrate" name="refreshrate" value="0" />
    <div id="countdown-progress">
        <div class="progress-circle text-center">
            <div class="progress-circle-fill" ></div>
        </div>
    </div>



</div>
&#13;
&#13;
&#13;

我似乎无法锻炼哪些代码是错误的。要测试此项,请更改选择选项,然后圆圈将移动。我原来是以圆环图为基础的,这可能是计算失效的原因。

1 个答案:

答案 0 :(得分:1)

我认为这就是你想要的。它不是使用CSS而是通过JavaScript创建SVG路径。请参阅以下评论。

进一步阅读:
SVG Tutorial From MDN
Interface SVGPathSegArcAbs From W3C Recommendation

let x = 100, // center point of the circle
    y = 100, // cneter point of the circle
    r = 50, // radius of the circle
    start = 0, // start degree
    end = 360, // end degree
    fillColor = '#81CE97', // fill color of the circle
    timers = [], // all of the times
    path = document.querySelector('path'), // path element
    circle = document.querySelector('circle'), // circle element
    timeSelect = document.querySelector('select'); // select element

// clear all of the times
function ClearTimers(timers) {
  timers.forEach(function(timer) {
    clearTimeout(timer);
  })
}

// reset the circle
function ResetCircle() {
  path.setAttribute('display', 'none');
  circle.setAttribute('display', '');
}

// calculate the point of the svg A parameters
function CalculatePoint(centerX, centerY, radius, degree) {
  // convert degree to radians
  // decrease 90 degrees to start from y axis
  let radians = (degree - 90) * 2 * Math.PI / 360.0,
      point = {
        x: centerX + radius * Math.cos(radians),
        y: centerY + radius * Math.sin(radians),
      }
  return point;
}

// create a circle
function CreateCircle(centerX, centerY, radius, startDegree, endDegree) {
  let startPoint = CalculatePoint(centerX, centerY, radius, endDegree),
      endPoint = CalculatePoint(centerX, centerY, radius, startDegree),
      largeArcFlag = endDegree - startDegree <= 180 ? 0 : 1,
      displayDegree = endDegree - startDegree;

  if (displayDegree % 360 == 0 && displayDegree != 0) {
    path.setAttribute('display', 'none');

    circle.setAttribute('display', '');
    circle.setAttribute('r', radius);
    circle.setAttribute('cx', centerX);
    circle.setAttribute('cy', centerY);
    circle.setAttribute('fill', fillColor);
  } else {
    path.setAttribute('display', '');
    circle.setAttribute('display', 'none');

    d = `M ${startPoint.x} ${startPoint.y}
         A ${radius} ${radius} 0 ${largeArcFlag} 0 ${endPoint.x} ${endPoint.y}
         L ${centerX} ${centerY}
         L ${startPoint.x} ${startPoint.y} Z`;

    path = document.querySelector('path');
    path.setAttribute('d', d);
    path.setAttribute('fill', fillColor);
  }
}

// change event of the select that create several times counting down
timeSelect.addEventListener('change', function() {
  ClearTimers(timers)

  let seconds = this.value;

  // reset the circle
  if (seconds == 0) {
    ResetCircle();
    return;
  }

  // create timers
  for (let i = 0; i <= seconds; i++) {
    timers.push(setTimeout(function() {
      let deg = end * (seconds - i) / seconds;
      CreateCircle(x, y, r, start, deg);
    }, i * 1000))
  }
})

// initialize the circle
CreateCircle(x, y, r, start, end);
svg {
  width: 200px;
  height: 200px;
}
<svg>
  <circle></circle>
  <path d=""></path>
</svg>
<select>
  <option value="0" selected>-</option>
  <option value="10">10 secs</option>
  <option value="30">30 secs</option>
  <option value="60">1 min</option>
  <option value="120">2 mins</option>
  <option value="300">5 mins</option>
  <option value="600">10 mins</option>
</select>