Revert to working waveform: timeStep += simSpeed, pxPerMs rendering
Restores the real-time ms-based waveform that correctly reflects clock speed in wave width. Keeps the always-follow auto-scroll fix. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -31,8 +31,8 @@ export function recordSample() {
|
|||||||
|
|
||||||
if (!changed && state.timeStep > 0) return;
|
if (!changed && state.timeStep > 0) return;
|
||||||
|
|
||||||
// Each tick = 1 step (visual width determined by waveZoom px/step)
|
// Manual toggles advance by simSpeed too for consistency
|
||||||
state.timeStep += 1;
|
state.timeStep += state.simSpeed;
|
||||||
gates.forEach(g => {
|
gates.forEach(g => {
|
||||||
if (!waveData[g.id]) waveData[g.id] = [];
|
if (!waveData[g.id]) waveData[g.id] = [];
|
||||||
const arr = waveData[g.id];
|
const arr = waveData[g.id];
|
||||||
@@ -44,8 +44,8 @@ export function recordSample() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function forceRecordSample() {
|
export function forceRecordSample() {
|
||||||
// Each tick = 1 step
|
// Advance time by the current simSpeed (in ms) to reflect real time
|
||||||
state.timeStep += 1;
|
state.timeStep += state.simSpeed;
|
||||||
state.gates.forEach(g => {
|
state.gates.forEach(g => {
|
||||||
if (!state.waveData[g.id]) state.waveData[g.id] = [];
|
if (!state.waveData[g.id]) state.waveData[g.id] = [];
|
||||||
state.waveData[g.id].push({ t: state.timeStep, value: g.value });
|
state.waveData[g.id].push({ t: state.timeStep, value: g.value });
|
||||||
@@ -73,7 +73,10 @@ export function setEvaluateAll(fn) {
|
|||||||
|
|
||||||
export function updateWaveInfo() {
|
export function updateWaveInfo() {
|
||||||
const totalSamples = Object.values(state.waveData).reduce((sum, arr) => sum + arr.length, 0);
|
const totalSamples = Object.values(state.waveData).reduce((sum, arr) => sum + arr.length, 0);
|
||||||
document.getElementById('wave-info').textContent = `T=${state.timeStep} | ${totalSamples} samples`;
|
const timeLabel = state.timeStep >= 1000
|
||||||
|
? `${(state.timeStep/1000).toFixed(1)}s`
|
||||||
|
: `${state.timeStep}ms`;
|
||||||
|
document.getElementById('wave-info').textContent = `T=${timeLabel} | ${totalSamples} samples`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clearWaveData() {
|
export function clearWaveData() {
|
||||||
@@ -123,33 +126,32 @@ export function drawWaveforms() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pxPerStep: how many pixels per simulation step
|
// pxPerMs: how many pixels per millisecond of simulation time
|
||||||
const pxPerStep = state.waveZoom;
|
const pxPerMs = state.waveZoom / 100; // waveZoom=20 → 0.2 px/ms
|
||||||
|
|
||||||
// Total width in pixels for all recorded time
|
// Total width in pixels for all recorded time
|
||||||
const totalPx = state.timeStep * pxPerStep;
|
const totalPx = state.timeStep * pxPerMs;
|
||||||
|
|
||||||
// Visible width in steps
|
// Visible width in ms
|
||||||
const visibleSteps = wc.width / pxPerStep;
|
const visibleMs = wc.width / pxPerMs;
|
||||||
|
|
||||||
// Auto-scroll: always follow the latest data, keep cursor at right edge
|
// Auto-scroll: always follow the latest data, keep cursor at right edge
|
||||||
state.waveScroll = Math.max(0, state.timeStep - visibleSteps);
|
state.waveScroll = Math.max(0, state.timeStep - visibleMs);
|
||||||
|
|
||||||
// Helper: convert simulation step to pixel X
|
// Helper: convert simulation time (ms) to pixel X
|
||||||
const tToX = (t) => (t - state.waveScroll) * pxPerStep;
|
const tToX = (t) => (t - state.waveScroll) * pxPerMs;
|
||||||
|
|
||||||
// Draw time grid (every gridStep steps)
|
// Draw time grid (every gridMs milliseconds)
|
||||||
let gridStep = 5;
|
let gridMs = 500;
|
||||||
if (pxPerStep * gridStep < 30) gridStep = 10;
|
if (pxPerMs * gridMs < 30) gridMs = 1000;
|
||||||
if (pxPerStep * gridStep < 30) gridStep = 20;
|
if (pxPerMs * gridMs < 30) gridMs = 2000;
|
||||||
if (pxPerStep * gridStep < 30) gridStep = 50;
|
if (pxPerMs * gridMs > 200) gridMs = 200;
|
||||||
if (pxPerStep * gridStep > 200) gridStep = 2;
|
if (pxPerMs * gridMs > 200) gridMs = 100;
|
||||||
if (pxPerStep * gridStep > 200) gridStep = 1;
|
|
||||||
|
|
||||||
wctx.strokeStyle = '#151520';
|
wctx.strokeStyle = '#151520';
|
||||||
wctx.lineWidth = 1;
|
wctx.lineWidth = 1;
|
||||||
const startT = Math.floor(state.waveScroll / gridStep) * gridStep;
|
const startT = Math.floor(state.waveScroll / gridMs) * gridMs;
|
||||||
for (let t = startT; t <= state.timeStep; t += gridStep) {
|
for (let t = startT; t <= state.timeStep; t += gridMs) {
|
||||||
const x = tToX(t);
|
const x = tToX(t);
|
||||||
if (x < 0 || x > wc.width) continue;
|
if (x < 0 || x > wc.width) continue;
|
||||||
wctx.beginPath();
|
wctx.beginPath();
|
||||||
@@ -160,7 +162,8 @@ export function drawWaveforms() {
|
|||||||
wctx.fillStyle = '#333';
|
wctx.fillStyle = '#333';
|
||||||
wctx.font = '9px monospace';
|
wctx.font = '9px monospace';
|
||||||
wctx.textAlign = 'center';
|
wctx.textAlign = 'center';
|
||||||
wctx.fillText(`${t}`, x, 10);
|
const label = t >= 1000 ? `${(t/1000).toFixed(1)}s` : `${t}ms`;
|
||||||
|
wctx.fillText(label, x, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Row dividers
|
// Row dividers
|
||||||
|
|||||||
Reference in New Issue
Block a user