diff --git a/src/components/video-editor/SettingsPanel.tsx b/src/components/video-editor/SettingsPanel.tsx index cff898a53..5b84863ae 100644 --- a/src/components/video-editor/SettingsPanel.tsx +++ b/src/components/video-editor/SettingsPanel.tsx @@ -512,6 +512,8 @@ interface SettingsPanelProps { onShowCursorChange?: (enabled: boolean) => void; loopCursor?: boolean; onLoopCursorChange?: (enabled: boolean) => void; + alwaysUsePointerCursor?: boolean; + onAlwaysUsePointerCursorChange?: (enabled: boolean) => void; cursorStyle?: CursorStyle; onCursorStyleChange?: (style: CursorStyle) => void; cursorSize?: number; @@ -897,6 +899,8 @@ export function SettingsPanel({ onShowCursorChange, loopCursor = false, onLoopCursorChange, + alwaysUsePointerCursor = false, + onAlwaysUsePointerCursorChange, cursorStyle = DEFAULT_CURSOR_STYLE, onCursorStyleChange, cursorSize = 5, @@ -1523,6 +1527,7 @@ export function SettingsPanel({ const resetCursorSection = () => { onShowCursorChange?.(initialEditorPreferences.showCursor); onLoopCursorChange?.(initialEditorPreferences.loopCursor); + onAlwaysUsePointerCursorChange?.(initialEditorPreferences.alwaysUsePointerCursor); onCursorStyleChange?.(initialEditorPreferences.cursorStyle); onCursorSizeChange?.(initialEditorPreferences.cursorSize); onCursorSmoothingChange?.(initialEditorPreferences.cursorSmoothing); @@ -3308,6 +3313,19 @@ export function SettingsPanel({ +
( initialEditorPreferences.cursorStyle ?? DEFAULT_CURSOR_STYLE, ); @@ -848,6 +851,7 @@ export default function VideoEditor() { connectedZoomEasing, showCursor, loopCursor, + alwaysUsePointerCursor, cursorStyle, cursorSize, cursorSmoothing, @@ -899,6 +903,7 @@ export default function VideoEditor() { connectedZoomEasing, showCursor, loopCursor, + alwaysUsePointerCursor, cursorStyle, cursorSize, cursorSmoothing, @@ -991,6 +996,7 @@ export default function VideoEditor() { setConnectedZoomEasing(snapshot.connectedZoomEasing); setShowCursor(snapshot.showCursor); setLoopCursor(snapshot.loopCursor); + setAlwaysUsePointerCursor(snapshot.alwaysUsePointerCursor); setCursorStyle(snapshot.cursorStyle); setCursorSize(snapshot.cursorSize); setCursorSmoothing(snapshot.cursorSmoothing); @@ -1261,6 +1267,7 @@ export default function VideoEditor() { previewHeight, cursorTelemetry, showCursor: effectiveShowCursor, + alwaysUsePointerCursor, cursorStyle, cursorSize, cursorSmoothing, @@ -1360,6 +1367,7 @@ export default function VideoEditor() { resolvedWebcamVideoUrl, shadowIntensity, effectiveShowCursor, + alwaysUsePointerCursor, speedRegions, wallpaper, webcam, @@ -1733,6 +1741,7 @@ export default function VideoEditor() { connectedZoomEasing: ZoomTransitionEasing; showCursor: boolean; loopCursor: boolean; + alwaysUsePointerCursor: boolean; cursorStyle: CursorStyle; cursorSize: number; cursorSmoothing: number; @@ -1836,6 +1845,7 @@ export default function VideoEditor() { connectedZoomEasing, showCursor, loopCursor, + alwaysUsePointerCursor, cursorStyle, cursorSize, cursorSmoothing, @@ -1898,6 +1908,7 @@ export default function VideoEditor() { connectedZoomEasing, showCursor, loopCursor, + alwaysUsePointerCursor, cursorStyle, cursorSize, cursorSmoothing, @@ -2096,6 +2107,7 @@ export default function VideoEditor() { setConnectedZoomEasing(normalizedEditor.connectedZoomEasing); setShowCursor(normalizedEditor.showCursor); setLoopCursor(normalizedEditor.loopCursor); + setAlwaysUsePointerCursor(normalizedEditor.alwaysUsePointerCursor); setCursorStyle(normalizedEditor.cursorStyle); setCursorSize(normalizedEditor.cursorSize); setCursorSmoothing(normalizedEditor.cursorSmoothing); @@ -2572,6 +2584,7 @@ export default function VideoEditor() { connectedZoomEasing, showCursor, loopCursor, + alwaysUsePointerCursor, cursorStyle, cursorSize, cursorSmoothing, @@ -2623,6 +2636,7 @@ export default function VideoEditor() { connectedZoomEasing, showCursor, loopCursor, + alwaysUsePointerCursor, cursorStyle, cursorSize, cursorSmoothing, @@ -4274,6 +4288,7 @@ export default function VideoEditor() { zoomRegions: effectiveZoomRegions, cursorTelemetry: effectiveCursorTelemetry, showCursor: effectiveShowCursor, + alwaysUsePointerCursor, cursorStyle, cursorSize, cursorSmoothing, @@ -4446,6 +4461,7 @@ export default function VideoEditor() { zoomRegions: effectiveZoomRegions, cursorTelemetry: effectiveCursorTelemetry, showCursor: effectiveShowCursor, + alwaysUsePointerCursor, cursorStyle, cursorSize, cursorSmoothing, @@ -4697,6 +4713,7 @@ export default function VideoEditor() { zoomOutEasing, connectedZoomEasing, effectiveShowCursor, + alwaysUsePointerCursor, cursorStyle, effectiveCursorTelemetry, cursorSize, @@ -5882,6 +5899,8 @@ export default function VideoEditor() { onShowCursorChange={handleShowCursorChange} loopCursor={loopCursor} onLoopCursorChange={setLoopCursor} + alwaysUsePointerCursor={alwaysUsePointerCursor} + onAlwaysUsePointerCursorChange={setAlwaysUsePointerCursor} cursorStyle={cursorStyle} onCursorStyleChange={setCursorStyle} cursorSize={cursorSize} @@ -6106,6 +6125,7 @@ export default function VideoEditor() { onAnnotationSizeChange={handleAnnotationSizeChange} cursorTelemetry={effectiveCursorTelemetry} showCursor={effectiveShowCursor} + alwaysUsePointerCursor={alwaysUsePointerCursor} cursorStyle={cursorStyle} cursorSize={cursorSize} cursorSmoothing={cursorSmoothing} diff --git a/src/components/video-editor/VideoPlayback.tsx b/src/components/video-editor/VideoPlayback.tsx index c64e6b425..39bb2a569 100644 --- a/src/components/video-editor/VideoPlayback.tsx +++ b/src/components/video-editor/VideoPlayback.tsx @@ -352,6 +352,7 @@ interface VideoPlaybackProps { onAnnotationSizeChange?: (id: string, size: { width: number; height: number }) => void; cursorTelemetry?: CursorTelemetryPoint[]; showCursor?: boolean; + alwaysUsePointerCursor?: boolean; cursorStyle?: CursorStyle; cursorSize?: number; cursorSmoothing?: number; @@ -430,6 +431,7 @@ const VideoPlayback = forwardRef( onAnnotationSizeChange, cursorTelemetry = [], showCursor = false, + alwaysUsePointerCursor = false, cursorStyle = DEFAULT_CURSOR_STYLE, cursorSize = DEFAULT_CURSOR_SIZE, cursorSmoothing = DEFAULT_CURSOR_SMOOTHING, @@ -554,6 +556,7 @@ const VideoPlayback = forwardRef( const cursorEffectsCanvasRef = useRef(null); const cursorTelemetryRef = useRef([]); const showCursorRef = useRef(showCursor); + const alwaysUsePointerCursorRef = useRef(alwaysUsePointerCursor); const cursorSizeRef = useRef(cursorSize); const cursorStyleRef = useRef(cursorStyle); const cursorSmoothingRef = useRef(cursorSmoothing); @@ -1511,6 +1514,11 @@ const VideoPlayback = forwardRef( cursorStyleRef.current = cursorStyle; }, [cursorStyle]); + useEffect(() => { + alwaysUsePointerCursorRef.current = alwaysUsePointerCursor; + cursorOverlayRef.current?.setAlwaysUsePointerCursor(alwaysUsePointerCursor); + }, [alwaysUsePointerCursor]); + useEffect(() => { cursorSizeRef.current = cursorSize; }, [cursorSize]); @@ -1866,6 +1874,7 @@ const VideoPlayback = forwardRef( const cursorOverlay = new PixiCursorOverlay({ dotRadius: DEFAULT_CURSOR_CONFIG.dotRadius * cursorSizeRef.current, style: cursorStyleRef.current, + alwaysUsePointerCursor: alwaysUsePointerCursorRef.current, smoothingFactor: cursorSmoothingRef.current, springTuning: { stiffnessMultiplier: cursorSpringStiffnessMultiplierRef.current, diff --git a/src/components/video-editor/editorPreferences.ts b/src/components/video-editor/editorPreferences.ts index cbd417561..803a247b8 100644 --- a/src/components/video-editor/editorPreferences.ts +++ b/src/components/video-editor/editorPreferences.ts @@ -29,6 +29,7 @@ type PersistedEditorControls = Pick< | "connectedZoomEasing" | "showCursor" | "loopCursor" + | "alwaysUsePointerCursor" | "cursorStyle" | "cursorSize" | "cursorSmoothing" @@ -110,6 +111,7 @@ export const DEFAULT_EDITOR_PREFERENCES: EditorPreferences = { connectedZoomEasing: DEFAULT_EDITOR_CONTROLS.connectedZoomEasing, showCursor: DEFAULT_EDITOR_CONTROLS.showCursor, loopCursor: DEFAULT_EDITOR_CONTROLS.loopCursor, + alwaysUsePointerCursor: DEFAULT_EDITOR_CONTROLS.alwaysUsePointerCursor, cursorStyle: DEFAULT_EDITOR_CONTROLS.cursorStyle, cursorSize: DEFAULT_EDITOR_CONTROLS.cursorSize, cursorSmoothing: DEFAULT_EDITOR_CONTROLS.cursorSmoothing, @@ -289,6 +291,8 @@ function normalizeEditorControls( sanitizedRaw.connectedZoomEasing ?? fallback.connectedZoomEasing, showCursor: sanitizedRaw.showCursor ?? fallback.showCursor, loopCursor: sanitizedRaw.loopCursor ?? fallback.loopCursor, + alwaysUsePointerCursor: + sanitizedRaw.alwaysUsePointerCursor ?? fallback.alwaysUsePointerCursor, cursorStyle: sanitizedRaw.cursorStyle ?? fallback.cursorStyle, cursorSize: sanitizedRaw.cursorSize ?? fallback.cursorSize, cursorSmoothing: sanitizedRaw.cursorSmoothing ?? fallback.cursorSmoothing, @@ -361,6 +365,7 @@ function normalizeEditorControls( connectedZoomEasing: normalized.connectedZoomEasing, showCursor: normalized.showCursor, loopCursor: normalized.loopCursor, + alwaysUsePointerCursor: normalized.alwaysUsePointerCursor, cursorStyle: normalized.cursorStyle, cursorSize: normalized.cursorSize, cursorSmoothing: normalized.cursorSmoothing, diff --git a/src/components/video-editor/projectPersistence.ts b/src/components/video-editor/projectPersistence.ts index bb3d00dfe..106e72f05 100644 --- a/src/components/video-editor/projectPersistence.ts +++ b/src/components/video-editor/projectPersistence.ts @@ -96,6 +96,7 @@ export interface ProjectEditorState { connectedZoomEasing: ZoomTransitionEasing; showCursor: boolean; loopCursor: boolean; + alwaysUsePointerCursor: boolean; cursorStyle: CursorStyle; cursorSize: number; cursorSmoothing: number; @@ -880,6 +881,10 @@ export function normalizeProjectEditor(editor: Partial): Pro ), showCursor: typeof editor.showCursor === "boolean" ? editor.showCursor : true, loopCursor: typeof editor.loopCursor === "boolean" ? editor.loopCursor : false, + alwaysUsePointerCursor: + typeof editor.alwaysUsePointerCursor === "boolean" + ? editor.alwaysUsePointerCursor + : false, cursorStyle: normalizedCursorStyle, cursorSize: normalizedMotionPreset.cursorSize, cursorSmoothing: normalizedMotionPreset.cursorSmoothing, diff --git a/src/components/video-editor/videoPlayback/cursorRenderer.ts b/src/components/video-editor/videoPlayback/cursorRenderer.ts index 644cf8992..71175762d 100644 --- a/src/components/video-editor/videoPlayback/cursorRenderer.ts +++ b/src/components/video-editor/videoPlayback/cursorRenderer.ts @@ -89,6 +89,7 @@ export interface CursorRenderConfig { sway: number; /** Cursor visual style. */ style: CursorStyle; + alwaysUsePointerCursor: boolean; } export const DEFAULT_CURSOR_CONFIG: CursorRenderConfig = { @@ -107,6 +108,7 @@ export const DEFAULT_CURSOR_CONFIG: CursorRenderConfig = { clickBounceDuration: DEFAULT_CURSOR_CLICK_BOUNCE_DURATION, sway: 0, style: DEFAULT_CURSOR_STYLE, + alwaysUsePointerCursor: false, }; const REFERENCE_WIDTH = 1920; @@ -1011,6 +1013,10 @@ export class PixiCursorOverlay { this.config.sway = clamp(sway, 0, 2); } + setAlwaysUsePointerCursor(enabled: boolean) { + this.config.alwaysUsePointerCursor = enabled; + } + setStyle(style: CursorStyle) { this.config.style = style; if (isStatefulCursorStyle(style)) { @@ -1108,11 +1114,14 @@ export class PixiCursorOverlay { const px = viewport.x + this.state.x * viewport.width; const py = viewport.y + this.state.y * viewport.height; const h = this.config.dotRadius * getCursorViewportScale(viewport); - const { cursorType, clickBounceProgress } = getCursorVisualState( + const { cursorType: rawCursorType, clickBounceProgress } = getCursorVisualState( samples, timeMs, this.config.clickBounceDuration, ); + const cursorType: CursorAssetKey = this.config.alwaysUsePointerCursor + ? "pointer" + : rawCursorType; const bounceScale = Math.max( 0.72, 1 - Math.sin(clickBounceProgress * Math.PI) * (0.08 * this.config.clickBounce), @@ -1317,11 +1326,12 @@ export function drawCursorOnCanvas( const px = viewport.x + smoothedState.x * viewport.width; const py = viewport.y + smoothedState.y * viewport.height; const h = config.dotRadius * getCursorViewportScale(viewport); - const { cursorType, clickBounceProgress } = getCursorVisualState( + const { cursorType: rawCursorType, clickBounceProgress } = getCursorVisualState( samples, timeMs, config.clickBounceDuration, ); + const cursorType: CursorAssetKey = config.alwaysUsePointerCursor ? "pointer" : rawCursorType; const spriteKey = ( cursorType && loadedCursorAssets[cursorType] ? cursorType : "arrow" ) as CursorAssetKey; diff --git a/src/i18n/locales/en/settings.json b/src/i18n/locales/en/settings.json index b9a2d00ad..ff5b4c30e 100644 --- a/src/i18n/locales/en/settings.json +++ b/src/i18n/locales/en/settings.json @@ -30,6 +30,7 @@ "show": "Show", "showCursor": "Show Cursor", "loopCursor": "Loop cursor", + "alwaysUsePointerCursor": "Always use pointer cursor", "cursorStyle": "Cursor Style", "cursorStyleOptions": { "macos": "macOS", diff --git a/src/i18n/locales/es/settings.json b/src/i18n/locales/es/settings.json index 66a05e89c..ebfa96778 100644 --- a/src/i18n/locales/es/settings.json +++ b/src/i18n/locales/es/settings.json @@ -30,6 +30,7 @@ "show": "Mostrar", "showCursor": "Mostrar cursor", "loopCursor": "Cursor en bucle", + "alwaysUsePointerCursor": "Usar siempre el cursor puntero", "cursorStyle": "Estilo del cursor", "cursorStyleOptions": { "macos": "macOS", diff --git a/src/i18n/locales/fr/settings.json b/src/i18n/locales/fr/settings.json index 200ecaa02..28ece8600 100644 --- a/src/i18n/locales/fr/settings.json +++ b/src/i18n/locales/fr/settings.json @@ -30,6 +30,7 @@ "show": "Afficher", "showCursor": "Afficher le curseur", "loopCursor": "Boucler le curseur", + "alwaysUsePointerCursor": "Toujours utiliser le curseur pointeur", "cursorStyle": "Style du curseur", "cursorStyleOptions": { "macos": "macOS", diff --git a/src/i18n/locales/it/settings.json b/src/i18n/locales/it/settings.json index d9b9a1a18..a546b4587 100644 --- a/src/i18n/locales/it/settings.json +++ b/src/i18n/locales/it/settings.json @@ -30,6 +30,7 @@ "show": "Mostra", "showCursor": "Mostra cursore", "loopCursor": "Cursore in loop", + "alwaysUsePointerCursor": "Usa sempre il cursore puntatore", "cursorStyle": "Stile cursore", "cursorStyleOptions": { "macos": "macOS", diff --git a/src/i18n/locales/ko/settings.json b/src/i18n/locales/ko/settings.json index c528a98fb..30aaa172f 100644 --- a/src/i18n/locales/ko/settings.json +++ b/src/i18n/locales/ko/settings.json @@ -30,6 +30,7 @@ "show": "표시", "showCursor": "커서 표시", "loopCursor": "커서 반복", + "alwaysUsePointerCursor": "항상 포인터 커서 사용", "cursorStyle": "커서 스타일", "cursorStyleOptions": { "macos": "macOS", diff --git a/src/i18n/locales/nl/settings.json b/src/i18n/locales/nl/settings.json index d88e4278c..5112e4992 100644 --- a/src/i18n/locales/nl/settings.json +++ b/src/i18n/locales/nl/settings.json @@ -30,6 +30,7 @@ "show": "Tonen", "showCursor": "Cursor tonen", "loopCursor": "Cursor herhalen", + "alwaysUsePointerCursor": "Altijd aanwijzer-cursor gebruiken", "cursorStyle": "Cursorstijl", "cursorStyleOptions": { "macos": "macOS", diff --git a/src/i18n/locales/pt-BR/settings.json b/src/i18n/locales/pt-BR/settings.json index a34e6e4d2..8180f7960 100644 --- a/src/i18n/locales/pt-BR/settings.json +++ b/src/i18n/locales/pt-BR/settings.json @@ -30,6 +30,7 @@ "show": "Mostrar", "showCursor": "Mostrar cursor", "loopCursor": "Loop do cursor", + "alwaysUsePointerCursor": "Usar sempre cursor de ponteiro", "cursorStyle": "Estilo do cursor", "cursorStyleOptions": { "macos": "macOS", diff --git a/src/i18n/locales/ru/settings.json b/src/i18n/locales/ru/settings.json index 687f8383b..2c6ee61b0 100644 --- a/src/i18n/locales/ru/settings.json +++ b/src/i18n/locales/ru/settings.json @@ -30,6 +30,7 @@ "show": "Показать", "showCursor": "Показать курсор", "loopCursor": "Зациклить курсор", + "alwaysUsePointerCursor": "Всегда использовать курсор-указатель", "cursorStyle": "Стиль курсора", "cursorStyleOptions": { "macos": "macOS", diff --git a/src/i18n/locales/zh-CN/settings.json b/src/i18n/locales/zh-CN/settings.json index a68d2a04f..c06d9001f 100644 --- a/src/i18n/locales/zh-CN/settings.json +++ b/src/i18n/locales/zh-CN/settings.json @@ -30,6 +30,7 @@ "show": "显示", "showCursor": "显示光标", "loopCursor": "循环光标", + "alwaysUsePointerCursor": "始终使用指针光标", "cursorStyle": "光标样式", "cursorStyleOptions": { "macos": "macOS", diff --git a/src/i18n/locales/zh-TW/settings.json b/src/i18n/locales/zh-TW/settings.json index db0ea7e04..36d925219 100644 --- a/src/i18n/locales/zh-TW/settings.json +++ b/src/i18n/locales/zh-TW/settings.json @@ -30,6 +30,7 @@ "show": "顯示", "showCursor": "顯示游標", "loopCursor": "游標循環", + "alwaysUsePointerCursor": "始終使用指針游標", "cursorStyle": "游標樣式", "cursorStyleOptions": { "macos": "macOS", diff --git a/src/lib/exporter/frameRenderer.ts b/src/lib/exporter/frameRenderer.ts index 4ebc12059..cd0c629d1 100644 --- a/src/lib/exporter/frameRenderer.ts +++ b/src/lib/exporter/frameRenderer.ts @@ -118,6 +118,7 @@ interface FrameRenderConfig { previewHeight?: number; cursorTelemetry?: CursorTelemetryPoint[]; showCursor?: boolean; + alwaysUsePointerCursor?: boolean; cursorStyle?: CursorStyle; cursorSize?: number; cursorSmoothing?: number; @@ -434,6 +435,7 @@ export class FrameRenderer { this.cursorOverlay = new PixiCursorOverlay({ dotRadius: DEFAULT_CURSOR_CONFIG.dotRadius * (this.config.cursorSize ?? 1.4), style: this.config.cursorStyle ?? "tahoe", + alwaysUsePointerCursor: this.config.alwaysUsePointerCursor ?? false, smoothingFactor: this.config.cursorSmoothing ?? DEFAULT_CURSOR_CONFIG.smoothingFactor, springTuning: { diff --git a/src/lib/exporter/gifExporter.ts b/src/lib/exporter/gifExporter.ts index 4c8338529..a58b13384 100644 --- a/src/lib/exporter/gifExporter.ts +++ b/src/lib/exporter/gifExporter.ts @@ -67,6 +67,7 @@ interface GifExporterConfig { autoCaptionSettings?: AutoCaptionSettings; cursorTelemetry?: CursorTelemetryPoint[]; showCursor?: boolean; + alwaysUsePointerCursor?: boolean; cursorStyle?: CursorStyle; cursorSize?: number; cursorSmoothing?: number; @@ -197,6 +198,7 @@ export class GifExporter { previewHeight: this.config.previewHeight, cursorTelemetry: this.config.cursorTelemetry, showCursor: this.config.showCursor, + alwaysUsePointerCursor: this.config.alwaysUsePointerCursor, cursorStyle: this.config.cursorStyle, cursorSize: this.config.cursorSize, cursorSmoothing: this.config.cursorSmoothing, diff --git a/src/lib/exporter/modernFrameRenderer.ts b/src/lib/exporter/modernFrameRenderer.ts index 5372937fd..e4ebd98d7 100644 --- a/src/lib/exporter/modernFrameRenderer.ts +++ b/src/lib/exporter/modernFrameRenderer.ts @@ -136,6 +136,7 @@ interface FrameRenderConfig { previewHeight?: number; cursorTelemetry?: CursorTelemetryPoint[]; showCursor?: boolean; + alwaysUsePointerCursor?: boolean; cursorStyle?: CursorStyle; cursorSize?: number; cursorSmoothing?: number; @@ -608,6 +609,7 @@ export class FrameRenderer { this.cursorOverlay = new PixiCursorOverlay({ dotRadius: DEFAULT_CURSOR_CONFIG.dotRadius * (this.config.cursorSize ?? 1.4), style: this.config.cursorStyle ?? "tahoe", + alwaysUsePointerCursor: this.config.alwaysUsePointerCursor ?? false, smoothingFactor: this.config.cursorSmoothing ?? DEFAULT_CURSOR_CONFIG.smoothingFactor, springTuning: { diff --git a/src/lib/exporter/modernVideoExporter.ts b/src/lib/exporter/modernVideoExporter.ts index 679c9a9da..1210ecc77 100644 --- a/src/lib/exporter/modernVideoExporter.ts +++ b/src/lib/exporter/modernVideoExporter.ts @@ -120,6 +120,7 @@ interface VideoExporterConfig extends ExportConfig { autoCaptionSettings?: AutoCaptionSettings; cursorTelemetry?: CursorTelemetryPoint[]; showCursor?: boolean; + alwaysUsePointerCursor?: boolean; cursorStyle?: CursorStyle; cursorSize?: number; cursorSmoothing?: number; @@ -603,6 +604,7 @@ export class ModernVideoExporter { previewHeight: this.config.previewHeight, cursorTelemetry: this.config.cursorTelemetry, showCursor: this.config.showCursor, + alwaysUsePointerCursor: this.config.alwaysUsePointerCursor, cursorStyle: this.config.cursorStyle, cursorSize: this.config.cursorSize, cursorSmoothing: this.config.cursorSmoothing, @@ -2021,6 +2023,7 @@ export class ModernVideoExporter { clickBounce: this.config.cursorClickBounce, clickBounceDurationMs: this.config.cursorClickBounceDuration, sourceCrop: this.config.cropRegion, + alwaysUsePointerCursor: this.config.alwaysUsePointerCursor, }); } diff --git a/src/lib/exporter/nativeStaticLayoutTelemetry.ts b/src/lib/exporter/nativeStaticLayoutTelemetry.ts index 7a8cda118..402e4d53e 100644 --- a/src/lib/exporter/nativeStaticLayoutTelemetry.ts +++ b/src/lib/exporter/nativeStaticLayoutTelemetry.ts @@ -18,6 +18,7 @@ export type NativeStaticLayoutCursorTelemetryOptions = { clickBounce?: number; clickBounceDurationMs?: number; sourceCrop?: CropRegion; + alwaysUsePointerCursor?: boolean; }; const CURSOR_POSITION_EPSILON = 0.00001; @@ -144,12 +145,15 @@ function createMonotonicCursorRenderSampler( } const projectedPosition = projectCursorPositionToViewport(position, options.sourceCrop); + const effectiveCursorType: CursorTelemetryPoint["cursorType"] = options.alwaysUsePointerCursor + ? "pointer" + : latestStableCursorType; return { ...position, cx: projectedPosition.cx, cy: projectedPosition.cy, - cursorType: latestStableCursorType, - cursorTypeIndex: getCursorTypeIndex(latestStableCursorType), + cursorType: effectiveCursorType, + cursorTypeIndex: getCursorTypeIndex(effectiveCursorType), bounceScale: getCursorBounceScale(latestClick, timeMs, options), ...(options.sourceCrop ? { visible: projectedPosition.visible } : {}), }; diff --git a/src/lib/exporter/videoExporter.ts b/src/lib/exporter/videoExporter.ts index b99f5f96c..19b66b840 100644 --- a/src/lib/exporter/videoExporter.ts +++ b/src/lib/exporter/videoExporter.ts @@ -76,6 +76,7 @@ interface VideoExporterConfig extends ExportConfig { autoCaptionSettings?: AutoCaptionSettings; cursorTelemetry?: CursorTelemetryPoint[]; showCursor?: boolean; + alwaysUsePointerCursor?: boolean; cursorStyle?: CursorStyle; cursorSize?: number; cursorSmoothing?: number; @@ -251,6 +252,7 @@ export class VideoExporter { previewHeight: this.config.previewHeight, cursorTelemetry: this.config.cursorTelemetry, showCursor: this.config.showCursor, + alwaysUsePointerCursor: this.config.alwaysUsePointerCursor, cursorStyle: this.config.cursorStyle, cursorSize: this.config.cursorSize, cursorSmoothing: this.config.cursorSmoothing,