Files
front/components/AnimatedBackground.vue
T

119 lines
3.4 KiB
Vue

<script setup lang="ts">
import noise from "~/assets/shaders/noise.frag?raw"
const canvas = ref<HTMLCanvasElement | null>(null)
declare const webglUtils: {
createProgramFromSources: (gl: WebGLRenderingContext, array: [string, string]) => any,
resizeCanvasToDisplaySize: (e: HTMLCanvasElement | OffscreenCanvas) => any
}
declare const resolveLygiaAsync: (source: string) => Promise<string>
async function main(canvas: HTMLCanvasElement) {
// Get A WebGL context
/** @type {HTMLCanvasElement} */
const gl = canvas.getContext("webgl");
if (!gl) {
return;
}
const vs = `attribute vec4 a_position;void main() {gl_Position = a_position;}`;
const fs = await resolveLygiaAsync(noise);
// setup GLSL program
const program = webglUtils.createProgramFromSources(gl, [vs, fs]);
// look up where the vertex data needs to go.
const positionAttributeLocation = gl.getAttribLocation(program, "a_position");
// look up uniform locations
const resolutionLocation = gl.getUniformLocation(program, "u_resolution");
const mouseLocation = gl.getUniformLocation(program, "u_mouse");
const timeLocation = gl.getUniformLocation(program, "u_time");
// Create a buffer to put three 2d clip space points in
const positionBuffer = gl.createBuffer();
// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// fill it with a 2 triangles that cover clipspace
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1, -1, // first triangle
1, -1,
-1, 1,
-1, 1, // second triangle
1, -1,
1, 1,
]), gl.STATIC_DRAW);
let mouseX = 0;
let mouseY = 0;
function render(time: number) {
if (!gl) { return }
time *= 0.001; // convert to seconds
webglUtils.resizeCanvasToDisplaySize(gl.canvas);
// Tell WebGL how to convert from clip space to pixels
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
// Tell it to use our program (pair of shaders)
gl.useProgram(program);
// Turn on the attribute
gl.enableVertexAttribArray(positionAttributeLocation);
// Bind the position buffer.
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER)
gl.vertexAttribPointer(
positionAttributeLocation,
2, // 2 components per iteration
gl.FLOAT, // the data is 32bit floats
false, // don't normalize the data
0, // 0 = move forward size * sizeof(type) each iteration to get the next position
0, // start at the beginning of the buffer
);
gl.uniform2f(resolutionLocation, gl.canvas.width, gl.canvas.height);
gl.uniform2f(mouseLocation, mouseX, mouseY);
gl.uniform1f(timeLocation, time);
gl.drawArrays(
gl.TRIANGLES,
0, // offset
6, // num vertices to process
);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
onMounted(() => {
if (!canvas.value) { return }
console.log("e")
main(canvas.value);
})
</script>
<template>
<canvas ref="canvas" id="background">test</canvas>
</template>
<style scoped>
#background {
z-index: -1;
left: 0;
position: absolute;
height: 100%;
width: 100%;
}
</style>