From 3dfe87f7d4d0768fe109c37ec2723d6d47302565 Mon Sep 17 00:00:00 2001 From: tomasfdev Date: Mon, 26 May 2025 14:30:38 -0300 Subject: [PATCH 1/8] Refactor app layout and introduce redesign components - Updated the main application layout to incorporate new UI components such as Hero, FilterType, and ListItem. - Replaced PackageCard with ListItem for better integration with the new design. - Added new components for filtering and selecting packages and tools. - Introduced GitHub repository handling in the redesigned UI. - Enhanced global styles with new font faces and design system colors. --- apps/react-three-org/src/app.tsx | 170 ++++-------------- .../components/redesign-ui/filter-type.tsx | 43 +++++ .../src/components/redesign-ui/filter.tsx | 33 ++++ .../components/redesign-ui/github-repo.tsx | 86 +++++++++ .../src/components/redesign-ui/hero.tsx | 56 ++++++ .../src/components/redesign-ui/index.ts | 7 + .../src/components/redesign-ui/link.tsx | 29 +++ .../src/components/redesign-ui/list-item.tsx | 37 ++++ .../src/components/redesign-ui/navbar.tsx | 40 +++++ .../redesign-ui/project-configurator.tsx | 91 ++++++++++ .../src/components/redesign-ui/select-box.tsx | 8 + apps/react-three-org/src/global.css | 36 +++- 12 files changed, 495 insertions(+), 141 deletions(-) create mode 100644 apps/react-three-org/src/components/redesign-ui/filter-type.tsx create mode 100644 apps/react-three-org/src/components/redesign-ui/filter.tsx create mode 100644 apps/react-three-org/src/components/redesign-ui/github-repo.tsx create mode 100644 apps/react-three-org/src/components/redesign-ui/hero.tsx create mode 100644 apps/react-three-org/src/components/redesign-ui/index.ts create mode 100644 apps/react-three-org/src/components/redesign-ui/link.tsx create mode 100644 apps/react-three-org/src/components/redesign-ui/list-item.tsx create mode 100644 apps/react-three-org/src/components/redesign-ui/navbar.tsx create mode 100644 apps/react-three-org/src/components/redesign-ui/project-configurator.tsx create mode 100644 apps/react-three-org/src/components/redesign-ui/select-box.tsx diff --git a/apps/react-three-org/src/app.tsx b/apps/react-three-org/src/app.tsx index d9390c4..c1a95f3 100644 --- a/apps/react-three-org/src/app.tsx +++ b/apps/react-three-org/src/app.tsx @@ -1,14 +1,9 @@ -import { useEffect, useMemo, useState } from 'react' -import { Loading } from './loading.js' -import { useQuery } from '@tanstack/react-query' -import { PackageCard } from '@/components/package-card' -import { ProjectConfigurator } from '@/components/project-configurator' -import { NavBar } from '@/components/nav-bar' -import { packages, tools, PackageIDs, ToolIDs } from '@/lib/packages' -import { BackgroundAnimation } from '@/components/background-animation' -import { CogIcon, PackageIcon } from 'lucide-react' +import { PackageIDs, packages, ToolIDs, tools } from '@/lib/packages' +import { useState } from 'react' +import { ProjectConfigurator, FilterType, GithubRepo } from './components/redesign-ui' import { Toaster } from 'sonner' -import { SelectionSection } from './components/selection-section.js' +import { Hero } from './components/redesign-ui/hero' +import { ListItem } from './components/redesign-ui/list-item' const searchParams = new URLSearchParams(location.search) const sessionAccessTokenKey = 'access_token' @@ -24,31 +19,23 @@ export function App() { } return ( -
- -
-
-

React Three

-

- Building 3D experiences with the React Three Ecosystem -

- -
- - {/* Visual separator using space instead of a border */} -
- - + +
+ { + setSelectedPackages(selected ? packages.map((pkg) => pkg.id) : []) + }} + onSelectAllTools={(selected) => { + setSelectedTools(selected ? tools.map((tool) => tool.id) : []) + }} /> -
+
{packages.map((pkg) => ( - ))} -
- - {/* Visual separator using space instead of a border */} -
- - - -
{tools.map((pkg) => ( - ))}
- - { - const integrations: any = {} - const selections = [...selectedPackages, ...selectedTools] - for (const integration of selections) { - integrations[integration] = true - } - - setState(btoa(JSON.stringify(integrations))) - }} - selections={[...selectedPackages, ...selectedTools]} - />
+ { + const integrations: any = {} + const selections = [...selectedPackages, ...selectedTools] + for (const integration of selections) { + integrations[integration] = true + } + + setState(btoa(JSON.stringify(integrations))) + }} + selections={[...selectedPackages, ...selectedTools]} + /> ) } - -function GithubRepo({ state }: { state: string }) { - const code = useMemo(() => searchParams.get('code'), []) - const { - isPending: isPendingAccessToken, - error: errorAccessToken, - data: accessTokenData, - } = useQuery({ - retry: false, - enabled: sessionAccessToken == null, - queryKey: ['oauth', code], - queryFn: async () => { - if (code == null) { - //promise never - return new Promise<{ token: string }>(() => {}) - } - const response = await fetch(new URL(`/oauth?code=${code}`, import.meta.env.VITE_SERVER_URL)) - if (!response.ok) { - throw new Error(response.statusText) - } - return response.json() as any as { token: string } - }, - }) - useEffect(() => { - if (accessTokenData == null) { - return - } - sessionStorage.setItem(sessionAccessTokenKey, accessTokenData.token) - }, [accessTokenData?.token]) - const accessToken = sessionAccessToken ?? accessTokenData?.token - const { - data: repoData, - isPending: isPendingRepo, - error: repoError, - } = useQuery({ - retry: false, - enabled: accessToken != null, - queryKey: ['repo', accessToken], - queryFn: async () => { - const response = await fetch(new URL('/repo', import.meta.env.VITE_SERVER_URL), { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ token: accessToken!, ...JSON.parse(atob(decodeURIComponent(state))) }), - }) - if (!response.ok) { - throw new Error(response.statusText) - } - return response.json() as any as { url: string } - }, - }) - useEffect(() => { - if (repoData?.url == null) { - return - } - setTimeout(() => (location.href = repoData.url), 1000) - }, [repoData?.url]) - if (code == null) { - location.href = `https://github.com/login/oauth/authorize?client_id=${ - import.meta.env.VITE_CLIENT_ID - }&redirect_uri=${import.meta.env.VITE_REDIRECT_URL}&state=${state}&scope=user%20repo%20workflow` - return null - } - if (sessionAccessToken == null && isPendingAccessToken) { - return - } - if (errorAccessToken != null) { - return errorAccessToken.message - } - if (isPendingRepo) { - return - } - if (repoError) { - return repoError.message - } - return -} diff --git a/apps/react-three-org/src/components/redesign-ui/filter-type.tsx b/apps/react-three-org/src/components/redesign-ui/filter-type.tsx new file mode 100644 index 0000000..1221e0a --- /dev/null +++ b/apps/react-three-org/src/components/redesign-ui/filter-type.tsx @@ -0,0 +1,43 @@ +import { type Package, PackageIDs, packages, ToolIDs, tools } from '@/lib/packages' +import { SelectBox } from './select-box' + +interface FilterTypeProps { + selectedPackages: PackageIDs[] + selectedTools: ToolIDs[] + onSelectAllPackages: (selected: boolean) => void + onSelectAllTools: (selected: boolean) => void +} + +export const FilterType = ({ + selectedPackages, + selectedTools, + onSelectAllPackages, + onSelectAllTools, +}: FilterTypeProps) => { + const allPackagesSelected = packages.every((pkg) => selectedPackages.includes(pkg.id)) + const allToolsSelected = tools.every((tool) => selectedTools.includes(tool.id)) + + return ( +
+
+
+

/ SELECT ALL

+ +
+ +
+ +
+ +
+
+
+
+ ) +} diff --git a/apps/react-three-org/src/components/redesign-ui/filter.tsx b/apps/react-three-org/src/components/redesign-ui/filter.tsx new file mode 100644 index 0000000..b6487e5 --- /dev/null +++ b/apps/react-three-org/src/components/redesign-ui/filter.tsx @@ -0,0 +1,33 @@ +import { packages, tools } from '@/lib/packages' +import { Package } from '@/lib/packages' +import { SelectBox } from './select-box' + +//TODO + +export const Filter = ({ + handleSelectAll, + selectedPackages, + visibleTypes, +}: { + handleSelectAll: () => void + selectedPackages: Package[] + visibleTypes: { packages: boolean; tools: boolean } +}) => { + const allVisible = [...(visibleTypes.packages ? packages : []), ...(visibleTypes.tools ? tools : [])] + const allSelected = allVisible.length > 0 && selectedPackages.length === allVisible.length + + return ( +
+
+

SELECT WHAT POWERS YOUR PROJECT.

+
+

A - Z

+
+ +

SELECT ALL

+
+
+
+
+ ) +} diff --git a/apps/react-three-org/src/components/redesign-ui/github-repo.tsx b/apps/react-three-org/src/components/redesign-ui/github-repo.tsx new file mode 100644 index 0000000..4530c7a --- /dev/null +++ b/apps/react-three-org/src/components/redesign-ui/github-repo.tsx @@ -0,0 +1,86 @@ +import { useEffect, useMemo } from 'react' +import { useQuery } from '@tanstack/react-query' +import { Loading } from '@/loading' + +const searchParams = new URLSearchParams(location.search) +const sessionAccessTokenKey = 'access_token' +const sessionAccessToken = sessionStorage.getItem(sessionAccessTokenKey) + +export function GithubRepo({ state }: { state: string }) { + const code = useMemo(() => searchParams.get('code'), []) + const { + isPending: isPendingAccessToken, + error: errorAccessToken, + data: accessTokenData, + } = useQuery({ + retry: false, + enabled: sessionAccessToken == null, + queryKey: ['oauth', code], + queryFn: async () => { + if (code == null) { + //promise never + return new Promise<{ token: string }>(() => {}) + } + const response = await fetch(new URL(`/oauth?code=${code}`, import.meta.env.VITE_SERVER_URL)) + if (!response.ok) { + throw new Error(response.statusText) + } + return response.json() as any as { token: string } + }, + }) + useEffect(() => { + if (accessTokenData == null) { + return + } + sessionStorage.setItem(sessionAccessTokenKey, accessTokenData.token) + }, [accessTokenData?.token]) + const accessToken = sessionAccessToken ?? accessTokenData?.token + const { + data: repoData, + isPending: isPendingRepo, + error: repoError, + } = useQuery({ + retry: false, + enabled: accessToken != null, + queryKey: ['repo', accessToken], + queryFn: async () => { + const response = await fetch(new URL('/repo', import.meta.env.VITE_SERVER_URL), { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ token: accessToken!, ...JSON.parse(atob(decodeURIComponent(state))) }), + }) + if (!response.ok) { + throw new Error(response.statusText) + } + return response.json() as any as { url: string } + }, + }) + useEffect(() => { + if (repoData?.url == null) { + return + } + setTimeout(() => (location.href = repoData.url), 1000) + }, [repoData?.url]) + if (code == null) { + location.href = `https://github.com/login/oauth/authorize?client_id=${ + import.meta.env.VITE_CLIENT_ID + }&redirect_uri=${import.meta.env.VITE_REDIRECT_URL}&state=${state}&scope=user%20repo%20workflow` + return null + } + if (sessionAccessToken == null && isPendingAccessToken) { + return + } + if (errorAccessToken != null) { + return errorAccessToken.message + } + if (isPendingRepo) { + return + } + if (repoError) { + return repoError.message + } + return + } + \ No newline at end of file diff --git a/apps/react-three-org/src/components/redesign-ui/hero.tsx b/apps/react-three-org/src/components/redesign-ui/hero.tsx new file mode 100644 index 0000000..9fea4d3 --- /dev/null +++ b/apps/react-three-org/src/components/redesign-ui/hero.tsx @@ -0,0 +1,56 @@ +import { useThree, useFrame } from '@react-three/fiber' +import { Canvas } from '@react-three/fiber' +import { NavBar } from './navbar' +import { useMemo, useEffect } from 'react' +import * as THREE from 'three' + +export const Hero = () => { + return ( +
+
+ +
+

react-three

+

BUILDING COOL 3D EXPERIENCES WITH THE REACT THREE ECOSYSTEM.

+
+
+
+ + + + + +
+
+ ) +} + +const CameraPlane = () => { + const { camera, size } = useThree() + const shaderMaterial = useMemo(() => createShaderMaterial(), []) + + const planeZ = 1 + const distanceFromCamera = camera.position.z - planeZ + const fovRadians = THREE.MathUtils.degToRad(camera instanceof THREE.PerspectiveCamera ? camera.fov : 75) + const height = 2 * Math.tan(fovRadians / 2) * distanceFromCamera + const width = height * (size.width / size.height) + + useEffect(() => { + if (shaderMaterial.uniforms?.uResolution) { + shaderMaterial.uniforms.uResolution.value.set(size.width, size.height, 1) + } + }, [size, shaderMaterial]) + + useFrame(({ clock }) => { + if (shaderMaterial.uniforms?.uTime) { + shaderMaterial.uniforms.uTime.value = clock.getElapsedTime() + } + }) + + return ( + + + + + ) +} diff --git a/apps/react-three-org/src/components/redesign-ui/index.ts b/apps/react-three-org/src/components/redesign-ui/index.ts new file mode 100644 index 0000000..6124b6c --- /dev/null +++ b/apps/react-three-org/src/components/redesign-ui/index.ts @@ -0,0 +1,7 @@ +export * from './filter' +export * from './filter-type' +export * from './link' +export * from './navbar' +export * from './project-configurator' +export * from './select-box' +export * from './github-repo' diff --git a/apps/react-three-org/src/components/redesign-ui/link.tsx b/apps/react-three-org/src/components/redesign-ui/link.tsx new file mode 100644 index 0000000..363c1c2 --- /dev/null +++ b/apps/react-three-org/src/components/redesign-ui/link.tsx @@ -0,0 +1,29 @@ +import { cn } from "@/lib/utils" + +export const Link = ({ + children, + href, + isExternal = false, + 'aria-label': ariaLabel, + className, +}: { + children: React.ReactNode + href: string + isExternal?: boolean + 'aria-label'?: string + className?: string +}) => { + const externalProps = isExternal + ? { + target: '_blank', + rel: 'noopener noreferrer', + 'aria-label': ariaLabel || undefined, + } + : {} + + return ( + + {children} + + ) +} diff --git a/apps/react-three-org/src/components/redesign-ui/list-item.tsx b/apps/react-three-org/src/components/redesign-ui/list-item.tsx new file mode 100644 index 0000000..1f348b2 --- /dev/null +++ b/apps/react-three-org/src/components/redesign-ui/list-item.tsx @@ -0,0 +1,37 @@ +import { Package } from '@/lib/packages' +import { cn } from '@/lib/utils' +import { SelectBox } from './select-box' +import { Link } from './link' + +interface PackageCardProps { + package: Package + isSelected: boolean + onToggle: () => void +} + +export const ListItem = ({ package: pkg, isSelected, onToggle }: PackageCardProps) => { + return ( + + ) +} diff --git a/apps/react-three-org/src/components/redesign-ui/navbar.tsx b/apps/react-three-org/src/components/redesign-ui/navbar.tsx new file mode 100644 index 0000000..9ac2e54 --- /dev/null +++ b/apps/react-three-org/src/components/redesign-ui/navbar.tsx @@ -0,0 +1,40 @@ + +import { Link } from "./link" + +export const NavBar = () => { + return ( + + ) +} diff --git a/apps/react-three-org/src/components/redesign-ui/project-configurator.tsx b/apps/react-three-org/src/components/redesign-ui/project-configurator.tsx new file mode 100644 index 0000000..d60359e --- /dev/null +++ b/apps/react-three-org/src/components/redesign-ui/project-configurator.tsx @@ -0,0 +1,91 @@ +import { Copy } from 'lucide-react' +import { generate } from '@react-three/create' +import JSZip from 'jszip' +import { toast } from 'sonner' + +interface ProjectConfiguratorProps { + selections: string[] + createGithubRepo: () => void +} + +export const ProjectConfigurator = ({ selections, createGithubRepo }: ProjectConfiguratorProps) => { + const command = `npm create @react-three ${selections.length > 0 ? '-- ' : ''}${selections + .map((id) => `--${id}`) + .join(' ')}` + + const copyToClipboard = async () => { + try { + await navigator.clipboard.writeText(command) + toast.success('Command copied to clipboard') + } catch (err) { + toast.error('Failed to copy command') + } + } + + const downloadProject = async () => { + const element = document.createElement('a') + const options: any = {} + for (const selection of selections) { + options[selection] = true + } + const files = generate(options) + console.log(files) + const zip = new JSZip() + // Write each file into the zip + for (const [path, file] of Object.entries(files)) { + const parts = path.split('/').filter(Boolean) + + let currentFolder = zip + // Create nested folders if needed + for (let i = 0; i < parts.length - 1; i++) { + currentFolder = currentFolder.folder(parts[i]!)! + } + // Add the file + let content: string | Blob + if (file.type === 'text') { + content = file.content + } else { + // For remote files, we'll need to fetch them first + const response = await fetch(file.url) + content = await response.blob() + } + currentFolder.file(parts[parts.length - 1]!, content) + } + const content = await zip.generateAsync({ type: 'blob' }) + element.href = URL.createObjectURL(content) + element.download = 'react-three-app.zip' + document.body.appendChild(element) + element.click() + document.body.removeChild(element) + } + + return ( +
+
+

{'>_ ' + command}

+ +
+
+

+ {selections.length} {selections.length === 1 ? 'package' : 'packages'} selected +

+
+ + +
+
+
+ ) +} diff --git a/apps/react-three-org/src/components/redesign-ui/select-box.tsx b/apps/react-three-org/src/components/redesign-ui/select-box.tsx new file mode 100644 index 0000000..40ac3e8 --- /dev/null +++ b/apps/react-three-org/src/components/redesign-ui/select-box.tsx @@ -0,0 +1,8 @@ +export const SelectBox = ({ selected }: { selected?: boolean }) => { + return ( + + + {selected && } + + ) +} diff --git a/apps/react-three-org/src/global.css b/apps/react-three-org/src/global.css index ff05ccd..c0f24bd 100644 --- a/apps/react-three-org/src/global.css +++ b/apps/react-three-org/src/global.css @@ -10,9 +10,26 @@ font-display: swap; } +@font-face { + font-family: 'Geist Mono'; + src: url('./assets/fonts/GeistMono-Regular.ttf') format('truetype'); + font-weight: normal; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: 'Geist Mono'; + src: url('./assets/fonts/GeistMono-Bold.ttf') format('truetype'); + font-weight: bold; + font-style: normal; + font-display: swap; +} + :root { font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; + --font-mono: 'Geist Mono', monospace; --radius: 0.625rem; --background: oklch(1 0 0); --foreground: oklch(0.145 0 0); @@ -45,6 +62,12 @@ --sidebar-accent-foreground: oklch(0.205 0 0); --sidebar-border: oklch(0.922 0 0); --sidebar-ring: oklch(0.708 0 0); + + /* Design system colors */ + --redesign-white: #FAFAFA; + --redesign-gray: #404040; + --redesign-dark: #1A1A1A; + --redesign-black: #050505; } @supports (font-variation-settings: normal) { @@ -94,9 +117,7 @@ body { } /* Add a subtle glow to text */ -h1 { - text-shadow: 0 0 10px color-mix(in oklab, white 50%, transparent); -} + button { cursor: pointer; @@ -138,6 +159,10 @@ button { --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-border: var(--sidebar-border); --color-sidebar-ring: var(--sidebar-ring); + --color-redesign-white: var(--redesign-white); + --color-redesign-gray: var(--redesign-gray); + --color-redesign-dark: var(--redesign-dark); + --color-redesign-black: var(--redesign-black); } .dark { @@ -186,4 +211,9 @@ button { @keyframes spinner-leaf-fade { 0%, 100% { opacity: 0; } 50% { opacity: 1; } +} + +.font-mono { + font-family: var(--font-mono); + letter-spacing: 0; } \ No newline at end of file From f3b7ec47654fb4c32c46ffcbd38868e17b2130f4 Mon Sep 17 00:00:00 2001 From: tomasfdev Date: Mon, 26 May 2025 14:37:50 -0300 Subject: [PATCH 2/8] Add shader material for enhanced visual effects in Hero component - Introduced a new shader material in shader-material.tsx to create dynamic visual effects. - Updated the Hero component to utilize the new shader material, enhancing the 3D experience. - Adjusted layout styles in the Hero component for better design consistency. --- .../src/components/redesign-ui/hero.tsx | 5 +- .../redesign-ui/shader-material.tsx | 149 ++++++++++++++++++ 2 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 apps/react-three-org/src/components/redesign-ui/shader-material.tsx diff --git a/apps/react-three-org/src/components/redesign-ui/hero.tsx b/apps/react-three-org/src/components/redesign-ui/hero.tsx index 9fea4d3..127d717 100644 --- a/apps/react-three-org/src/components/redesign-ui/hero.tsx +++ b/apps/react-three-org/src/components/redesign-ui/hero.tsx @@ -3,6 +3,7 @@ import { Canvas } from '@react-three/fiber' import { NavBar } from './navbar' import { useMemo, useEffect } from 'react' import * as THREE from 'three' +import { createShaderMaterial } from './shader-material' export const Hero = () => { return ( @@ -14,7 +15,7 @@ export const Hero = () => {

BUILDING COOL 3D EXPERIENCES WITH THE REACT THREE ECOSYSTEM.

-
+
@@ -54,3 +55,5 @@ const CameraPlane = () => { ) } + + diff --git a/apps/react-three-org/src/components/redesign-ui/shader-material.tsx b/apps/react-three-org/src/components/redesign-ui/shader-material.tsx new file mode 100644 index 0000000..f9ef2b9 --- /dev/null +++ b/apps/react-three-org/src/components/redesign-ui/shader-material.tsx @@ -0,0 +1,149 @@ +import * as THREE from 'three' + +export const createShaderMaterial = () => { + return new THREE.ShaderMaterial({ + uniforms: { + uTime: { value: 0 }, + uResolution: { value: new THREE.Vector3(1, 1, 1) }, + }, + vertexShader: ` + varying vec2 vUv; + void main() { + vUv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); + } + `, + fragmentShader: ` + uniform float uTime; + uniform vec3 uResolution; + varying vec2 vUv; + + mat4 RotationMatrixX(float angle){ + return mat4(1.0, 0.0, 0.0, 0.0, + 0.0, cos(angle), -sin(angle), 0.0, + 0.0, sin(angle), cos(angle), 0.0, + 0.0, 0.0, 0.0, 1.0); + } + + mat4 RotationMatrixY(float angle){ + return mat4(cos(angle), 0.0, sin(angle), 0.0, + 0.0, 1.0, 0.0, 0.0, + -sin(angle), 0.0, cos(angle), 0.0, + 0.0, 0.0, 0.0, 1.0); + } + + float sdCircle(vec2 st, vec2 pos, float radius){ + return length(st - pos) + radius; + } + + float sinTheta(float theta){ + return sin(theta * 3.14 / 180.0); + } + + float cosTheta(float theta){ + return cos(theta * 3.14 / 180.0); + } + + vec3 getRotation(int index){ + vec3 angle[7]; + angle[0] = vec3(1.0, 0.5, 0.0); + angle[1] = vec3(-1.0, 0.5, 0.0); + angle[2] = vec3(0.0, 2.0, 0.0); + return angle[index]; + } + + float getNeonCircle(float circle, float radius, float brightness){ + circle -= radius; + circle = abs(circle); + return circle = brightness / circle; + } + + float random(vec2 st) { + return fract(sin(dot(st.xy, + vec2(12.9898,79.321)))* + 51758.54); + } + + float noise(vec2 st) { + vec2 i = floor(st); + vec2 f = fract(st); + + float a = random(i); + float b = random(i + vec2(1.0, 0.0)); + float c = random(i + vec2(0.0, 1.0)); + float d = random(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 fbm(vec2 st) { + int octaves = 2; + float v = 0.0; + float a = 0.5; + vec2 shift = vec2(100.0); + mat2 rot = mat2(cos(0.5), sin(0.5), + -sin(0.5), cos(0.5)); + for (int i = 0; i < octaves; i++) { + v += a * noise(st); + st = rot * st * 2.0 + shift; + a *= 0.5; + } + return v; + } + + void mainImage(out vec4 fragColor, in vec2 fragCoord) { + vec2 st = (fragCoord.xy * 2.0 - uResolution.xy) / uResolution.y; + vec3 finalColor = vec3(0.0); + + vec2 q = vec2(0.0); + q.x = fbm(st + 0.00*uTime); + q.y = fbm(st + vec2(1.0)); + vec2 r = vec2(0.0); + r.x = fbm(st + 1.0*q + vec2(1.7,9.2)+ 0.15*uTime); + r.y = fbm(st + 1.0*q + vec2(8.3,2.8)+ 0.126*uTime); + float f = fbm(st+r); + + float signed = 1.0; + for (float i = 0.0; i < 3.0; i++){ + vec3 col = vec3(0.0); + vec4 st0 = vec4(st, 0.0, 1.0); + vec3 angle = getRotation(int(i)); + st0 *= RotationMatrixX(angle.x); + st0 *= RotationMatrixY(angle.y); + + float radius = 0.6; + float circle = sdCircle(st0.xy, vec2(0.0), radius); + circle = getNeonCircle(circle, 1.0, 0.01); + + col +=circle; + float timeCoef = uTime * 2.0 + i - signed; + float theta = 90.0 * timeCoef * signed; + float theta2 = 90.0 * (timeCoef + 1.2) * signed; + float cosAngle = st0.x * cosTheta(theta); + float sinAngle = st0.y * sinTheta(theta); + + col *= (cosAngle + sinAngle); + + finalColor = max(finalColor + col, finalColor); + signed *= -1.0; + } + + finalColor *= vec3(1.0, 1.0, 1.0); + fragColor = vec4(finalColor, 1.0); + } + + void main() { + vec2 fragCoord = vUv * uResolution.xy; + vec4 fragColor; + mainImage(fragColor, fragCoord); + gl_FragColor = fragColor; + } + `, + side: THREE.DoubleSide, + transparent: true + }); + }; \ No newline at end of file From 9ef80bf1abfec387b257a4100f5c3f96de379f64 Mon Sep 17 00:00:00 2001 From: tomasfdev Date: Mon, 26 May 2025 14:39:03 -0300 Subject: [PATCH 3/8] Remove unused session access token logic from app.tsx --- apps/react-three-org/src/app.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/react-three-org/src/app.tsx b/apps/react-three-org/src/app.tsx index c1a95f3..1649935 100644 --- a/apps/react-three-org/src/app.tsx +++ b/apps/react-three-org/src/app.tsx @@ -6,8 +6,6 @@ import { Hero } from './components/redesign-ui/hero' import { ListItem } from './components/redesign-ui/list-item' const searchParams = new URLSearchParams(location.search) -const sessionAccessTokenKey = 'access_token' -const sessionAccessToken = sessionStorage.getItem(sessionAccessTokenKey) export function App() { const [state, setState] = useState(() => searchParams.get('state')) From 462042d2cf9381ed82efeb402c515dc87a5fdbd9 Mon Sep 17 00:00:00 2001 From: tomasfdev Date: Mon, 26 May 2025 15:06:43 -0300 Subject: [PATCH 4/8] improve hero a11y --- .../src/components/redesign-ui/hero.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/apps/react-three-org/src/components/redesign-ui/hero.tsx b/apps/react-three-org/src/components/redesign-ui/hero.tsx index 127d717..8860a09 100644 --- a/apps/react-three-org/src/components/redesign-ui/hero.tsx +++ b/apps/react-three-org/src/components/redesign-ui/hero.tsx @@ -7,22 +7,29 @@ import { createShaderMaterial } from './shader-material' export const Hero = () => { return ( -
+
-

react-three

-

BUILDING COOL 3D EXPERIENCES WITH THE REACT THREE ECOSYSTEM.

+

react-three

+

BUILDING COOL 3D EXPERIENCES WITH THE REACT THREE ECOSYSTEM.

-
+
+
+ Interactive 3D visualization demonstrating React Three capabilities +
-
+
) } From f6b7664e42ad0299d055f5ade2c63b6c9c150d20 Mon Sep 17 00:00:00 2001 From: tomasfdev Date: Mon, 26 May 2025 15:08:29 -0300 Subject: [PATCH 5/8] improve filter a11y --- .../components/redesign-ui/filter-type.tsx | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/apps/react-three-org/src/components/redesign-ui/filter-type.tsx b/apps/react-three-org/src/components/redesign-ui/filter-type.tsx index 1221e0a..5bbfa9a 100644 --- a/apps/react-three-org/src/components/redesign-ui/filter-type.tsx +++ b/apps/react-three-org/src/components/redesign-ui/filter-type.tsx @@ -18,20 +18,33 @@ export const FilterType = ({ const allToolsSelected = tools.every((tool) => selectedTools.includes(tool.id)) return ( -
+
-

/ SELECT ALL

+

Filter Options

+

/ SELECT ALL

-
-
-
- From 178e8e850b55384dd5506c6deda3354790170fce Mon Sep 17 00:00:00 2001 From: tomasfdev Date: Mon, 26 May 2025 15:11:36 -0300 Subject: [PATCH 6/8] improve list item and navbar a11y --- .../src/components/redesign-ui/list-item.tsx | 18 ++++++++-- .../src/components/redesign-ui/navbar.tsx | 35 ++++++++++++++----- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/apps/react-three-org/src/components/redesign-ui/list-item.tsx b/apps/react-three-org/src/components/redesign-ui/list-item.tsx index 1f348b2..5f59b54 100644 --- a/apps/react-three-org/src/components/redesign-ui/list-item.tsx +++ b/apps/react-three-org/src/components/redesign-ui/list-item.tsx @@ -14,20 +14,32 @@ export const ListItem = ({ package: pkg, isSelected, onToggle }: PackageCardProp +
+ )} {packages.map((pkg) => ( ))} + + {isMobile && ( +
+ +
+ )} {tools.map((pkg) => (

Filter Options

-

/ SELECT ALL

+

+ / SELECT ALL +

-
-
-

+

{selections.length} {selections.length === 1 ? 'package' : 'packages'} selected