sync + pause animation btwn cycles
This commit is contained in:
parent
3d3e1e62ee
commit
6b103cd95f
@ -490,8 +490,12 @@ function createScene(container, dataset) {
|
|||||||
trajectories: null,
|
trajectories: null,
|
||||||
numFrames: 0,
|
numFrames: 0,
|
||||||
snapshotMs: 1000 / 12,
|
snapshotMs: 1000 / 12,
|
||||||
// random phase so the three scenes don't loop in lockstep
|
// holdMs pads the end of each cycle at rest, so the pulse actually
|
||||||
cycleStartMs: performance.now() - Math.random() * 2000,
|
// lands (otherwise frame-0-as-rest is zero-duration and never visible).
|
||||||
|
holdMs: 200,
|
||||||
|
// shared reference so all scenes stay in lockstep; applyF() sets this
|
||||||
|
// to the same value across scenes on every n-frames toggle.
|
||||||
|
cycleStartMs: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -515,7 +519,6 @@ function buildTrajectories(s, numFrames) {
|
|||||||
}
|
}
|
||||||
s.trajectories = buf;
|
s.trajectories = buf;
|
||||||
s.numFrames = numFrames;
|
s.numFrames = numFrames;
|
||||||
s.cycleStartMs = performance.now() - Math.random() * s.snapshotMs * numFrames;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sizeScene(s) {
|
function sizeScene(s) {
|
||||||
@ -630,9 +633,11 @@ async function main() {
|
|||||||
const fInputs = document.querySelectorAll('input[name="f"]');
|
const fInputs = document.querySelectorAll('input[name="f"]');
|
||||||
function applyF(n) {
|
function applyF(n) {
|
||||||
numFrames = n;
|
numFrames = n;
|
||||||
|
// Shared start time keeps all three scenes in lockstep.
|
||||||
|
const start = performance.now();
|
||||||
for (const s of scenes) {
|
for (const s of scenes) {
|
||||||
s.numFrames = n;
|
s.numFrames = n;
|
||||||
s.cycleStartMs = performance.now() - Math.random() * s.snapshotMs * n;
|
s.cycleStartMs = start;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fInputs.forEach(input => {
|
fInputs.forEach(input => {
|
||||||
@ -691,14 +696,9 @@ async function main() {
|
|||||||
for (const s of scenes) {
|
for (const s of scenes) {
|
||||||
const N = s.numFrames;
|
const N = s.numFrames;
|
||||||
const n = s.basePositions.length;
|
const n = s.basePositions.length;
|
||||||
const cycleMs = N * s.snapshotMs;
|
const walkMs = N * s.snapshotMs;
|
||||||
|
const cycleMs = walkMs + s.holdMs;
|
||||||
const elapsed = ((now - s.cycleStartMs) % cycleMs + cycleMs) % cycleMs;
|
const elapsed = ((now - s.cycleStartMs) % cycleMs + cycleMs) % cycleMs;
|
||||||
const frameF = elapsed / s.snapshotMs;
|
|
||||||
const frameIdx = Math.floor(frameF);
|
|
||||||
const interpT = frameF - frameIdx;
|
|
||||||
const nextIdx = (frameIdx + 1) % N;
|
|
||||||
const aOff = frameIdx * n;
|
|
||||||
const bOff = nextIdx * n;
|
|
||||||
|
|
||||||
const total = n / 3;
|
const total = n / 3;
|
||||||
const drawCount = s.geometry.drawRange.count;
|
const drawCount = s.geometry.drawRange.count;
|
||||||
@ -706,13 +706,25 @@ async function main() {
|
|||||||
const limit = visibleN * 3;
|
const limit = visibleN * 3;
|
||||||
const pos = s.geometry.attributes.position.array;
|
const pos = s.geometry.attributes.position.array;
|
||||||
const base = s.basePositions;
|
const base = s.basePositions;
|
||||||
const tr = s.trajectories;
|
|
||||||
// Jitter is applied in normalized space so σ means the same thing
|
if (elapsed >= walkMs) {
|
||||||
// across datasets — independent of the raw feature magnitudes.
|
// Hold zone: snap-back has landed, sit at rest until next cycle.
|
||||||
const scale = jitterScale;
|
for (let i = 0; i < limit; i++) pos[i] = base[i];
|
||||||
const u = 1 - interpT;
|
} else {
|
||||||
for (let i = 0; i < limit; i++) {
|
const frameF = elapsed / s.snapshotMs;
|
||||||
pos[i] = base[i] + (tr[aOff + i] * u + tr[bOff + i] * interpT) * scale;
|
const frameIdx = Math.floor(frameF);
|
||||||
|
const interpT = frameF - frameIdx;
|
||||||
|
const nextIdx = (frameIdx + 1) % N;
|
||||||
|
const aOff = frameIdx * n;
|
||||||
|
const bOff = nextIdx * n;
|
||||||
|
const tr = s.trajectories;
|
||||||
|
// Jitter is applied in normalized space so σ means the same thing
|
||||||
|
// across datasets — independent of the raw feature magnitudes.
|
||||||
|
const scale = jitterScale;
|
||||||
|
const u = 1 - interpT;
|
||||||
|
for (let i = 0; i < limit; i++) {
|
||||||
|
pos[i] = base[i] + (tr[aOff + i] * u + tr[bOff + i] * interpT) * scale;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s.geometry.attributes.position.needsUpdate = true;
|
s.geometry.attributes.position.needsUpdate = true;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user