From 77a103223bed665fb63babb71a191540c5afce2d Mon Sep 17 00:00:00 2001 From: zubiden <19638254+zubiden@users.noreply.github.com> Date: Fri, 20 Dec 2024 11:37:05 +0100 Subject: [PATCH] Media: Fix blurred thumb size (#5309) --- src/hooks/useOffscreenCanvasBlur.ts | 38 +++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/hooks/useOffscreenCanvasBlur.ts b/src/hooks/useOffscreenCanvasBlur.ts index b25d1b097..4e3643363 100644 --- a/src/hooks/useOffscreenCanvasBlur.ts +++ b/src/hooks/useOffscreenCanvasBlur.ts @@ -1,36 +1,54 @@ import { useLayoutEffect, useMemo, useRef } from '../lib/teact/teact'; +import { requestMutation } from '../lib/fasterdom/fasterdom'; import cycleRestrict from '../util/cycleRestrict'; +import { preloadImage } from '../util/files'; import { MAX_WORKERS, requestMediaWorker } from '../util/launchMediaWorkers'; +import useLastCallback from './useLastCallback'; -const RADIUS = 7; +const RADIUS_RATIO = 0.1; // Use 10% of the smallest dimension as the blur radius let lastWorkerIndex = -1; export default function useOffscreenCanvasBlur( thumbData?: string, // data URI or blob URL isDisabled = false, - radius = RADIUS, ) { // eslint-disable-next-line no-null/no-null const canvasRef = useRef(null); const workerIndex = useMemo(() => cycleRestrict(MAX_WORKERS, ++lastWorkerIndex), []); const offscreenRef = useRef(); + const blurThumb = useLastCallback(async (canvas: HTMLCanvasElement, uri: string) => { + const image = await preloadImage(uri); + if (!image) { + return; + } + + requestMutation(() => { + canvas.width = image.width; + canvas.height = image.height; + + offscreenRef.current = canvas.transferControlToOffscreen(); + + const radius = Math.ceil(Math.min(image.width, image.height) * RADIUS_RATIO); + + requestMediaWorker({ + name: 'offscreen-canvas:blurThumb', + args: [offscreenRef.current, uri, radius], + transferables: [offscreenRef.current], + }, workerIndex); + }); + }); + useLayoutEffect(() => { if (!thumbData || isDisabled || offscreenRef.current) return; const canvas = canvasRef.current; if (!canvas) return; - offscreenRef.current = canvas.transferControlToOffscreen(); - - requestMediaWorker({ - name: 'offscreen-canvas:blurThumb', - args: [offscreenRef.current, thumbData, radius], - transferables: [offscreenRef.current], - }, workerIndex); - }, [thumbData, isDisabled, radius, workerIndex]); + blurThumb(canvas, thumbData); + }, [blurThumb, isDisabled, thumbData]); return canvasRef; }