Skip to content

fix: canvas scaling quality, copyTransformTo, and pitch-preserving speed change - #488

Open
PiedPiper911 wants to merge 4 commits into
WebAV-Tech:mainfrom
PiedPiper911:fix/canvas-quality-and-copy-transform
Open

fix: canvas scaling quality, copyTransformTo, and pitch-preserving speed change#488
PiedPiper911 wants to merge 4 commits into
WebAV-Tech:mainfrom
PiedPiper911:fix/canvas-quality-and-copy-transform

Conversation

@PiedPiper911

@PiedPiper911 PiedPiper911 commented Aug 6, 2026

Copy link
Copy Markdown

Summary

Three improvements to the WebAV canvas rendering and audio processing:

Fix #482 - Video blurs after manual scale-down

Set imageSmoothingQuality = 'high' in BaseSprite._render() before any drawing operations. The Canvas 2D API defaults to low-quality interpolation, which causes visible blurriness when high-resolution video is scaled down on the canvas.

This applies to all sprite types (VisibleSprite, OffscreenSprite) since they all call super._render(ctx) before drawImage().

Fix #481 - Text sprite bounding box doesn't follow after copyStateTo

Added a new copyTransformTo() method on BaseSprite that copies only position and rotation (x, y, angle) while preserving the target sprite's own dimensions (w, h).

The existing copyStateTo() behavior is unchanged for backward compatibility.

Fix #487 - Pitch-preserving speed change (SoundTouch integration)

Added SpeedAudioClip class and createSpeedAudioClip() factory function that wraps an AudioClip with SoundTouch time-stretching. This decouples playback speed from pitch:

  • Native OffscreenSprite speed change: changes both speed AND pitch
  • SpeedAudioClip: changes speed while keeping original pitch

soundtouch-ts is added as an optional peer dependency - dynamically imported only when SpeedAudioClip is used, so users who don't need this feature pay zero cost.

Usage:

import { AudioClip, OffscreenSprite, createSpeedAudioClip } from '@webav/av-cliper';

const audioClip = new AudioClip(audioSource);
const speedClip = createSpeedAudioClip(audioClip, 1.5); // 1.5x speed, pitch preserved

const sprite = new OffscreenSprite(speedClip);
sprite.time.playbackRate = 1; // Required: bypass OffscreenSprite's own resampling

Test plan

  • Import a high-res video, scale it down on canvas - should be sharp, not blurry
  • Create a text sprite, modify its text, use copyTransformTo() to transfer position - bounding box should follow correctly
  • Verify copyStateTo() still works as before (copies all properties including dimensions)
  • Install soundtouch-ts, create a SpeedAudioClip at 1.5x speed - audio should be faster but pitch unchanged
  • Verify createSpeedAudioClip(clip, 1.0) returns the original clip (no overhead)

…ment

- Set imageSmoothingQuality to high in BaseSprite._render() to fix
  blurry video when scaling down (WebAV-Tech#482).
- Add copyTransformTo() method that copies only position/rotation,
  preserving the target sprite's own dimensions (WebAV-Tech#481).
Integrates soundtouch-ts to implement time-stretching without pitch shift.
Wraps AudioClip with a SoundTouch processor that decouples playback speed
from pitch. Uses dynamic import so soundtouch-ts is an optional dependency.

Closes WebAV-Tech#487
@PiedPiper911 PiedPiper911 changed the title fix: high-quality canvas scaling + copyTransformTo for sprite replacement fix: canvas scaling quality, copyTransformTo, and pitch-preserving speed change Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant