wip
This commit is contained in:
		@@ -22,8 +22,13 @@ import TestWebGL2 from '@/workers/test-webgl2?worker';
 | 
			
		||||
const workerPromise = new Promise<Worker | null>(resolve => {
 | 
			
		||||
	const testWorker = new TestWebGL2();
 | 
			
		||||
	testWorker.addEventListener('message', event => {
 | 
			
		||||
		if (event.data.result) resolve(new DrawBlurhash());
 | 
			
		||||
		else resolve(null);
 | 
			
		||||
		if (event.data.result) {
 | 
			
		||||
			console.log('WebGL2 is supported in worker.')
 | 
			
		||||
			resolve(new DrawBlurhash());
 | 
			
		||||
		} else {
 | 
			
		||||
			console.log('WebGL2 is not supported in worker.')
 | 
			
		||||
			resolve(null);
 | 
			
		||||
		}
 | 
			
		||||
		testWorker.terminate();
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
@@ -74,6 +79,7 @@ let canvasWidth = $ref(64);
 | 
			
		||||
let canvasHeight = $ref(64);
 | 
			
		||||
let imgWidth = $ref(props.width);
 | 
			
		||||
let imgHeight = $ref(props.height);
 | 
			
		||||
let bitmapTmp = $ref<ImageBitmap | undefined>();
 | 
			
		||||
const hide = computed(() => !loaded || props.forceBlurhash);
 | 
			
		||||
 | 
			
		||||
function waitForDecode() {
 | 
			
		||||
@@ -108,19 +114,43 @@ watch([() => props.width, () => props.height, root], () => {
 | 
			
		||||
	immediate: true,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
async function draw(transfer: boolean = false) {
 | 
			
		||||
workerPromise.then(worker => {
 | 
			
		||||
	if (!worker) return;
 | 
			
		||||
 | 
			
		||||
	worker.postMessage({
 | 
			
		||||
		id: viewId,
 | 
			
		||||
		hash: props.hash,
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
	worker.addEventListener('message', event => {
 | 
			
		||||
		if (event.data.id !== viewId) return;
 | 
			
		||||
		drawImage(event.data.bitmap as ImageBitmap);
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
function drawImage(bitmap: CanvasImageSource) {
 | 
			
		||||
	// canvasがない(mountedされていない)場合はTmpに保存しておく
 | 
			
		||||
	if (!canvas.value) {
 | 
			
		||||
		bitmapTmp = bitmap;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bitmapTmp = undefined;
 | 
			
		||||
 | 
			
		||||
	// canvasがあったらすぐに描画する
 | 
			
		||||
	const ctx = canvas.value.getContext('2d');
 | 
			
		||||
	if (!ctx) return;
 | 
			
		||||
	ctx.drawImage(bitmap, 0, 0, canvasWidth, canvasHeight);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function draw() {
 | 
			
		||||
	if (!canvas.value || props.hash == null) return;
 | 
			
		||||
	const worker = await workerPromise;
 | 
			
		||||
	if (worker) {
 | 
			
		||||
		let offscreen: OffscreenCanvas | undefined;
 | 
			
		||||
		if (transfer) {
 | 
			
		||||
			offscreen = canvas.value.transferControlToOffscreen();
 | 
			
		||||
		}
 | 
			
		||||
		worker.postMessage({
 | 
			
		||||
			id: viewId,
 | 
			
		||||
			canvas: offscreen ?? undefined,
 | 
			
		||||
			hash: props.hash,
 | 
			
		||||
		}, offscreen ? [offscreen] : []);
 | 
			
		||||
		});
 | 
			
		||||
	} else {
 | 
			
		||||
		try {
 | 
			
		||||
			const work = document.createElement('canvas');
 | 
			
		||||
@@ -128,8 +158,7 @@ async function draw(transfer: boolean = false) {
 | 
			
		||||
			work.height = canvasHeight;
 | 
			
		||||
			render(props.hash, work);
 | 
			
		||||
			const bitmap = await createImageBitmap(work);
 | 
			
		||||
			const ctx = canvas.value.getContext('2d');
 | 
			
		||||
			ctx?.drawImage(bitmap, 0, 0, canvasWidth, canvasHeight);
 | 
			
		||||
			drawImage(bitmap);
 | 
			
		||||
		} catch (error) {
 | 
			
		||||
			console.error('Error occured during drawing blurhash', error);
 | 
			
		||||
		}
 | 
			
		||||
@@ -145,8 +174,10 @@ watch(() => props.hash, () => {
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
	draw(true);
 | 
			
		||||
	waitForDecode();
 | 
			
		||||
	// drawImageがmountedより先に呼ばれている場合はここで描画する
 | 
			
		||||
	if (bitmapTmp) {
 | 
			
		||||
		drawImage(bitmapTmp);
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
onUnmounted(() => {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,15 @@
 | 
			
		||||
import { render } from 'buraha';
 | 
			
		||||
 | 
			
		||||
const canvases = new Map<string, OffscreenCanvas>();
 | 
			
		||||
 | 
			
		||||
onmessage = async (event) => {
 | 
			
		||||
    // console.log(event.data);
 | 
			
		||||
    if (!('id' in event.data && typeof event.data.id === 'string')) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (event.data.delete) {
 | 
			
		||||
        canvases.delete(event.data.id);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (event.data.canvas) {
 | 
			
		||||
        canvases.set(event.data.id, event.data.canvas);
 | 
			
		||||
    }
 | 
			
		||||
    if (!('hash' in event.data && typeof event.data.hash === 'string')) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    const canvas = event.data.canvas ?? canvases.get(event.data.id);
 | 
			
		||||
    if (!canvas) {
 | 
			
		||||
        throw new Error('No canvas');
 | 
			
		||||
    }
 | 
			
		||||
    const work = new OffscreenCanvas(canvas.width, canvas.height);
 | 
			
		||||
    render(event.data.hash, work);
 | 
			
		||||
    const bitmap = await createImageBitmap(work);
 | 
			
		||||
    const ctx = canvas.getContext('2d');
 | 
			
		||||
    ctx?.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
 | 
			
		||||
    postMessage({ result: true });
 | 
			
		||||
    postMessage({ id: event.data.id, bitmap });
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user