mirror of https://github.com/almqv/wych.dev
parent
ae1a514854
commit
ac4b24e4a2
@ -1,82 +1,82 @@ |
||||
"use client"; |
||||
|
||||
import * as THREE from "three"; |
||||
import { CurveProps } from "../renderer"; |
||||
|
||||
const maxParticles = 20000; |
||||
|
||||
const startScatter = 0.1; |
||||
|
||||
const init = () => { |
||||
var arrayCurve = []; |
||||
|
||||
var x = 0.01, |
||||
y = 0.01, |
||||
z = 0.01; |
||||
var a = 0.9; |
||||
var b = 3.4; |
||||
var f = 9.9; |
||||
var g = 1; |
||||
var t = 0.001; |
||||
for (var i = 0; i < maxParticles; i++) { |
||||
x = x - t * a * x + t * y * y - t * z * z + t * a * f; |
||||
y = y - t * y + t * x * y - t * b * x * z + t * g; |
||||
z = z - t * z + t * b * x * y + t * x * z; |
||||
arrayCurve.push( |
||||
new THREE.Vector3(x, y, z).multiplyScalar( |
||||
1 - startScatter / 2 + Math.random() * startScatter, |
||||
), |
||||
); |
||||
} |
||||
return arrayCurve; |
||||
}; |
||||
|
||||
const update = (pc: THREE.Points<THREE.BufferGeometry>, group: THREE.Group) => { |
||||
//Varying the points on each frame
|
||||
// step += 0.01;
|
||||
var geometry = pc.geometry; |
||||
var a = 0.9; //+ Math.random() * .2;
|
||||
var b = 3.4; //+ Math.random() * .1;
|
||||
var f = 9.9; //+ Math.random() * .2;
|
||||
var g = 1; //+ Math.random() * .1;
|
||||
var t = 0.001; |
||||
|
||||
var positions = geometry.attributes.position; |
||||
const numPoints = positions.array.length / 3; |
||||
|
||||
for (let i = 0; i < numPoints; i++) { |
||||
let x = positions.getX(i), |
||||
y = positions.getY(i), |
||||
z = positions.getZ(i); |
||||
positions.setXYZ( |
||||
i, |
||||
x - t * a * x + t * y * y - t * z * z + t * a * f, |
||||
y - t * y + t * x * y - t * b * x * z + t * g, |
||||
z - t * z + t * b * x * y + t * x * z, |
||||
); |
||||
} |
||||
positions.needsUpdate = true; |
||||
|
||||
// TODO: remove
|
||||
// group.rotation.x += 0.0005;
|
||||
// group.rotation.y += 0.001;
|
||||
// group.rotation.z -= 0.0005;
|
||||
}; |
||||
|
||||
// INFO: Curve definition
|
||||
const ThingCurve = { |
||||
func: { init: init, update: update }, |
||||
cam: { |
||||
pos: new THREE.Vector3(0, 0, 18).multiplyScalar(1.7), |
||||
rotation: new THREE.Vector3(0, 0, 180), |
||||
}, |
||||
particles: { |
||||
max: maxParticles, |
||||
size: 0.07, |
||||
color: "#888", |
||||
darkcolor: "#444", |
||||
opacity: 0.4, |
||||
}, // 87a
|
||||
}; |
||||
|
||||
export default ThingCurve; |
||||
"use client"; |
||||
|
||||
import * as THREE from "three"; |
||||
import { CurveProps } from "../renderer"; |
||||
|
||||
const maxParticles = 20000; |
||||
|
||||
const startScatter = 0.1; |
||||
|
||||
const init = () => { |
||||
var arrayCurve = []; |
||||
|
||||
var x = 0.01, |
||||
y = 0.01, |
||||
z = 0.01; |
||||
var a = 0.9; |
||||
var b = 3.4; |
||||
var f = 9.9; |
||||
var g = 1; |
||||
var t = 0.001; |
||||
for (var i = 0; i < maxParticles; i++) { |
||||
x = x - t * a * x + t * y * y - t * z * z + t * a * f; |
||||
y = y - t * y + t * x * y - t * b * x * z + t * g; |
||||
z = z - t * z + t * b * x * y + t * x * z; |
||||
arrayCurve.push( |
||||
new THREE.Vector3(x, y, z).multiplyScalar( |
||||
1 - startScatter / 2 + Math.random() * startScatter, |
||||
), |
||||
); |
||||
} |
||||
return arrayCurve; |
||||
}; |
||||
|
||||
const update = (pc: THREE.Points<THREE.BufferGeometry>, group: THREE.Group) => { |
||||
//Varying the points on each frame
|
||||
// step += 0.01;
|
||||
var geometry = pc.geometry; |
||||
var a = 0.9; //+ Math.random() * .2;
|
||||
var b = 3.4; //+ Math.random() * .1;
|
||||
var f = 9.9; //+ Math.random() * .2;
|
||||
var g = 1; //+ Math.random() * .1;
|
||||
var t = 0.001; |
||||
|
||||
var positions = geometry.attributes.position; |
||||
const numPoints = positions.array.length / 3; |
||||
|
||||
for (let i = 0; i < numPoints; i++) { |
||||
let x = positions.getX(i), |
||||
y = positions.getY(i), |
||||
z = positions.getZ(i); |
||||
positions.setXYZ( |
||||
i, |
||||
x - t * a * x + t * y * y - t * z * z + t * a * f, |
||||
y - t * y + t * x * y - t * b * x * z + t * g, |
||||
z - t * z + t * b * x * y + t * x * z, |
||||
); |
||||
} |
||||
positions.needsUpdate = true; |
||||
|
||||
// TODO: remove
|
||||
// group.rotation.x += 0.0005;
|
||||
// group.rotation.y += 0.001;
|
||||
// group.rotation.z -= 0.0005;
|
||||
}; |
||||
|
||||
// INFO: Curve definition
|
||||
const ThingCurve = { |
||||
func: { init: init, update: update }, |
||||
cam: { |
||||
pos: new THREE.Vector3(0, 0, 18).multiplyScalar(1.7), |
||||
rotation: new THREE.Vector3(0, 0, 180), |
||||
}, |
||||
particles: { |
||||
max: maxParticles, |
||||
size: 0.07, |
||||
color: "#888", |
||||
darkcolor: "#444", |
||||
opacity: 0.4, |
||||
}, // 87a
|
||||
}; |
||||
|
||||
export default ThingCurve; |
||||
|
@ -1,34 +1,34 @@ |
||||
"use client"; |
||||
|
||||
import React, { ReactNode, HTMLProps } from "react"; |
||||
import Renderer, { CurveProps } from "@/components/3d/renderer"; |
||||
import { cn } from "@/lib/utils"; |
||||
|
||||
const RenderedSection: React.FC< |
||||
HTMLProps<HTMLElement> & { |
||||
children?: ReactNode; |
||||
evenly?: boolean; |
||||
curve: CurveProps; |
||||
curveClassname?: string; |
||||
} |
||||
> = ({ |
||||
children, |
||||
className, |
||||
curveClassname, |
||||
evenly = false, |
||||
curve, |
||||
...props |
||||
}) => { |
||||
return ( |
||||
<div className="flex w-full h-full flex-col items-center align-middle relative"> |
||||
<div className={cn("absolute", curveClassname)}> |
||||
<Renderer {...curve} /> |
||||
</div> |
||||
<section className={cn("relative", className)} {...props}> |
||||
{children} |
||||
</section> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default RenderedSection; |
||||
"use client"; |
||||
|
||||
import React, { ReactNode, HTMLProps } from "react"; |
||||
import Renderer, { CurveProps } from "@/components/3d/renderer"; |
||||
import { cn } from "@/lib/utils"; |
||||
|
||||
const RenderedSection: React.FC< |
||||
HTMLProps<HTMLElement> & { |
||||
children?: ReactNode; |
||||
evenly?: boolean; |
||||
curve: CurveProps; |
||||
curveClassname?: string; |
||||
} |
||||
> = ({ |
||||
children, |
||||
className, |
||||
curveClassname, |
||||
evenly = false, |
||||
curve, |
||||
...props |
||||
}) => { |
||||
return ( |
||||
<div className="flex w-full h-full flex-col items-center align-middle relative"> |
||||
<div className={cn("absolute", curveClassname)}> |
||||
<Renderer {...curve} /> |
||||
</div> |
||||
<section className={cn("relative", className)} {...props}> |
||||
{children} |
||||
</section> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default RenderedSection; |
||||
|
@ -1,114 +1,114 @@ |
||||
"use client"; |
||||
|
||||
import * as THREE from "three"; |
||||
import React, { ComponentPropsWithRef, useEffect, useRef } from "react"; |
||||
import { Canvas, useFrame, useThree } from "@react-three/fiber"; |
||||
import { useTheme } from "next-themes"; |
||||
|
||||
export type FuncProps = { |
||||
init: () => THREE.Vector3[]; |
||||
update: (pc: THREE.Points<THREE.BufferGeometry>, group: THREE.Group) => void; |
||||
}; |
||||
|
||||
export type ParticleProps = { |
||||
max?: number; |
||||
size?: number; |
||||
color?: string; |
||||
darkcolor?: string; |
||||
opacity?: number; |
||||
}; |
||||
|
||||
export type CameraProps = { |
||||
pos?: THREE.Vector3; |
||||
lookAt?: THREE.Vector3; |
||||
rotation?: THREE.Vector3; |
||||
}; |
||||
|
||||
export type CurveProps = { |
||||
func: FuncProps; |
||||
cam?: CameraProps; |
||||
particles?: ParticleProps; |
||||
}; |
||||
|
||||
export const FuncRenderer = ({ |
||||
func, |
||||
cam = { |
||||
pos: new THREE.Vector3(0, 0, 0), |
||||
lookAt: new THREE.Vector3(0, 0, 0), |
||||
rotation: new THREE.Vector3(0, 0, 0), |
||||
}, |
||||
particles = { |
||||
max: 10000, |
||||
size: 1, |
||||
color: "#000", |
||||
darkcolor: "#fff", |
||||
opacity: 1, |
||||
}, |
||||
}: CurveProps) => { |
||||
const groupRef = useRef<THREE.Group>(null); |
||||
const { gl, camera } = useThree(); |
||||
const { theme } = useTheme(); |
||||
|
||||
const isDarkMode = theme === "dark"; |
||||
|
||||
useEffect(() => { |
||||
if (cam.pos) camera.position.copy(cam.pos); |
||||
if (cam.lookAt) camera.lookAt(cam.lookAt); |
||||
if (cam.rotation) { |
||||
camera.rotateX(cam.rotation.x); |
||||
camera.rotateY(cam.rotation.y); |
||||
camera.rotateZ(cam.rotation.z); |
||||
} |
||||
|
||||
// Initialize and set up the points on mount
|
||||
if (groupRef.current) { |
||||
const arrayCurve = func.init(); |
||||
const romCurve = new THREE.CatmullRomCurve3(arrayCurve); |
||||
const points = romCurve.getPoints(particles.max); |
||||
const geometry = new THREE.BufferGeometry().setFromPoints(points); |
||||
|
||||
const pcMat = new THREE.PointsMaterial({ |
||||
size: particles.size, |
||||
color: isDarkMode ? particles.darkcolor : particles.color, |
||||
opacity: particles.opacity, |
||||
transparent: true, |
||||
}); |
||||
// pcMat.blending = THREE.AdditiveBlending;
|
||||
|
||||
const pc = new THREE.Points(geometry, pcMat); |
||||
groupRef.current.add(pc); |
||||
} |
||||
|
||||
return () => { |
||||
// Clean up any resources if needed
|
||||
}; |
||||
}, [cam, func, particles, camera, isDarkMode]); |
||||
|
||||
useFrame(() => { |
||||
gl.setPixelRatio(window.devicePixelRatio); |
||||
if (groupRef.current && groupRef.current.children.length > 0) { |
||||
const pc = groupRef.current.children[0] as THREE.Points; |
||||
if (pc.geometry) { |
||||
func.update(pc, groupRef.current); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
return <group ref={groupRef} />; |
||||
}; |
||||
|
||||
const Renderer: React.FC< |
||||
ComponentPropsWithRef<typeof FuncRenderer> & { |
||||
cam?: CameraProps; |
||||
} |
||||
> = ({ cam = { pos: new THREE.Vector3(0, 0, 0) }, ...props }) => { |
||||
return ( |
||||
<Canvas gl={{ alpha: true }} className="transform"> |
||||
<pointLight position={[0, 0, 0]} color="#fff" /> |
||||
<perspectiveCamera position={cam.pos} /> |
||||
<FuncRenderer cam={cam} {...props} /> |
||||
</Canvas> |
||||
); |
||||
}; |
||||
|
||||
export default Renderer; |
||||
"use client"; |
||||
|
||||
import * as THREE from "three"; |
||||
import React, { ComponentPropsWithRef, useEffect, useRef } from "react"; |
||||
import { Canvas, useFrame, useThree } from "@react-three/fiber"; |
||||
import { useTheme } from "next-themes"; |
||||
|
||||
export type FuncProps = { |
||||
init: () => THREE.Vector3[]; |
||||
update: (pc: THREE.Points<THREE.BufferGeometry>, group: THREE.Group) => void; |
||||
}; |
||||
|
||||
export type ParticleProps = { |
||||
max?: number; |
||||
size?: number; |
||||
color?: string; |
||||
darkcolor?: string; |
||||
opacity?: number; |
||||
}; |
||||
|
||||
export type CameraProps = { |
||||
pos?: THREE.Vector3; |
||||
lookAt?: THREE.Vector3; |
||||
rotation?: THREE.Vector3; |
||||
}; |
||||
|
||||
export type CurveProps = { |
||||
func: FuncProps; |
||||
cam?: CameraProps; |
||||
particles?: ParticleProps; |
||||
}; |
||||
|
||||
export const FuncRenderer = ({ |
||||
func, |
||||
cam = { |
||||
pos: new THREE.Vector3(0, 0, 0), |
||||
lookAt: new THREE.Vector3(0, 0, 0), |
||||
rotation: new THREE.Vector3(0, 0, 0), |
||||
}, |
||||
particles = { |
||||
max: 10000, |
||||
size: 1, |
||||
color: "#000", |
||||
darkcolor: "#fff", |
||||
opacity: 1, |
||||
}, |
||||
}: CurveProps) => { |
||||
const groupRef = useRef<THREE.Group>(null); |
||||
const { gl, camera } = useThree(); |
||||
const { theme } = useTheme(); |
||||
|
||||
const isDarkMode = theme === "dark"; |
||||
|
||||
useEffect(() => { |
||||
if (cam.pos) camera.position.copy(cam.pos); |
||||
if (cam.lookAt) camera.lookAt(cam.lookAt); |
||||
if (cam.rotation) { |
||||
camera.rotateX(cam.rotation.x); |
||||
camera.rotateY(cam.rotation.y); |
||||
camera.rotateZ(cam.rotation.z); |
||||
} |
||||
|
||||
// Initialize and set up the points on mount
|
||||
if (groupRef.current) { |
||||
const arrayCurve = func.init(); |
||||
const romCurve = new THREE.CatmullRomCurve3(arrayCurve); |
||||
const points = romCurve.getPoints(particles.max); |
||||
const geometry = new THREE.BufferGeometry().setFromPoints(points); |
||||
|
||||
const pcMat = new THREE.PointsMaterial({ |
||||
size: particles.size, |
||||
color: isDarkMode ? particles.darkcolor : particles.color, |
||||
opacity: particles.opacity, |
||||
transparent: true, |
||||
}); |
||||
// pcMat.blending = THREE.AdditiveBlending;
|
||||
|
||||
const pc = new THREE.Points(geometry, pcMat); |
||||
groupRef.current.add(pc); |
||||
} |
||||
|
||||
return () => { |
||||
// Clean up any resources if needed
|
||||
}; |
||||
}, [cam, func, particles, camera, isDarkMode]); |
||||
|
||||
useFrame(() => { |
||||
gl.setPixelRatio(window.devicePixelRatio); |
||||
if (groupRef.current && groupRef.current.children.length > 0) { |
||||
const pc = groupRef.current.children[0] as THREE.Points; |
||||
if (pc.geometry) { |
||||
func.update(pc, groupRef.current); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
return <group ref={groupRef} />; |
||||
}; |
||||
|
||||
const Renderer: React.FC< |
||||
ComponentPropsWithRef<typeof FuncRenderer> & { |
||||
cam?: CameraProps; |
||||
} |
||||
> = ({ cam = { pos: new THREE.Vector3(0, 0, 0) }, ...props }) => { |
||||
return ( |
||||
<Canvas gl={{ alpha: true }} className="transform"> |
||||
<pointLight position={[0, 0, 0]} color="#fff" /> |
||||
<perspectiveCamera position={cam.pos} /> |
||||
<FuncRenderer cam={cam} {...props} /> |
||||
</Canvas> |
||||
); |
||||
}; |
||||
|
||||
export default Renderer; |
||||
|
Loading…
Reference in new issue