93 lines
2.4 KiB
Vue
93 lines
2.4 KiB
Vue
<script setup lang="ts">
|
|
const settingsStore = useSettingsStore()
|
|
import { off } from 'process';
|
|
import ShaderWorker from '~/assets/workers/ShaderWorker?worker'
|
|
const worker = new ShaderWorker()
|
|
|
|
const canvas = ref<HTMLCanvasElement | null>(null)
|
|
|
|
export interface Props {
|
|
colorStart?: [number, number, number]
|
|
colorEnd?: [number, number, number]
|
|
}
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
colorStart: () => [0, .3, 0],
|
|
colorEnd: () => [0, 1, 0]
|
|
})
|
|
|
|
function initShader() {
|
|
if (!canvas.value) { return }
|
|
const offscreen = canvas.value?.transferControlToOffscreen()
|
|
worker.postMessage({
|
|
command: "initShader",
|
|
canvas: offscreen
|
|
}, [offscreen])
|
|
}
|
|
function safeReloadShader() {
|
|
reloadShader()
|
|
}
|
|
|
|
function reloadShader() {
|
|
const bounds = canvas.value?.getBoundingClientRect()
|
|
if (!bounds) { return }
|
|
worker.postMessage({
|
|
command: 'reloadShader',
|
|
quality: settingsStore.shaderQuality,
|
|
framerate: settingsStore.shaderFramerate,
|
|
bounds: { left: bounds.left, bottom: bounds.bottom },
|
|
screen: { height: window.screen.height, width: window.screen.width, devicePixelRatio },
|
|
shaderOptions: { quality: settingsStore.shaderQuality, framerate: settingsStore.shaderFramerate },
|
|
colorStart: props.colorStart,
|
|
colorEnd: props.colorEnd
|
|
})
|
|
}
|
|
|
|
function resizeShader() {
|
|
const bounds = canvas.value?.getBoundingClientRect()
|
|
if (!bounds) { return }
|
|
worker.postMessage({
|
|
command: 'changeBounds',
|
|
bounds: { left: bounds.left, bottom: bounds.bottom },
|
|
screen: { height: window.screen.height, width: window.screen.width, devicePixelRatio },
|
|
})
|
|
}
|
|
|
|
function endShader() {
|
|
worker.postMessage({
|
|
command: 'killShader'
|
|
})
|
|
}
|
|
|
|
watch(() => [settingsStore.shaderQuality, settingsStore.shaderFramerate, props.colorEnd, props.colorStart], () => {
|
|
safeReloadShader()
|
|
})
|
|
|
|
|
|
onMounted(async () => {
|
|
nextTick(() => {
|
|
initShader()
|
|
window.addEventListener("resize", resizeShader, true)
|
|
safeReloadShader()
|
|
})
|
|
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
window.removeEventListener("resize", resizeShader)
|
|
endShader()
|
|
})
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<canvas v-if="settingsStore.shaderQuality != 0" ref="canvas" id="background">test</canvas>
|
|
</template>
|
|
|
|
<style scoped>
|
|
#background {
|
|
left: 0;
|
|
position: absolute;
|
|
height: 100%;
|
|
width: 100%;
|
|
}
|
|
</style> |