Feat : handle settings gracefully

This commit is contained in:
2024-05-24 17:19:31 +02:00
parent 766dc92931
commit 4ea5c25a47
5 changed files with 131 additions and 77 deletions
+41 -35
View File
@@ -5,6 +5,7 @@ import ShaderWorker from '~/assets/workers/ShaderWorker?worker'
const worker = new ShaderWorker()
const canvas = ref<HTMLCanvasElement | null>(null)
const canvas_resize_temp = ref<HTMLCanvasElement | null>(null)
export interface Props {
colorStart?: [number, number, number]
@@ -20,80 +21,80 @@ function initShader() {
const offscreen = canvas.value?.transferControlToOffscreen()
worker.postMessage({
command: "initShader",
canvas: offscreen
canvas: offscreen,
screen: { height: window.innerHeight * devicePixelRatio, width: window.innerWidth * devicePixelRatio, devicePixelRatio },
shaderOptions: { quality: settingsStore.shaderQuality, framerate: settingsStore.shaderFramerate },
}, [offscreen])
}
function safeReloadShader() {
reloadShader()
if (settingsStore.shaderFramerate == 0) {
killShader()
}
resizeShader()
}
function reloadShader() {
const bounds = canvas.value?.getBoundingClientRect()
if (!bounds) { return }
function recolorShader() {
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 },
command: 'recolorShader',
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 },
colorStart: props.colorStart,
colorEnd: props.colorEnd
command: 'resizeShader',
screen: { height: window.innerHeight * devicePixelRatio, width: window.innerWidth * devicePixelRatio, devicePixelRatio },
shaderOptions: { quality: settingsStore.shaderQuality, framerate: settingsStore.shaderFramerate },
})
}
function endShader() {
function killShader() {
worker.postMessage({
command: 'killShader'
})
}
watch(() => [settingsStore.shaderQuality, settingsStore.shaderFramerate], () => {
safeReloadShader()
function resumeShader() {
worker.postMessage({
command: 'resumeShader',
shaderOptions: { quality: settingsStore.shaderQuality, framerate: settingsStore.shaderFramerate },
})
}
watch(() => [settingsStore.shaderFramerate], () => {
if (settingsStore.shaderFramerate == 0) {
killShader()
return
}
resumeShader()
})
watch(() => [settingsStore.shaderQuality], () => {
resizeShader()
})
let has_resized = false
watch(() => [props.colorEnd, props.colorStart], () => {
if (!has_resized) {
has_resized = true
nextTick(() => {
resizeShader()
has_resized = false
})
}
recolorShader()
})
onMounted(async () => {
nextTick(() => {
recolorShader()
initShader()
window.addEventListener("resize", resizeShader, true)
safeReloadShader()
})
})
onUnmounted(() => {
window.removeEventListener("resize", resizeShader)
endShader()
killShader()
})
</script>
<template>
<canvas v-if="settingsStore.shaderQuality != 0" ref="canvas" id="background">test</canvas>
<canvas ref="canvas" id="background" :class="{ pixelated: settingsStore.shaderPixelated }" width="480"
height="270">test</canvas>
</template>
<style scoped>
@@ -102,5 +103,10 @@ onUnmounted(() => {
position: absolute;
height: 100%;
width: 100%;
image-rendering: smooth;
}
#background.pixelated {
image-rendering: crisp-edges;
}
</style>
+15 -15
View File
@@ -6,6 +6,9 @@ export interface Props {
isVisible: boolean;
}
const _devicePixelRatio = computed(() => devicePixelRatio)
const _window = computed(() => window)
const props = withDefaults(defineProps<Props>(), {
})
@@ -15,10 +18,6 @@ const close = () => {
emit('close')
}
watch(() => settingsStore.shaderQuality, async () => {
console.log(settingsStore.shaderQuality)
})
</script>
<template>
@@ -40,27 +39,28 @@ watch(() => settingsStore.shaderQuality, async () => {
<span>Shader Quality</span>
</div>
<div class="dialog-body">
<input type="range" min="0" max="10" v-model="settingsStore.shaderQuality">
<input type="range" min="1" max="10" v-model="settingsStore.shaderQuality">
</div>
<div class="dialog-footer">
<span>
<template v-if="settingsStore.shaderQuality == 0">
Disabled
</template>
<template v-if="settingsStore.shaderQuality > 0">
{{ settingsStore.shaderQuality }}
</template>
</span>
<span>{{ _window.innerWidth * _devicePixelRatio * settingsStore.shaderQuality / 10 }}x{{ _window.innerHeight *
_devicePixelRatio * settingsStore.shaderQuality / 10 }}</span>
</div>
<div class="dialog-header">
<span>Shader Framerate</span>
</div>
<div class="dialog-body">
<input type="range" min="10" max="60" step="5" v-model="settingsStore.shaderFramerate"
<input type="range" min="0" max="65" step="5" v-model="settingsStore.shaderFramerate"
:disabled="settingsStore.shaderQuality == 0">
</div>
<div class="dialog-footer">
<span>{{ settingsStore.shaderFramerate }} fps</span>
<span v-if="settingsStore.shaderFramerate == 65">vsync</span>
<span v-else>{{ settingsStore.shaderFramerate }} fps</span>
</div>
<div class="dialog-header">
<span>Pixelated</span>
</div>
<div class="dialog-body">
<input type="checkbox" v-model="settingsStore.shaderPixelated">
</div>
</div>
</div>