fix: 进度条平滑过渡 — force reflow 技巧确保 CSS transition 生效
- 临时关 transition → 设旧值 → offsetWidth reflow → 开 transition → 设新值 - DOM 复用: 首次 innerHTML 创建, 后续只改属性 - 进度条从旧值滑到新值, 不再闪现 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -262,5 +262,27 @@
|
|||||||
"framework.command.execute"
|
"framework.command.execute"
|
||||||
],
|
],
|
||||||
"timestamp": 27544.2709947
|
"timestamp": 27544.2709947
|
||||||
|
},
|
||||||
|
"29ffcf99": {
|
||||||
|
"plugin_name": "example_plugin",
|
||||||
|
"permissions": [
|
||||||
|
"plugin.example.read",
|
||||||
|
"plugin.example.write",
|
||||||
|
"plugin.example.execute",
|
||||||
|
"framework.event.subscribe",
|
||||||
|
"framework.command.execute"
|
||||||
|
],
|
||||||
|
"timestamp": 27821.237625479
|
||||||
|
},
|
||||||
|
"bd46f35e": {
|
||||||
|
"plugin_name": "sentinel",
|
||||||
|
"permissions": [
|
||||||
|
"plugin.sentinel.read",
|
||||||
|
"plugin.sentinel.write",
|
||||||
|
"plugin.network.access",
|
||||||
|
"framework.event.subscribe",
|
||||||
|
"framework.command.execute"
|
||||||
|
],
|
||||||
|
"timestamp": 27821.239961313
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ commands:
|
|||||||
permissions:
|
permissions:
|
||||||
- framework.command.test
|
- framework.command.test
|
||||||
source: internal
|
source: internal
|
||||||
last_updated: 27544.226537616
|
last_updated: 27821.221132094
|
||||||
plugin_commands:
|
plugin_commands:
|
||||||
example_plugin:
|
example_plugin:
|
||||||
echo: *id001
|
echo: *id001
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
http_port: 4200
|
http_port: 4200
|
||||||
last_updated: 27544.261331002
|
last_updated: 27821.238246209
|
||||||
plugin_routes:
|
plugin_routes:
|
||||||
example_plugin:
|
example_plugin:
|
||||||
- methods:
|
- methods:
|
||||||
|
|||||||
@@ -164,27 +164,41 @@
|
|||||||
var oldMem = parseFloat((body.getAttribute('data-mem')||memVal));
|
var oldMem = parseFloat((body.getAttribute('data-mem')||memVal));
|
||||||
body.setAttribute('data-cpu', cpuVal);
|
body.setAttribute('data-cpu', cpuVal);
|
||||||
body.setAttribute('data-mem', memVal);
|
body.setAttribute('data-mem', memVal);
|
||||||
body.innerHTML =
|
var isNew = !body.querySelector('.cpu-val');
|
||||||
'<div class="metric-row">'+
|
if (isNew) {
|
||||||
'<div class="metric"><div class="metric-label">CPU</div><div class="metric-value cpu-val">'+oldCpu.toFixed(1)+'%</div><div class="metric-bar"><div class="metric-bar-fill '+cpuBarCls+'" style="width:'+oldCpu+'%"></div></div></div>'+
|
body.innerHTML =
|
||||||
'<div class="metric"><div class="metric-label">MEM</div><div class="metric-value mem-val">'+oldMem.toFixed(1)+'%</div><div class="metric-bar"><div class="metric-bar-fill '+memBarCls+'" style="width:'+oldMem+'%"></div></div></div>'+
|
'<div class="metric-row">'+
|
||||||
'</div>'+
|
'<div class="metric"><div class="metric-label">CPU</div><div class="metric-value cpu-val">0%</div><div class="metric-bar"><div class="metric-bar-fill" style="width:0%"></div></div></div>'+
|
||||||
'<div class="metric-row">'+
|
'<div class="metric"><div class="metric-label">MEM</div><div class="metric-value mem-val">0%</div><div class="metric-bar"><div class="metric-bar-fill" style="width:0%"></div></div></div>'+
|
||||||
'<div class="metric"><div class="metric-label">NET ↓</div><div class="metric-value" style="font-size:.9rem">'+fmtSpeed(net.rx_bytes_sec||0)+'</div></div>'+
|
'</div>'+
|
||||||
'<div class="metric"><div class="metric-label">NET ↑</div><div class="metric-value" style="font-size:.9rem">'+fmtSpeed(net.tx_bytes_sec||0)+'</div></div>'+
|
'<div class="metric-row">'+
|
||||||
'</div>'+
|
'<div class="metric"><div class="metric-label">NET ↓</div><div class="metric-value net-down" style="font-size:.9rem"></div></div>'+
|
||||||
'<div style="font-size:.7rem;color:var(--text-dim);margin-top:8px">内存 '+(mem.used_gb||0).toFixed(1)+'/'+(mem.total_gb||0).toFixed(1)+' GB</div>';
|
'<div class="metric"><div class="metric-label">NET ↑</div><div class="metric-value net-up" style="font-size:.9rem"></div></div>'+
|
||||||
// 动画计数
|
'</div>'+
|
||||||
var cpuEl = body.querySelector('.cpu-val');
|
'<div class="mem-detail"></div>';
|
||||||
var memEl = body.querySelector('.mem-val');
|
}
|
||||||
animateValue(cpuEl, oldCpu, cpuVal, 1, '%');
|
// 更新 NET
|
||||||
animateValue(memEl, oldMem, memVal, 1, '%');
|
body.querySelector('.net-down').textContent = fmtSpeed(net.rx_bytes_sec||0);
|
||||||
// 进度条平滑过渡 (CSS transition 自动处理)
|
body.querySelector('.net-up').textContent = fmtSpeed(net.tx_bytes_sec||0);
|
||||||
requestAnimationFrame(function(){
|
body.querySelector('.mem-detail').innerHTML = '<div style="font-size:.7rem;color:var(--text-dim);margin-top:8px">内存 '+(mem.used_gb||0).toFixed(1)+'/'+(mem.total_gb||0).toFixed(1)+' GB</div>';
|
||||||
var fills = body.querySelectorAll('.metric-bar-fill');
|
// 进度条: 先设旧值 → force reflow → 设新值
|
||||||
if (fills[0]) { fills[0].style.width = cpuVal+'%'; fills[0].className = 'metric-bar-fill '+cpuBarCls; }
|
var barCpu = body.querySelectorAll('.metric-bar-fill')[0];
|
||||||
if (fills[1]) { fills[1].style.width = memVal+'%'; fills[1].className = 'metric-bar-fill '+memBarCls; }
|
var barMem = body.querySelectorAll('.metric-bar-fill')[1];
|
||||||
});
|
barCpu.style.transition = 'none';
|
||||||
|
barMem.style.transition = 'none';
|
||||||
|
barCpu.style.width = oldCpu+'%';
|
||||||
|
barMem.style.width = oldMem+'%';
|
||||||
|
barCpu.className = 'metric-bar-fill '+cpuBarCls;
|
||||||
|
barMem.className = 'metric-bar-fill '+memBarCls;
|
||||||
|
barCpu.offsetWidth; // force reflow
|
||||||
|
barMem.offsetWidth;
|
||||||
|
barCpu.style.transition = '';
|
||||||
|
barMem.style.transition = '';
|
||||||
|
barCpu.style.width = cpuVal+'%';
|
||||||
|
barMem.style.width = memVal+'%';
|
||||||
|
// 数字跳动
|
||||||
|
animateValue(body.querySelector('.cpu-val'), oldCpu, cpuVal, 1, '%');
|
||||||
|
animateValue(body.querySelector('.mem-val'), oldMem, memVal, 1, '%');
|
||||||
} else {
|
} else {
|
||||||
body.innerHTML = '<div style="color:var(--error);font-size:.85rem">'+(n.error||'离线')+'</div>';
|
body.innerHTML = '<div style="color:var(--error);font-size:.85rem">'+(n.error||'离线')+'</div>';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user