diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 5b46ac64e110..635db47245d6 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -331,6 +331,7 @@ export class ReplayContainer implements ReplayContainerInterface { */ public startRecording(): void { try { + const canvas = this._options._experiments.canvas; this._stopRecording = record({ ...this._recordingOptions, // When running in error sampling mode, we need to overwrite `checkoutEveryNms` @@ -339,6 +340,12 @@ export class ReplayContainer implements ReplayContainerInterface { ...(this.recordingMode === 'buffer' && { checkoutEveryNms: BUFFER_CHECKOUT_TIME }), emit: getHandleRecordingEmit(this), onMutation: this._onMutationHandler, + ...(canvas && { + recordCanvas: true, + sampling: { canvas: canvas.fps || 4 }, + dataURLOptions: { quality: canvas.quality || 0.6 }, + getCanvasManager: canvas.manager, + }), }); } catch (err) { this._handleException(err); diff --git a/packages/replay/src/types/replay.ts b/packages/replay/src/types/replay.ts index 38ca35ac8f0e..d854f258c073 100644 --- a/packages/replay/src/types/replay.ts +++ b/packages/replay/src/types/replay.ts @@ -14,7 +14,7 @@ import type { SKIPPED, THROTTLED } from '../util/throttle'; import type { AllPerformanceEntry, AllPerformanceEntryData, ReplayPerformanceEntry } from './performance'; import type { ReplayFrameEvent } from './replayFrame'; import type { ReplayNetworkRequestOrResponse } from './request'; -import type { ReplayEventWithTime, RrwebRecordOptions } from './rrweb'; +import type { CanvasManagerInterface, GetCanvasManagerOptions, ReplayEventWithTime, RrwebRecordOptions } from './rrweb'; export type RecordingEvent = ReplayFrameEvent | ReplayEventWithTime; export type RecordingOptions = RrwebRecordOptions; @@ -232,6 +232,11 @@ export interface ReplayPluginOptions extends ReplayNetworkOptions { _experiments: Partial<{ captureExceptions: boolean; traceInternals: boolean; + canvas: { + fps?: number; + quality?: number; + manager: (options: GetCanvasManagerOptions) => CanvasManagerInterface; + }; }>; } diff --git a/packages/replay/src/types/rrweb.ts b/packages/replay/src/types/rrweb.ts index bc78c5811b12..bbef4f94903f 100644 --- a/packages/replay/src/types/rrweb.ts +++ b/packages/replay/src/types/rrweb.ts @@ -44,3 +44,23 @@ export type RrwebRecordOptions = { blockSelector?: string; maskInputOptions?: Record; } & Record; + +export interface CanvasManagerInterface { + reset(): void; + freeze(): void; + unfreeze(): void; + lock(): void; + unlock(): void; +} + +export interface GetCanvasManagerOptions { + recordCanvas: boolean; + blockClass: string | RegExp; + blockSelector: string | null; + unblockSelector: string | null; + sampling?: 'all' | number; + dataURLOptions: Partial<{ + type: string; + quality: number; + }>; +}