diff --git a/public/fourbar_test.html b/public/fourbar_test.html index ffd7866..6fc9b2e 100644 --- a/public/fourbar_test.html +++ b/public/fourbar_test.html @@ -841,6 +841,7 @@ let scanAnimation = { active: false, frame: 0, + direction: 1, timer: 0, intervalId: null, }; @@ -1318,18 +1319,30 @@ function animateScanFrame() { const validRows = latestScan.filter((row) => row.ok); if (!validRows.length) { - pauseScanAnimation(); + stopScanAnimation(); return; } - const row = validRows[scanAnimation.frame % validRows.length]; + const clampedFrame = Math.max(0, Math.min(scanAnimation.frame, validRows.length - 1)); + const row = validRows[clampedFrame]; const input = { ...readInput(), startValue: row.inputValue }; renderThreeMechanism( row.points, input, { title: "扫描播放中", value: row.inputValue }, ); - scanAnimation.frame += 1; + + if (validRows.length <= 1) { + scanAnimation.frame = 0; + return; + } + + if (clampedFrame >= validRows.length - 1) { + scanAnimation.direction = -1; + } else if (clampedFrame <= 0) { + scanAnimation.direction = 1; + } + scanAnimation.frame = clampedFrame + scanAnimation.direction; } // 开始播放已扫描的接口点位。 @@ -1345,19 +1358,27 @@ } scanAnimation.active = true; scanAnimation.timer = 0; + scanAnimation.direction = scanAnimation.direction || 1; animateScanFrame(); scanAnimation.intervalId = window.setInterval(animateScanFrame, 120); setMessage("正在播放扫描点位动画", "is-ok"); } - // 暂停 3D 扫描动画。 - function pauseScanAnimation() { + // 停止 3D 扫描动画,可选择是否刷新提示文案。 + function stopScanAnimation(options = {}) { scanAnimation.active = false; if (scanAnimation.intervalId) { clearInterval(scanAnimation.intervalId); scanAnimation.intervalId = null; } - setMessage("3D 动画已暂停", "is-ok"); + if (options.showMessage) { + setMessage("3D 动画已暂停", "is-ok"); + } + } + + // 暂停 3D 扫描动画。 + function pauseScanAnimation() { + stopScanAnimation({ showMessage: true }); } // 加载并初始化 WASM 模块。 @@ -1588,7 +1609,7 @@ true, ); - renderThreeMechanism(points, input, { fitCamera: true, value: frame.inputValue ?? input.startValue }); + renderThreeMechanism(points, input, { value: frame.inputValue ?? input.startValue }); } // 渲染仿真扫描汇总图。 @@ -1654,6 +1675,7 @@ // 执行当前角度的单次接口验证。 async function runOnce() { try { + stopScanAnimation(); setMessage(""); requestStatus.textContent = "执行中"; requestStatus.className = "badge warn"; @@ -1670,11 +1692,9 @@ renderSummary(response, input); renderChecks(response, input); if (response.res_data && response.res_data.success) { - scanAnimation.active = false; renderMechanismChart(response, input); setMessage("接口调用完成,当前姿态已刷新", "is-ok"); } else { - scanAnimation.active = false; setMessage(response.res_data?.error || response.msg || "接口返回业务失败", "is-error"); } requestStatus.textContent = "已执行"; @@ -1691,6 +1711,7 @@ // 调用批量仿真接口,生成轨迹和位移曲线。 async function runScan() { try { + stopScanAnimation(); setMessage(""); const baseInput = readInput(); const stepTime = Number(stepInput.value); @@ -1736,6 +1757,7 @@ scanOutput.textContent = JSON.stringify(response, null, 2); renderScanCharts(rows); scanAnimation.frame = 0; + scanAnimation.direction = 1; requestStatus.textContent = "扫描完成"; requestStatus.className = "badge ok"; renderSummary(response, baseInput);