简体   繁体   English

圆形进度条 - CSS/JS

[英]Round Progress Bar - CSS/JS

I have this round progress bar that shows the progress of completed tasks.我有这个圆形进度条,显示已完成任务的进度。 On progress change, the bar increases/decreases over 0.5s.进度更改时,条形增加/减少超过 0.5 秒。 The bar itself is made out of 2 halves, so in my JS I had to add some extra functions to delay and change the transition time if, for example, you would have an uneven number of total tasks.条形图本身由两半组成,因此在我的 JS 中,我不得不添加一些额外的函数来延迟和更改转换时间,例如,如果您的总任务数是奇数。

Now, this all works just fine, until I "reconstruct" the progress bar (clicking the "reload" button) by just emptying the bar wrapper and appending all the divs and necessary data to re-display the bar with its current progress.现在,这一切都很好,直到我“重建”进度条(单击“重新加载”按钮),只需清空条形包装器并附加所有 div 和必要的数据,以重新显示进度条及其当前进度。 At this point, whenever the progress bar hits the midpoint, for some reason, the transition isn't smooth as prior to "reload", but if you refresh the page again, the transition (at midpoint) is all fine.此时,每当进度条到达中点时,由于某种原因,过渡不像“重新加载”之前那样平滑,但是如果您再次刷新页面,过渡(在中点)就可以了。 I have no clue why this happens...我不知道为什么会发生这种情况...

Here's the JSFiddle这是JSFiddle

