133 lines
3.3 KiB
Vue
133 lines
3.3 KiB
Vue
<script setup lang="ts">
|
|
const settingsStore = useSettingsStore()
|
|
|
|
import gsap from 'gsap';
|
|
import ShaderWorker from '~/assets/workers/ShaderWorker?worker'
|
|
import goStore from '~/netcode';
|
|
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]
|
|
colorEnd?: [number, number, number]
|
|
}
|
|
|
|
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
colorStart: () => [0, .3, 0],
|
|
colorEnd: () => [0, 1, 0]
|
|
})
|
|
|
|
const _colorStart = reactive(props.colorStart)
|
|
const _colorEnd = reactive(props.colorEnd)
|
|
|
|
|
|
function initShader() {
|
|
if (!canvas.value) { return }
|
|
const offscreen = canvas.value?.transferControlToOffscreen()
|
|
worker.postMessage({
|
|
command: "initShader",
|
|
canvas: offscreen,
|
|
screen: { height: window.innerHeight * devicePixelRatio, width: window.innerWidth * devicePixelRatio, devicePixelRatio },
|
|
shaderOptions: { quality: settingsStore.shaderQuality, framerate: settingsStore.shaderFramerate },
|
|
}, [offscreen])
|
|
if (settingsStore.shaderFramerate == 0) {
|
|
killShader()
|
|
}
|
|
resizeShader()
|
|
}
|
|
|
|
function recolorShader() {
|
|
worker.postMessage({
|
|
command: 'recolorShader',
|
|
colorStart: [..._colorStart],
|
|
colorEnd: [..._colorEnd]
|
|
})
|
|
}
|
|
|
|
function resizeShader() {
|
|
worker.postMessage({
|
|
command: 'resizeShader',
|
|
screen: { height: window.innerHeight * devicePixelRatio, width: window.innerWidth * devicePixelRatio, devicePixelRatio },
|
|
shaderOptions: { quality: settingsStore.shaderQuality, framerate: settingsStore.shaderFramerate },
|
|
})
|
|
}
|
|
|
|
function killShader() {
|
|
worker.postMessage({
|
|
command: 'killShader'
|
|
})
|
|
}
|
|
|
|
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()
|
|
})
|
|
|
|
watch(() => [goStore.current_game?.current_turn], () => {
|
|
if (goStore.current_game?.current_turn != goStore.self?.team) {
|
|
gsap.to(_colorStart, { duration: 0.5, 0: 0, 1: .2, 2: .3 })
|
|
gsap.to(_colorEnd, { duration: 0.5, 0: 0, 1: 1, 2: 1 })
|
|
} else {
|
|
gsap.to(_colorStart, { duration: 0.5, 0: 0, 1: .3, 2: 0 })
|
|
gsap.to(_colorEnd, { duration: 0.5, 0: 0, 1: 1, 2: 0 })
|
|
}
|
|
}, { immediate: true })
|
|
|
|
|
|
watch([_colorEnd, _colorStart], () => {
|
|
recolorShader()
|
|
})
|
|
|
|
onMounted(async () => {
|
|
nextTick(() => {
|
|
recolorShader()
|
|
initShader()
|
|
window.addEventListener("resize", resizeShader, true)
|
|
})
|
|
})
|
|
|
|
onUnmounted(() => {
|
|
window.removeEventListener("resize", resizeShader)
|
|
killShader()
|
|
})
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<canvas ref="canvas" id="background" :class="{ pixelated: settingsStore.shaderPixelated }" width="480"
|
|
height="270">test</canvas>
|
|
</template>
|
|
|
|
<style scoped>
|
|
#background {
|
|
left: 0;
|
|
position: absolute;
|
|
height: 100%;
|
|
width: 100%;
|
|
image-rendering: smooth;
|
|
}
|
|
|
|
#background.pixelated {
|
|
image-rendering: pixelated;
|
|
}
|
|
</style> |