diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 841f99f..fa7d1f4 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -83,6 +83,7 @@ function App() {
+
{isShaderTheme && }
diff --git a/frontend/src/ShaderBackground.tsx b/frontend/src/ShaderBackground.tsx
index fe9725e..522806a 100644
--- a/frontend/src/ShaderBackground.tsx
+++ b/frontend/src/ShaderBackground.tsx
@@ -2,6 +2,7 @@ import { useEffect, useRef } from "react";
import BLACKHOLE_SHADER_CODE from "./assets/blackhole.glsl?raw";
import STAR_SHADER_CODE from "./assets/star.glsl?raw";
+import BALL_SHADER_CODE from "./assets/ball.glsl?raw";
function buildProgram(
ctx: WebGL2RenderingContext,
@@ -117,7 +118,9 @@ type ShaderBackgroundProps = {
theme: string;
};
-export const ShaderBackground: React.FC = ({ theme }) => {
+export const ShaderBackground: React.FC = ({
+ theme,
+}) => {
const canvasRef = useRef(null);
useEffect(() => {
@@ -139,6 +142,9 @@ export const ShaderBackground: React.FC = ({ theme }) =>
case "star":
shader_code = STAR_SHADER_CODE;
break;
+ case "ball":
+ shader_code = BALL_SHADER_CODE;
+ break;
default:
console.error("Unknown shader theme:", theme);
return;
@@ -179,7 +185,13 @@ export const ShaderBackground: React.FC = ({ theme }) =>
function setResolution(program: WebGLProgram) {
const loc = gl!.getUniformLocation(program, "iResolution");
- if (loc) gl!.uniform3fv(loc, [canvas!.width, canvas!.height, 1]);
+ canvas!.width = window.visualViewport!.width;
+ canvas!.height = window.visualViewport!.height;
+ if (loc) gl!.uniform3fv(loc, [
+ window.visualViewport!.width,
+ window.visualViewport!.height,
+ 1,
+ ]);
}
function setTime(program: WebGLProgram, now: number) {
@@ -191,7 +203,12 @@ export const ShaderBackground: React.FC = ({ theme }) =>
const ichannel1_texture = loadTexture(gl, "assets/small_noise.png");
- gl!.viewport(0, 0, canvas!.width, canvas!.height);
+ gl!.viewport(
+ 0,
+ 0,
+ window.visualViewport!.width,
+ window.visualViewport!.height
+ );
gl!.useProgram(finalProgram);
setResolution(finalProgram!);
@@ -227,7 +244,6 @@ export const ShaderBackground: React.FC = ({ theme }) =>
top: 0,
left: 0,
zIndex: -1,
- pointerEvents: "none",
}}
/>
);
diff --git a/frontend/src/assets/ball.glsl b/frontend/src/assets/ball.glsl
new file mode 100644
index 0000000..ab67992
--- /dev/null
+++ b/frontend/src/assets/ball.glsl
@@ -0,0 +1,23 @@
+#version 300 es
+precision highp float;
+uniform vec3 iResolution;
+uniform float iTime;
+
+out vec4 FragColor;
+
+#define PALETTE vec3(9,4,0)
+
+void mainImage(out vec4 o, vec2 u) {
+ float n, i, s, t = iTime * .2, d, v;
+ vec3 q, p = iResolution, c;
+ u = (u + u - p.xy) / p.y;
+ vec2 l = u - (u.yx * .9 + .3 - vec2(-.35, .15));
+ for(; i++ < 5e1 && d < 5e1; d += s = min(q.y = .01 + .6 * abs(24. - length(q.xy)), v = max(s, dot(abs(fract(p) - .5), vec3(.04)))), c += (1. + cos(p.z + PALETTE)) / v + d * vec3(5, 2, 1) / q.y / 1e1 + 7. * vec3(3, 4, 1) / length(l)) for(q = p = vec3(u * d, d - 16.), s = length(p) - 8., p.xy *= mat2(cos(t + p.z * .6 + vec4(0, 33, 11, 0))), p += cos(t + p.zxy) + cos(t + p.yzx * s) / s / 4., p += .5 * cos(t + dot(cos(t + p), p) * p), n = .02; n < 2.; n *= 1.6) q.y -= abs(dot(sin(4. * t + .3 * q / n), q - q + n));
+
+ c = mix(c, c.yzx, smoothstep(2., .1, length(u) * 1.));
+ o.rgb = tanh(c * c / 6e7 / length(u - .3) + .1 * length(u));
+}
+
+void main() {
+ mainImage(FragColor, gl_FragCoord.xy);
+}
\ No newline at end of file
diff --git a/frontend/src/assets/react.svg b/frontend/src/assets/react.svg
deleted file mode 100644
index 6c87de9..0000000
--- a/frontend/src/assets/react.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file