Keep the Sound tab smooth while it pans (#360)
Panning the Sound tab drew the whole wave anew on every move, one filled rectangle per pixel column, and gave the ruler's labels new texts whenever a tick left the area. At 2560 px across that took the tab down to 16 fps. - The wave is drawn half the area's width past either side of it. A pan within that moves the drawing. Zoom, height, size or a pan past the margin draw it anew. - The bars of the wave share one fill instead of one fill each. - A ruler label keeps the second it already shows. Before, a pan shifted every label by one and each had to be rendered anew. - A clip's name is given its style only when the style changes. - The rule for what a drawing covers is pure in `waveView.ts` (`shownSeconds`, `drawnSeconds`, `coversShown`). Measured with a copy of the user's project, "Take 1" with 4 clips, 240 pan moves with the middle button, headless on stein2: - 2560x1440: main thread 712 -> 373 ms/s, texts rendered 694 -> 65 - 1280x800: main thread 429 -> 225 ms/s What is left in the profile is Pixi's render pass and the pointer events, which hovering pays as well. Tests: - Unit wave-view: 12 green (1 new), counter-probe red - e2e 34 (stein2, melektaus-atx was down): ALL PASSED, 92 checks (1 new). Counter-probe with the labels given out by position: red, 7 labels set anew instead of 1. - Gate (stein2): 272 files, 4210 tests green Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
490fcba88f
commit
cf96442835
5 files changed
+160
-15
No files matched your search
@@ -5,7 +5,9 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
clampWave,
|
||||
coversShown,
|
||||
draggedSpan,
|
||||
drawnSeconds,
|
||||
edgeAt,
|
||||
fileReach,
|
||||
fitWave,
|
||||
@@ -15,6 +17,7 @@ import {
|
||||
rulerLabel,
|
||||
rulerStep,
|
||||
secondsToX,
|
||||
shownSeconds,
|
||||
spanOf,
|
||||
spanPeak,
|
||||
storedCut,
|
||||
@@ -83,6 +86,23 @@ describe('the wave view', () => {
|
||||
expect(rulerLabel(0.25, 0.05)).toBe('0.25s');
|
||||
expect(rulerLabel(75, 5)).toBe('1:15');
|
||||
});
|
||||
|
||||
it('draws the wave past the area by a margin, and a pan within it keeps that drawing (#360)', () => {
|
||||
// 20 s at 100 px/s, 1000 px across: seconds 5 to 15 shown, 0 to 20 with 500 px either side.
|
||||
const view = { panX: -500, pxPerSecond: 100 };
|
||||
expect(shownSeconds(view, 20, 1000)).toEqual({ start: 5, end: 15 });
|
||||
const drawn = drawnSeconds(view, 20, 1000, 500);
|
||||
expect(drawn).toEqual({ start: 0, end: 20 });
|
||||
const near = drawnSeconds({ ...view, panX: -1000 }, 20, 1000, 300);
|
||||
expect(near).toEqual({ start: 7, end: 20 });
|
||||
// Panned 200 px it still covers what is shown, 400 px past it no longer.
|
||||
expect(coversShown(near, shownSeconds({ ...view, panX: -800 }, 20, 1000))).toBe(true);
|
||||
expect(coversShown(near, shownSeconds({ ...view, panX: -600 }, 20, 1000))).toBe(false);
|
||||
// Nothing of the file in view: nothing to cover, and nothing drawn.
|
||||
expect(shownSeconds({ panX: 1200, pxPerSecond: 100 }, 20, 1000)).toBeNull();
|
||||
expect(coversShown(null, null)).toBe(true);
|
||||
expect(coversShown(null, { start: 0, end: 1 })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('the cut span', () => {
|
||||
|
||||
Reference in new issue
Block a user