From e9c069d35690d72ae7a6a81691bd9e37b9a9c913 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Fri, 6 Sep 2024 15:43:08 +0200 Subject: [PATCH] Message: Fix Offscreen Canvas blur error after sending a message --- src/hooks/useOffscreenCanvasBlur.ts | 13 +++++++------ src/lib/offscreen-canvas/offscreen-canvas.worker.ts | 12 ++++++++++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/hooks/useOffscreenCanvasBlur.ts b/src/hooks/useOffscreenCanvasBlur.ts index a023bd2be..53fadc328 100644 --- a/src/hooks/useOffscreenCanvasBlur.ts +++ b/src/hooks/useOffscreenCanvasBlur.ts @@ -8,29 +8,30 @@ const RADIUS = 7; let lastWorkerIndex = -1; export default function useOffscreenCanvasBlur( - dataUri?: string, + 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(); useLayoutEffect(() => { - if (!dataUri || isDisabled) return; + if (!thumbData || isDisabled || offscreenRef.current) return; const canvas = canvasRef.current; if (!canvas) return; - const offscreen = canvas.transferControlToOffscreen(); + offscreenRef.current = canvas.transferControlToOffscreen(); const { connector } = launchMediaWorkers()[workerIndex]; connector.request({ name: 'blurThumb', - args: [offscreen, dataUri, radius], - transferables: [offscreen], + args: [offscreenRef.current, thumbData, radius], + transferables: [offscreenRef.current], }); - }, [dataUri, isDisabled, radius, workerIndex]); + }, [thumbData, isDisabled, radius, workerIndex]); return canvasRef; } diff --git a/src/lib/offscreen-canvas/offscreen-canvas.worker.ts b/src/lib/offscreen-canvas/offscreen-canvas.worker.ts index cd574f509..eb0e65558 100644 --- a/src/lib/offscreen-canvas/offscreen-canvas.worker.ts +++ b/src/lib/offscreen-canvas/offscreen-canvas.worker.ts @@ -3,8 +3,10 @@ import fastBlur from '../fastBlur'; const FAST_BLUR_ITERATIONS = 2; -export async function blurThumb(canvas: OffscreenCanvas, dataUri: string, radius: number) { - const imageBitmap = await dataUriToImageBitmap(dataUri); +export async function blurThumb(canvas: OffscreenCanvas, thumbData: string, radius: number) { + const imageBitmap = thumbData.startsWith('data:') + ? await dataUriToImageBitmap(thumbData) + : await blobUrlToImageBitmap(thumbData); const { width, height } = canvas; const ctx = canvas.getContext('2d')!; const isFilterSupported = 'filter' in ctx; @@ -35,6 +37,12 @@ function dataUriToImageBitmap(dataUri: string) { return createImageBitmap(blob); } +async function blobUrlToImageBitmap(blobUrl: string) { + const response = await fetch(blobUrl); + const blob = await response.blob(); + return createImageBitmap(blob); +} + const api = { blurThumb }; createWorkerInterface(api, 'media');