UPDATE In the "on reload" in JS, I forgot to re-initialize "bar_transition = $('.circle .bar_transition .sub-progress')"更新在JS中的“重新加载”中,我忘记重新初始化“bar_transition = $('.circle .bar_transition .sub-progress')”

 function updateSubtaskProgressBar(subs_completed, total_subs, progress_bar_transition, toggle, mod, reload_btn) { var left_side = $(".sub-progress-bar_transition .circle .left .sub-progress"); var right_side = $(".sub-progress-bar_transition .circle .right .sub-progress"); progress = subs_completed / total_subs * 360; transition = 500; delay = transition / 2; rot_reminder = 0; if (progress < 180) { rot_right = 0; right_side.css({ 'transform': 'rotate(' + rot_right + 'deg)' }); rot_left = progress rot_reminder = 180 - rot_left if (rot_reminder != 0 && mod != 0 && toggle == 0) { progress_bar_transition.css({ 'transition': 'all ' + delay / 1000 + 's ease-in' }); setTimeout(function () { progress_bar_transition.css({ 'transition': 'all ' + delay / 1000 + 's ease-out' }); left_side.css({ 'transform': 'rotate(' + rot_left + 'deg)' }); }, delay); toggle = 1 - toggle reload_btn.data('toggle', toggle) } else { progress_bar_transition.css({ 'transition': 'all ' + transition / 1000 + 's ease-in-out' }); left_side.css({ 'transform': 'rotate(' + rot_left + 'deg)' }); } } else { rot_left = 180; left_side.css({ 'transform': 'rotate(' + rot_left + 'deg)' }); rot_right = progress - 180; rot_reminder = rot_right if (rot_reminder != 0 && mod != 0 && toggle == 1) { progress_bar_transition.css({ 'transition': 'all ' + delay / 1000 + 's ease-in' }); setTimeout(function () { progress_bar_transition.css({ 'transition': 'all ' + delay / 1000 + 's ease-out' }); right_side.css({ 'transform': 'rotate(' + rot_right + 'deg)' }); }, delay); toggle = 1 - toggle reload_btn.data('toggle', toggle) } else { progress_bar_transition.css({ 'transition': 'all ' + transition / 1000 + 's ease-in-out' }); right_side.css({ 'transform': 'rotate(' + rot_right + 'deg)' }); } } } function setSubtaskProgressBar(subs_completed, total_subs, bar_transition) { modulo = 0; current_progress = 0; var left_side = $(".sub-progress-bar_transition .circle .left .sub-progress"); var right_side = $(".sub-progress-bar_transition .circle .right .sub-progress"); modulo = total_subs%2 current_progress = subs_completed / total_subs * 360; var reload = $('.reload') reload.data('completed', subs_completed) reload.data('total', total_subs) reload.data('modulo', modulo) if (current_progress < 180) { rot_left = current_progress rot_right = 0 left_side.css({ 'transform': 'rotate(' + rot_left + 'deg)' }); reload.data('toggle', 1) } else { rot_left = 180 rot_right = current_progress - 180 left_side.css({ 'transform': 'rotate(' + rot_left + 'deg)' }); right_side.css({ 'transform': 'rotate(' + rot_right + 'deg)' }); reload.data('toggle', 0) } bar_transition.css({ 'transition': 'none' }); } $(document).ready(function () { subs_completed = 3; total_subs = 5; bar_transition = $('.circle .bar_transition .sub-progress') number = $('.number') number.html(subs_completed + '/' + total_subs) setSubtaskProgressBar(subs_completed, total_subs, bar_transition) $(document).on('click', '.add', function () { subs_completed += 1 $('.number').html(subs_completed + '/' + total_subs) reload = $('.reload') reload.data('completed', subs_completed) modulo = reload.data('modulo') toggle = reload.data('toggle') total = reload.data('total') updateSubtaskProgressBar(subs_completed, total, bar_transition, toggle, modulo, reload) }) $(document).on('click', '.remove', function () { subs_completed -= 1; $('.number').html(subs_completed + '/' + total_subs) reload = $('.reload') reload.data('completed', subs_completed) modulo = reload.data('modulo') toggle = reload.data('toggle') total = reload.data('total') updateSubtaskProgressBar(subs_completed, total, bar_transition, toggle, modulo, reload) }) $(document).on('click', '.reload', function () { num = $(this).data('completed') + '/' + $(this).data('total') data = '<div class="subtask-circular-progress sub-progress-bar_transition" data-completed="'+$(this).data('completed')+'" data-total="'+$(this).data('total')+'" data-modulo="'+$(this).data('modulo')+'" data-toggle="'+$(this).data('toggle')+'"><div class="inner"></div><div class="number">'+num+'</div><div class="circle"><div class="bar_transition left"><div class="sub-progress"></div></div><div class="bar_transition right"><div class="sub-progress"></div></div></div></div>' wrapper = $('.wrapper').empty(); wrapper.append(data) setSubtaskProgressBar(subs_completed, total_subs, bar_transition) console.log('reload') }) });
 body{ background-color: #333; } .subtask-circular-progress { position: absolute; left: 50%; top: 40%; height: 100px; width: 100px; background-color: red; } .subtask-circular-progress .inner { position: absolute; z-index: 6; top: 50%; left: 50%; height: 80px; width: 80px; margin: -40px 0 0 -40px; border-radius: 100%; background: #454545; } .subtask-circular-progress .number { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 10; font-size: 15px; font-weight: 500; color: white; } .subtask-circular-progress .bar_transition { position: absolute; height: 100%; width: 100%; background: #fff; -webkit-border-radius: 100%; border-radius: 100%; clip: rect(0px, 100px, 100px, 50px); } .circle .bar_transition .sub-progress { position: absolute; height: 100%; width: 100%; -webkit-border-radius: 100%; border-radius: 100%; clip: rect(0px, 50px, 100px, 0px); background: #4158d0; transition: all 0.5s ease-in-out; } .circle .left .sub-progress { transform: rotate(0deg); } .circle .right { transform: rotate(180deg); z-index: 3; } .circle .right .sub-progress { transform: rotate(0deg); } .buttons{ position: absolute; left: 50%; top: 60%; }
 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="wrapper"> <div class="subtask-circular-progress sub-progress-bar_transition"> <div class="inner"></div> <div class="number">100%</div> <div class="circle"> <div class="bar_transition left"> <div class="sub-progress"></div> </div> <div class="bar_transition right"> <div class="sub-progress"></div> </div> </div> </div> </div> <div class="d-flex buttons"> <button type="button" class="btn btn-success add">+</button> <button type="button" class="btn btn-success remove ms-4">-</button> <button type="button" class="btn btn-success reload ms-4" data-completed="" data-total="" data-modulo="" data-toggle="">reload</button> </div>

The issue was tricky to find, but you are referring to the bar_transition global variable after that the relative content of the DOM is deleted.这个问题很难找到,但是在删除 DOM 的相关内容之后,您指的是bar_transition全局变量。

After the DOM replacement, the content of bar_transition does not reflect the DOM anymore, is lost. DOM替换后, bar_transition的内容不再反映DOM,丢失了。

You need to manually update the content of the variable is the reload callback:您需要手动更新变量的内容是重新加载回调:

bar_transition = $('.circle .bar_transition .sub-progress');

 function updateSubtaskProgressBar(subs_completed, total_subs, progress_bar_transition, toggle, mod, reload_btn) { var left_side = $(".sub-progress-bar_transition .circle .left .sub-progress"); var right_side = $(".sub-progress-bar_transition .circle .right .sub-progress"); progress = subs_completed / total_subs * 360; transition = 500; delay = transition / 2; rot_reminder = 0; if (progress < 180) { rot_right = 0; right_side.css({ 'transform': 'rotate(' + rot_right + 'deg)' }); rot_left = progress rot_reminder = 180 - rot_left if (rot_reminder != 0 && mod != 0 && toggle == 0) { progress_bar_transition.css({ 'transition': 'all ' + delay / 1000 + 's ease-in' }); setTimeout(function () { progress_bar_transition.css({ 'transition': 'all ' + delay / 1000 + 's ease-out' }); left_side.css({ 'transform': 'rotate(' + rot_left + 'deg)' }); }, delay); toggle = 1 - toggle reload_btn.data('toggle', toggle) } else { progress_bar_transition.css({ 'transition': 'all ' + transition / 1000 + 's ease-in-out' }); left_side.css({ 'transform': 'rotate(' + rot_left + 'deg)' }); } } else { rot_left = 180; left_side.css({ 'transform': 'rotate(' + rot_left + 'deg)' }); rot_right = progress - 180; rot_reminder = rot_right if (rot_reminder != 0 && mod != 0 && toggle == 1) { progress_bar_transition.css({ 'transition': 'all ' + delay / 1000 + 's ease-in' }); setTimeout(function () { progress_bar_transition.css({ 'transition': 'all ' + delay / 1000 + 's ease-out' }); right_side.css({ 'transform': 'rotate(' + rot_right + 'deg)' }); }, delay); toggle = 1 - toggle reload_btn.data('toggle', toggle) } else { progress_bar_transition.css({ 'transition': 'all ' + transition / 1000 + 's ease-in-out' }); right_side.css({ 'transform': 'rotate(' + rot_right + 'deg)' }); } } } function setSubtaskProgressBar(subs_completed, total_subs, bar_transition) { modulo = 0; current_progress = 0; var left_side = $(".sub-progress-bar_transition .circle .left .sub-progress"); var right_side = $(".sub-progress-bar_transition .circle .right .sub-progress"); modulo = total_subs%2 current_progress = subs_completed / total_subs * 360; var reload = $('.reload') reload.data('completed', subs_completed) reload.data('total', total_subs) reload.data('modulo', modulo) if (current_progress < 180) { rot_left = current_progress rot_right = 0 left_side.css({ 'transform': 'rotate(' + rot_left + 'deg)' }); reload.data('toggle', 1) } else { rot_left = 180 rot_right = current_progress - 180 left_side.css({ 'transform': 'rotate(' + rot_left + 'deg)' }); right_side.css({ 'transform': 'rotate(' + rot_right + 'deg)' }); reload.data('toggle', 0) } bar_transition.css({ 'transition': 'none' }); } $(document).ready(function () { subs_completed = 3; total_subs = 5; bar_transition = $('.circle .bar_transition .sub-progress') number = $('.number') number.html(subs_completed + '/' + total_subs) setSubtaskProgressBar(subs_completed, total_subs, bar_transition) $(document).on('click', '.add', function () { subs_completed += 1 $('.number').html(subs_completed + '/' + total_subs) reload = $('.reload') reload.data('completed', subs_completed) modulo = reload.data('modulo') toggle = reload.data('toggle') total = reload.data('total') updateSubtaskProgressBar(subs_completed, total, bar_transition, toggle, modulo, reload) }) $(document).on('click', '.remove', function () { subs_completed -= 1; $('.number').html(subs_completed + '/' + total_subs) reload = $('.reload') reload.data('completed', subs_completed) modulo = reload.data('modulo') toggle = reload.data('toggle') total = reload.data('total') updateSubtaskProgressBar(subs_completed, total, bar_transition, toggle, modulo, reload) }) $(document).on('click', '.reload', function () { num = $(this).data('completed') + '/' + $(this).data('total') data = '<div class="subtask-circular-progress sub-progress-bar_transition" data-completed="'+$(this).data('completed')+'" data-total="'+$(this).data('total')+'" data-modulo="'+$(this).data('modulo')+'" data-toggle="'+$(this).data('toggle')+'"><div class="inner"></div><div class="number">'+num+'</div><div class="circle"><div class="bar_transition left"><div class="sub-progress"></div></div><div class="bar_transition right"><div class="sub-progress"></div></div></div></div>' wrapper = $('.wrapper').empty(); wrapper.append(data) // Fix is here! bar_transition = $('.circle .bar_transition .sub-progress'); setSubtaskProgressBar(subs_completed, total_subs, bar_transition) console.log('reload') }) });
 body{ background-color: #333; } .subtask-circular-progress { position: absolute; left: 50%; top: 40%; height: 100px; width: 100px; background-color: red; } .subtask-circular-progress .inner { position: absolute; z-index: 6; top: 50%; left: 50%; height: 80px; width: 80px; margin: -40px 0 0 -40px; border-radius: 100%; background: #454545; } .subtask-circular-progress .number { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 10; font-size: 15px; font-weight: 500; color: white; } .subtask-circular-progress .bar_transition { position: absolute; height: 100%; width: 100%; background: #fff; -webkit-border-radius: 100%; border-radius: 100%; clip: rect(0px, 100px, 100px, 50px); } .circle .bar_transition .sub-progress { position: absolute; height: 100%; width: 100%; -webkit-border-radius: 100%; border-radius: 100%; clip: rect(0px, 50px, 100px, 0px); background: #4158d0; transition: all 0.5s ease-in-out; } .circle .left .sub-progress { transform: rotate(0deg); } .circle .right { transform: rotate(180deg); z-index: 3; } .circle .right .sub-progress { transform: rotate(0deg); } .buttons{ position: absolute; left: 50%; top: 60%; }
 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="wrapper"> <div class="subtask-circular-progress sub-progress-bar_transition"> <div class="inner"></div> <div class="number">100%</div> <div class="circle"> <div class="bar_transition left"> <div class="sub-progress"></div> </div> <div class="bar_transition right"> <div class="sub-progress"></div> </div> </div> </div> </div> <div class="d-flex buttons"> <button type="button" class="btn btn-success add">+</button> <button type="button" class="btn btn-success remove ms-4">-</button> <button type="button" class="btn btn-success reload ms-4" data-completed="" data-total="" data-modulo="" data-toggle="">reload</button> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM