我希望创建一个在计时器倒计时时填充的圆圈,因此如果计时器在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;
我似乎无法锻炼哪些代码是错误的。要测试此项,请更改选择选项,然后圆圈将移动。我原来是以圆环图为基础的,这可能是计算失效的原因。
答案 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>