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