import { CameraConfig } from '../types'; import { Avatar } from './Avatar'; import { AvatarController } from './AvatarController'; export declare class AvatarView { private readonly avatarController; private readonly avatar; onFirstRendering?: () => void; private canvas; private renderSystem; private isInitialized; private cameraConfig; private renderingState; private currentKeyframes; private lastRenderedFrameIndex; private lastRealtimeProtoFrame; private idleAnimationLoopId; private realtimeAnimationLoopId; private resizeObserver; private onWindowResize; private frameCount; private lastFpsUpdate; private currentFPS; private transitionKeyframes; private transitionStartTime; private readonly startTransitionDurationMs; private readonly endTransitionDurationMs; private cachedIdleFirstFrame; private idleCurrentFrameIndex; private currentPlayingFrame; private characterHandle; private characterId; private isPureRenderingMode; private _renderingEnabled; private avatarActiveTimer; private readonly AVATAR_ACTIVE_INTERVAL; /** * Constructor * Creates a unified AvatarController, internally composes network layer based on configuration * @param avatar - Avatar instance * @param container - Canvas container element (required) */ constructor(avatar: Avatar, container: HTMLElement); /** * Get controller (public interface) */ get controller(): AvatarController; /** * Cleanup view resources * Closes avatarController and cleans up all related resources */ dispose(): void; /** * 获取相机配置 */ getCameraConfig(): CameraConfig | null; /** * 更新相机配置 */ updateCameraConfig(cameraConfig: CameraConfig): void; /** * Render a single animation frame from raw protobuf data. * * Decodes the protobuf Message internally and renders the first keyframe. * This is the preferred method for RTC consumers that receive raw animation bytes. * * @param data - Raw protobuf bytes (a single Message containing ServerResponseAnimation) */ renderFromProtobuf(data: ArrayBuffer | Uint8Array): Promise; /** * Play a transition from idle to the target frame in the protobuf data, * then resolve when the transition is complete. * * The transition frames are generated and played internally at 25fps. * The caller should wait for the returned Promise before pushing streaming frames. * * @param data - Raw protobuf bytes containing the target frame * @param frameCount - Number of transition frames to generate * @returns Promise that resolves when the transition playback finishes */ playTransitionFromProtobuf(data: ArrayBuffer | Uint8Array, frameCount: number): Promise; /** * Play a transition from current animation back to idle, * then start the idle animation loop. * * Generates reverse transition frames from idle→lastFrame, reverses them, * plays at 25fps, then starts idle. * * @param data - Raw protobuf bytes containing the last animation frame * @param frameCount - Number of transition frames to generate * @returns Promise that resolves when idle animation starts */ playTransitionToIdleFromProtobuf(data: ArrayBuffer | Uint8Array, frameCount: number): Promise; /** * Start idle animation (stop pure rendering mode, resume idle loop). */ startIdle(): void; /** * Generate transition frames from protobuf data. * * Decodes the protobuf, extracts the target keyframe, and generates * transition frames from the current idle position to the target. * The caller is responsible for playing the returned frames at the desired cadence. * * @param data - Raw protobuf bytes containing the target frame * @param frameCount - Number of transition frames to generate * @param options - Additional options * @param options.useLinear - Use linear interpolation (default: true) * @returns Array of opaque keyframe data for sequential playback */ generateTransitionFromProtobuf(data: ArrayBuffer | Uint8Array, frameCount: number, options?: { useLinear?: boolean; }): Promise; /** * Cancel any in-progress frame sequence playback. * Called by renderFromProtobuf when streaming frames arrive during transition. */ cancelFrameSequence(): void; /** * Pause rendering loop * * When called: * - Rendering loop stops (no GPU/canvas updates) * - Audio playback continues normally * - Animation state machine continues running * * Use `resumeRendering()` to resume rendering. * * @example * // Stop rendering to save GPU resources (audio continues) * avatarView.pauseRendering() */ pauseRendering(): void; /** * Resume rendering loop * * When called: * - Rendering loop resumes from current state * - If in Idle state, immediately renders current frame to restore display * * @example * // Resume rendering * avatarView.resumeRendering() */ resumeRendering(): void; /** * Check if rendering is currently enabled * @returns true if rendering is enabled, false if paused */ isRenderingEnabled(): boolean; /** * Get or set avatar transform in canvas * * @example * // Get current transform * const current = avatarView.avatarTransform * * // Set transform * avatarView.avatarTransform = { x: 0.5, y: 0, scale: 2.0 } */ get avatarTransform(): { x: number; y: number; scale: number; }; set avatarTransform(value: { x: number; y: number; scale: number; }); }