fix: improve text sharpness on zoom with tighter buckets and reliable init
Fix text staying blurry on zoom by ensuring the first setZoomBucket call always applies (PixiJS v8 defaults to auto-resolution which skipped the initial bucket=1 assignment), listening on both 'moved' and 'zoomed' viewport events, and tightening bucket thresholds from 6 to 9 levels.
This commit is contained in:
@@ -35,6 +35,7 @@ export class TextCore {
|
||||
private _lastWordWrapWidth: number;
|
||||
private _lastLineHeightMultiplier: number;
|
||||
private _zoomBucket = 1;
|
||||
private _zoomBucketApplied = false;
|
||||
|
||||
get measuredWidth(): number {
|
||||
return this.pixiText.width;
|
||||
@@ -81,8 +82,11 @@ export class TextCore {
|
||||
* Only re-rasterizes when the bucket actually changes.
|
||||
*/
|
||||
setZoomBucket(bucket: number): void {
|
||||
if (bucket === this._zoomBucket) return;
|
||||
// Always apply on first call (resolution starts as null/auto in PixiJS v8).
|
||||
// After that, skip if bucket hasn't changed.
|
||||
if (this._zoomBucketApplied && bucket === this._zoomBucket) return;
|
||||
this._zoomBucket = bucket;
|
||||
this._zoomBucketApplied = true;
|
||||
this.pixiText.resolution = bucket;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,14 @@ import { StickySprite } from './sprites/StickySprite';
|
||||
* Fewer buckets = fewer re-rasterizations = better perf.
|
||||
*/
|
||||
export function getTextZoomBucket(scale: number): number {
|
||||
if (scale < 0.4) return 0.5;
|
||||
if (scale < 0.75) return 0.75;
|
||||
if (scale < 1.25) return 1;
|
||||
if (scale < 1.75) return 1.5;
|
||||
if (scale < 2.5) return 2;
|
||||
if (scale < 0.3) return 0.25;
|
||||
if (scale < 0.5) return 0.5;
|
||||
if (scale < 0.8) return 0.75;
|
||||
if (scale < 1.1) return 1;
|
||||
if (scale < 1.4) return 1.25;
|
||||
if (scale < 1.8) return 1.5;
|
||||
if (scale < 2.2) return 2;
|
||||
if (scale < 3.0) return 2.5;
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
@@ -185,12 +185,15 @@ export function useCanvasSetup(deps: CanvasSetupDeps) {
|
||||
undoRef.current = new UndoManager(scene);
|
||||
|
||||
// Zoom-bucket text sharpness — re-rasterize visible text when zoom crosses bucket boundary
|
||||
// Listen on both 'zoomed' and 'moved' — pixi-viewport may only fire 'moved' for some zoom types
|
||||
const sharpness = new TextSharpnessManager(viewport, scene);
|
||||
const onZoomBucketCheck = () => { sharpness.check(); };
|
||||
viewport.on('zoomed', onZoomBucketCheck);
|
||||
viewport.on('moved', onZoomBucketCheck);
|
||||
scene.onItemCreated = (item) => { sharpness.applyToItem(item); };
|
||||
sharpnessCleanupRef.current = () => {
|
||||
viewport.off('zoomed', onZoomBucketCheck);
|
||||
viewport.off('moved', onZoomBucketCheck);
|
||||
scene.onItemCreated = null;
|
||||
sharpness.destroy();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user