diff --git a/LandingPage/package-lock.json b/LandingPage/package-lock.json index f3f9e25..f7ce559 100644 --- a/LandingPage/package-lock.json +++ b/LandingPage/package-lock.json @@ -4259,21 +4259,6 @@ "dev": true, "license": "ISC" }, - "node_modules/yaml": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", - "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/LandingPage/src/App.tsx b/LandingPage/src/App.tsx index 3ac0eab..55d1e1f 100644 --- a/LandingPage/src/App.tsx +++ b/LandingPage/src/App.tsx @@ -1,34 +1,17 @@ import { BrowserRouter, Routes, Route } from 'react-router-dom'; -// import Lenis from '@studio-freight/lenis'; import Landing from '../src/Pages/Landing'; import PrivacyPolicy from './Pages/Privacy'; import TermsOfService from './Pages/Legal'; function App() { - // useEffect(() => { - // const lenis = new Lenis({ - // duration: 1.2, - // easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), - // smoothWheel: true, - // }); - - // function raf(time: number) { - // lenis.raf(time); - // requestAnimationFrame(raf); - // } - - // requestAnimationFrame(raf); - // }, []); - + return ( } /> } /> } /> - {/* } /> */} - {/* */} ); } diff --git a/LandingPage/src/components/bg.tsx b/LandingPage/src/components/bg.tsx index d69b642..9b78850 100644 --- a/LandingPage/src/components/bg.tsx +++ b/LandingPage/src/components/bg.tsx @@ -1,11 +1,12 @@ import React, { useEffect, useRef } from "react"; -import { Renderer, Program, Mesh, Triangle, Color } from "ogl"; +import { Renderer, Program, Mesh, Plane } from "ogl"; -interface ThreadsProps { +interface ThreadsProps extends React.ComponentPropsWithoutRef<"div"> { color?: [number, number, number]; amplitude?: number; distance?: number; enableMouseInteraction?: boolean; + maxDevicePixelRatio?: number; } const vertexShader = ` @@ -29,36 +30,31 @@ uniform float uDistance; uniform vec2 uMouse; #define PI 3.1415926538 - -const int u_line_count = 40; -const float u_line_width = 7.0; -const float u_line_blur = 10.0; - -float Perlin2D(vec2 P) { - vec2 Pi = floor(P); - vec4 Pf_Pfmin1 = P.xyxy - vec4(Pi, Pi + 1.0); - vec4 Pt = vec4(Pi.xy, Pi.xy + 1.0); - Pt = Pt - floor(Pt * (1.0 / 71.0)) * 71.0; - Pt += vec2(26.0, 161.0).xyxy; - Pt *= Pt; - Pt = Pt.xzxz * Pt.yyww; - vec4 hash_x = fract(Pt * (1.0 / 951.135664)); - vec4 hash_y = fract(Pt * (1.0 / 642.949883)); - vec4 grad_x = hash_x - 0.49999; - vec4 grad_y = hash_y - 0.49999; - vec4 grad_results = inversesqrt(grad_x * grad_x + grad_y * grad_y) - * (grad_x * Pf_Pfmin1.xzxz + grad_y * Pf_Pfmin1.yyww); - grad_results *= 1.4142135623730950; - vec2 blend = Pf_Pfmin1.xy * Pf_Pfmin1.xy * Pf_Pfmin1.xy - * (Pf_Pfmin1.xy * (Pf_Pfmin1.xy * 6.0 - 15.0) + 10.0); - vec4 blend2 = vec4(blend, vec2(1.0 - blend)); - return dot(grad_results, blend2.zxzx * blend2.wwyy); -} +const int U_LINE_COUNT = 20; +const float U_LINE_WIDTH = 7.0; +const float U_LINE_BLUR = 10.0; float pixel(float count, vec2 resolution) { return (1.0 / max(resolution.x, resolution.y)) * count; } +float hash21(vec2 p){ + p = fract(p * vec2(123.34, 456.21)); + p += dot(p, p + 45.32); + return fract(p.x * p.y); +} + +float fastNoise(vec2 p) { + vec2 i = floor(p); + vec2 f = fract(p); + float a = hash21(i + vec2(0.0,0.0)); + float b = hash21(i + vec2(1.0,0.0)); + float c = hash21(i + vec2(0.0,1.0)); + float d = hash21(i + vec2(1.0,1.0)); + vec2 u = f*f*(3.0-2.0*f); + return mix(a, b, u.x) + (c - a)*u.y*(1.0 - u.x) + (d - b)*u.x*u.y; +} + float lineFn(vec2 st, float width, float perc, float offset, vec2 mouse, float time, float amplitude, float distance) { float split_offset = (perc * 0.4); float split_point = 0.1 + split_offset; @@ -72,22 +68,22 @@ float lineFn(vec2 st, float width, float perc, float offset, vec2 mouse, float t float blur = smoothstep(split_point, split_point + 0.05, st.x) * perc; float xnoise = mix( - Perlin2D(vec2(time_scaled, st.x + perc) * 2.5), - Perlin2D(vec2(time_scaled, st.x + time_scaled) * 3.5) / 1.5, + fastNoise(vec2(time_scaled, st.x + perc) * 2.5), + fastNoise(vec2(time_scaled, st.x + time_scaled) * 3.5) / 1.5, st.x * 0.3 ); - float y = 0.5 + (perc - 0.5) * distance + xnoise / 2.0 * finalAmplitude; + float y = 0.5 + (perc - 0.5) * distance + (xnoise - 0.5) * finalAmplitude; float line_start = smoothstep( - y + (width / 2.0) + (u_line_blur * pixel(1.0, iResolution.xy) * blur), + y + (width / 2.0) + (U_LINE_BLUR * pixel(1.0, iResolution.xy) * blur), y, st.y ); float line_end = smoothstep( y, - y - (width / 2.0) - (u_line_blur * pixel(1.0, iResolution.xy) * blur), + y - (width / 2.0) - (U_LINE_BLUR * pixel(1.0, iResolution.xy) * blur), st.y ); @@ -102,11 +98,11 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord) { vec2 uv = fragCoord / iResolution.xy; float line_strength = 1.0; - for (int i = 0; i < u_line_count; i++) { - float p = float(i) / float(u_line_count); + for (int i = 0; i < U_LINE_COUNT; i++) { + float p = float(i) / float(U_LINE_COUNT); line_strength *= (1.0 - lineFn( uv, - u_line_width * pixel(1.0, iResolution.xy) * (1.0 - p), + U_LINE_WIDTH * pixel(1.0, iResolution.xy) * (1.0 - p), p, (PI * 1.0) * p, uMouse, @@ -114,6 +110,10 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord) { uAmplitude, uDistance )); + + if (line_strength < 0.001) { + break; + } } float colorVal = 1.0 - line_strength; @@ -130,105 +130,109 @@ const Threads: React.FC = ({ amplitude = 1, distance = 0, enableMouseInteraction = false, + maxDevicePixelRatio = 1.5, + className, ...rest }) => { - const containerRef = useRef(null); - const animationFrameId = useRef(null); + const containerRef = useRef(null); + const rendererRef = useRef(null); + const programRef = useRef(null); + const meshRef = useRef(null); + const animationFrameRef = useRef(null); + const visibleRef = useRef(true); + const mouseTargetRef = useRef<[number, number]>([0.5, 0.5]); + const mouseCurrentRef = useRef<[number, number]>([0.5, 0.5]); useEffect(() => { if (!containerRef.current) return; const container = containerRef.current; const renderer = new Renderer({ alpha: true }); + rendererRef.current = renderer; const gl = renderer.gl; + gl.clearColor(0, 0, 0, 0); gl.enable(gl.BLEND); - gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + container.appendChild(gl.canvas); - const geometry = new Triangle(gl); + const geometry = new Plane(gl, { width: 2, height: 2 }); + const program = new Program(gl, { vertex: vertexShader, fragment: fragmentShader, uniforms: { iTime: { value: 0 }, - iResolution: { - value: new Color( - gl.canvas.width, - gl.canvas.height, - gl.canvas.width / gl.canvas.height - ), - }, - uColor: { value: new Color(...color) }, + iResolution: { value: new Float32Array([0, 0, 0]) }, + uColor: { value: new Float32Array(color) }, uAmplitude: { value: amplitude }, uDistance: { value: distance }, uMouse: { value: new Float32Array([0.5, 0.5]) }, }, }); - const mesh = new Mesh(gl, { geometry, program }); + programRef.current = program; + meshRef.current = new Mesh(gl, { geometry, program }); + + const resize = () => { + const w = container.clientWidth; + const h = container.clientHeight; + renderer.setSize(w, h); + + const res = program.uniforms.iResolution.value as Float32Array; + res[0] = renderer.width; + res[1] = renderer.height; + res[2] = w / h; + }; - function resize() { - const { clientWidth, clientHeight } = container; - renderer.setSize(clientWidth, clientHeight); - program.uniforms.iResolution.value.r = clientWidth; - program.uniforms.iResolution.value.g = clientHeight; - program.uniforms.iResolution.value.b = clientWidth / clientHeight; - } - window.addEventListener("resize", resize); resize(); + window.addEventListener("resize", resize); - let currentMouse = [0.5, 0.5]; - let targetMouse = [0.5, 0.5]; + const observer = new IntersectionObserver((entries) => { + visibleRef.current = entries[0].isIntersecting; + }); + observer.observe(container); - function handleMouseMove(e: MouseEvent) { - const rect = container.getBoundingClientRect(); - const x = (e.clientX - rect.left) / rect.width; - const y = 1.0 - (e.clientY - rect.top) / rect.height; - targetMouse = [x, y]; - } - function handleMouseLeave() { - targetMouse = [0.5, 0.5]; - } - if (enableMouseInteraction) { - container.addEventListener("mousemove", handleMouseMove); - container.addEventListener("mouseleave", handleMouseLeave); - } + const animate = (t: number) => { + animationFrameRef.current = requestAnimationFrame(animate); + + if (!visibleRef.current) return; + + const m = program.uniforms.uMouse.value as Float32Array; + m.set(mouseCurrentRef.current); - function update(t: number) { - if (enableMouseInteraction) { - const smoothing = 0.05; - currentMouse[0] += smoothing * (targetMouse[0] - currentMouse[0]); - currentMouse[1] += smoothing * (targetMouse[1] - currentMouse[1]); - program.uniforms.uMouse.value[0] = currentMouse[0]; - program.uniforms.uMouse.value[1] = currentMouse[1]; - } else { - program.uniforms.uMouse.value[0] = 0.5; - program.uniforms.uMouse.value[1] = 0.5; - } program.uniforms.iTime.value = t * 0.001; - renderer.render({ scene: mesh }); - animationFrameId.current = requestAnimationFrame(update); - } - animationFrameId.current = requestAnimationFrame(update); + renderer.render({ scene: meshRef.current! }); + }; + + animationFrameRef.current = requestAnimationFrame(animate); return () => { - if (animationFrameId.current) - cancelAnimationFrame(animationFrameId.current); + if (animationFrameRef.current) cancelAnimationFrame(animationFrameRef.current); window.removeEventListener("resize", resize); - - if (enableMouseInteraction) { - container.removeEventListener("mousemove", handleMouseMove); - container.removeEventListener("mouseleave", handleMouseLeave); - } + observer.disconnect(); if (container.contains(gl.canvas)) container.removeChild(gl.canvas); - gl.getExtension("WEBGL_lose_context")?.loseContext(); + rendererRef.current = null; + programRef.current = null; + meshRef.current = null; }; - }, [color, amplitude, distance, enableMouseInteraction]); + }, []); return ( -
+
); }; diff --git a/LandingPage/src/components/github.tsx b/LandingPage/src/components/github.tsx index a1a33ff..b6c9abb 100644 --- a/LandingPage/src/components/github.tsx +++ b/LandingPage/src/components/github.tsx @@ -1,17 +1,35 @@ -import styled from 'styled-components'; +import React from "react"; +import styled from "styled-components"; + +const Github: React.FC = () => { + const openLink = (): void => { + window.open( + "https://github.com/AOSSIE-Org/", + "_blank", + "noopener,noreferrer" + ); + }; -const Github = () => { return ( - ); -} +}; const StyledWrapper = styled.div` .btn-github { @@ -40,9 +58,10 @@ const StyledWrapper = styled.div` box-shadow: inset 0 1px 0 0 rgba(255, 255, 255, 0.08), inset 0 0 0 1px rgba(252, 232, 3, 0.08); - color:rgb(152, 3, 252); + color: rgb(152, 3, 252); transform: translate(0, -0.25rem); background-color: rgba(0, 0, 0, 0.5); - }`; + } +`; export default Github;