Files
motioner/index.html
2025-09-11 18:32:41 +08:00

292 lines
8.7 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>性能监控</title>
<style>
body {
width: 100%;
height: 100%;
margin: 0;
padding: 20px;
font-family: 'Segoe UI', Arial, sans-serif;
color: black;
border-radius: 8px;
transition: all 0.3s ease;
user-select: none;
box-sizing: border-box;
overflow: hidden;
}
.drag-bar {
height: 32px;
background: rgba(255, 255, 255, 0.5);
border-radius: 4px;
-webkit-app-region: drag;
margin-bottom: 15px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
backdrop-filter: blur(10px);
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.controls {
-webkit-app-region: no-drag;
}
button {
background: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(0, 0, 0, 0.2);
color: black;
padding: 5px 10px;
border-radius: 4px;
cursor: pointer;
backdrop-filter: blur(5px);
transition: all 0.2s ease;
font-family: 'Segoe UI', Arial, sans-serif;
font-size: 12px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
button:hover {
background: rgba(255, 255, 255, 1);
border: 1px solid rgba(0, 0, 0, 0.3);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}
button:active {
background: rgba(240, 240, 240, 1);
border: 1px solid rgba(0, 0, 0, 0.25);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05) inset;
}
.metrics {
font-size: 14px;
display: grid;
grid-template-columns: 1fr;
gap: 10px;
}
.metric-item {
margin: 0;
padding: 4px 0;
border-radius: 6px;
transition: all 0.2s ease;
padding: 10px 14px;
background: rgba(255, 255, 255, 0.7);
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
display: flex;
justify-content: space-between;
align-items: center;
}
.metric-item:hover {
background: rgba(255, 255, 255, 0.9);
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.metric-label {
font-weight: 500;
}
.metric-value {
font-weight: 600;
font-size: 1.1em;
}
.settings {
margin-top: 15px;
padding-top: 10px;
border-top: 1px solid rgba(200, 200, 200, 0.1);
}
input[type='checkbox'] {
accent-color: #0078d4;
}
/* 动画类 */
.window-container {
transition: all 0.3s ease;
}
.minimized {
transform: scale(0.1);
opacity: 0.7;
}
/* 响应式设计 */
@media (max-width: 350px) {
.metrics {
grid-template-columns: 1fr 1fr;
}
.metric-value {
font-weight: 600;
font-size: 0.8em;
}
body {
padding: 20px;
}
}
@media (max-width: 150px) {
.metrics {
grid-template-columns: 1fr;
font-size: 10px;
gap: 3px;
}
body {
padding: 5px;
}
}
</style>
</head>
<body>
<div class="window-container" id="window-container">
<!-- 拖动区域 -->
<div style="-webkit-app-region: drag; position: absolute; top: 0; left: 0; right: 0; height: 30px; z-index: -1"></div>
<div class="metrics">
<div class="metric-item">
<span class="metric-label">CPU</span>
<span class="metric-value" id="cpu">0%</span>
</div>
<div class="metric-item">
<span class="metric-label">内存</span>
<span class="metric-value" id="memory">0%</span>
</div>
<div class="metric-item">
<span class="metric-label">网络</span>
<span class="metric-value" id="network">0 KB/s</span>
</div>
<div class="metric-item">
<span class="metric-label">GPU</span>
<span class="metric-value" id="gpu">0%</span>
</div>
<div class="metric-item">
<span class="metric-label">显存</span>
<span class="metric-value" id="gpu-memory">0 MB</span>
</div>
</div>
</div>
<script>
// 引入性能监控库
const si = require('systeminformation')
const pidusage = require('pidusage')
const process = require('process')
// 获取元素
const cpuEl = document.getElementById('cpu')
const memoryEl = document.getElementById('memory')
const networkEl = document.getElementById('network')
const gpuEl = document.getElementById('gpu')
const gpuMemoryEl = document.getElementById('gpu-memory')
// 跟踪窗口聚焦状态
let isWindowFocused = true;
let lastUpdateTime = 0;
// 监听窗口聚焦/失焦事件
const { ipcRenderer } = require('electron');
ipcRenderer.on('window-focused', () => {
isWindowFocused = true;
});
ipcRenderer.on('window-blurred', () => {
isWindowFocused = false;
});
// 监听主进程发送的GPU信息
ipcRenderer.on('gpu-info', (event, gpuInfo) => {
// 过滤掉任何剩余的虚拟GPU信息
const physicalGpus = gpuInfo.filter(gpu => {
// 检查是否为虚拟GPU
const isVirtual = gpu.name.includes('Oray') || gpu.name.includes('Virtual') || gpu.name.includes('Software')
return !isVirtual && (gpu.memoryUsed !== undefined || gpu.vram !== undefined)
})
if (physicalGpus && physicalGpus.length > 0) {
// 显示第一个物理GPU的显存使用情况
const gpu = physicalGpus[0]
// 优先使用memoryUsed和memoryTotal如果没有则使用vram
if (gpu.memoryUsed !== undefined && gpu.memoryTotal !== undefined) {
// 转换为MB单位
const usedMB = Math.round(gpu.memoryUsed)
const totalMB = Math.round(gpu.memoryTotal)
gpuMemoryEl.textContent = usedMB + ' / ' + totalMB + ' MB'
} else if (gpu.vram !== undefined) {
// 如果只有vram信息显示总显存
const totalMB = Math.round(gpu.vram)
gpuMemoryEl.textContent = '总共: ' + totalMB + ' MB'
} else {
gpuMemoryEl.textContent = 'N/A'
}
} else {
gpuMemoryEl.textContent = 'N/A'
}
})
// 使用requestAnimationFrame实现性能数据更新
let lastTime = 0;
const focusedUpdateInterval = 200; // 聚焦时200ms更新一次
const blurredUpdateInterval = 2000; // 失焦时2秒更新一次
async function updatePerformanceData(timestamp) {
// 根据窗口聚焦状态确定更新间隔
const updateInterval = isWindowFocused ? focusedUpdateInterval : blurredUpdateInterval;
if (timestamp - lastTime >= updateInterval) {
try {
// 获取CPU使用率
const cpuData = await si.currentLoad();
const cpuUsage = Math.round(cpuData.currentLoad);
// 获取内存使用率
const memData = await si.mem();
const memoryUsage = Math.round((memData.active / memData.total) * 100);
// 获取进程内存使用率
const pid = process.pid;
const pidData = await pidusage(pid);
const processMemory = Math.round(pidData.memory / 1024 / 1024); // 转换为MB
// 获取网络使用情况
const networkData = await si.networkStats();
const networkUsage = networkData[0] ? Math.round((networkData[0].rx_sec + networkData[0].tx_sec) / 1024) : 0; // KB/s
// 获取GPU使用率
const gpuData = await si.graphics();
let gpuUsage = 0;
if (gpuData.controllers && gpuData.controllers.length > 0) {
// 尝试获取GPU使用率如果没有则使用默认值
gpuUsage = gpuData.controllers[0].utilizationMemory || gpuData.controllers[0].fanSpeed || 0;
}
// 更新UI
cpuEl.textContent = cpuUsage + '%';
memoryEl.textContent = memoryUsage + '%';
networkEl.textContent = networkUsage + ' KB/s';
gpuEl.textContent = gpuUsage + '%';
} catch (error) {
console.error('获取性能数据时出错:', error);
}
lastTime = timestamp;
}
requestAnimationFrame(updatePerformanceData);
}
// 启动动画循环
requestAnimationFrame(updatePerformanceData)
</script>
</body>
</html>