From 85a04615727a8d44598aae8bad00bc588d7112f4 Mon Sep 17 00:00:00 2001 From: ad044 Date: Wed, 9 Sep 2020 23:35:13 +0400 Subject: [PATCH] starfield intro anim, still need to make a smooth transition. --- src/components/Starfield.tsx | 329 +++++++++++++++++++---------------- 1 file changed, 183 insertions(+), 146 deletions(-) diff --git a/src/components/Starfield.tsx b/src/components/Starfield.tsx index c7a654b..cd47603 100644 --- a/src/components/Starfield.tsx +++ b/src/components/Starfield.tsx @@ -10,9 +10,30 @@ type StarRefsAndIncrementors = [ type StarfieldProps = { starfieldPosY: Interpolation; + introStarfieldVisible: boolean; +}; + +type StarfieldObjectData = { + starPoses: number[][]; + ref: React.MutableRefObject[]>; + rotation: number[]; + positionSpecifier: number[]; + uniform?: + | { color1: { value: THREE.Color }; color2: { value: THREE.Color } } + | undefined; +}; + +type IntroStarfieldObjectData = { + starPoses: number[][]; + ref: React.MutableRefObject[]>; + uniform?: + | { color1: { value: THREE.Color }; color2: { value: THREE.Color } } + | undefined; }; const Starfield = memo((props: StarfieldProps) => { + const introStarfieldGroupRef = useRef(); + const uniformConstructor = (col: string) => { return { color1: { @@ -24,12 +45,6 @@ const Starfield = memo((props: StarfieldProps) => { }; }; - const [blueUniforms, cyanUniforms, whiteUniforms] = [ - "blue", - "cyan", - "gray", - ].map((color: string) => useMemo(() => uniformConstructor(color), [color])); - const vertexShader = ` varying vec2 vUv; @@ -58,13 +73,19 @@ const Starfield = memo((props: StarfieldProps) => { const lcgInstance = LCG(1664525, 1013904223, 2 ** 32, 2); + const [blueUniforms, cyanUniforms, whiteUniforms] = [ + "blue", + "cyan", + "gray", + ].map((color: string) => useMemo(() => uniformConstructor(color), [color])); + const [ posesBlueFromRight, posesBlueFromLeft, posesCyanFromRight, posesCyanFromLeft, posesWhiteFromLeft, - ] = [40, 40, 10, 5, 5].map((x) => + ] = [30, 30, 20, 20, 5].map((x) => Array.from({ length: x }, () => [ lcgInstance() / 1000000000, lcgInstance() / 1000000000, @@ -90,6 +111,28 @@ const Starfield = memo((props: StarfieldProps) => { ) ); + const [introPosesBlue, introPosesCyan, introPosesWhite] = [ + 80, + 80, + 60, + ].map((x) => + Array.from({ length: x }, () => [ + lcgInstance() / 1000000050, + lcgInstance() / 100000099, + lcgInstance() / 1000000050, + ]) + ); + + const [introBlueRef, introCyanRef, introWhiteRef] = [ + introPosesBlue, + introPosesCyan, + introPosesWhite, + ].map((poses) => + useRef[]>( + poses.map(() => createRef()) + ) + ); + // these arrays contain refs to the 3d planes and the increment values that they should move with across // the screen const fromRightStarRefsAndIncrementors: StarRefsAndIncrementors = [ @@ -104,154 +147,148 @@ const Starfield = memo((props: StarfieldProps) => { ]; useFrame(() => { - // planes (stars) coming from right move to positive X and negative Z direction - fromRightStarRefsAndIncrementors.forEach((el) => { - el[0].current.forEach((posRef: RefObject) => { - if (posRef.current!.position.x < -1) { - posRef.current!.position.x += el[1]; - posRef.current!.position.z -= el[1]; - } else { - posRef.current!.position.x -= 0.03; - posRef.current!.position.z += 0.03; - } + if (props.introStarfieldVisible) { + introStarfieldGroupRef.current!.position.y += 0.2; + } else { + // planes (stars) coming from right move to positive X and negative Z direction + fromRightStarRefsAndIncrementors.forEach((el) => { + el[0].current.forEach((posRef: RefObject) => { + if (posRef.current!.position.x < -1) { + posRef.current!.position.x += el[1]; + posRef.current!.position.z -= el[1]; + } else { + posRef.current!.position.x -= 0.03; + posRef.current!.position.z += 0.03; + } + }); }); - }); - // the ones that are coming from left move to negative X and Z - fromLeftStarRefsAndIncrementors.forEach((el) => { - el[0].current.forEach((posRef: RefObject) => { - if (posRef.current!.position.x > 3) { - posRef.current!.position.x -= el[1]; - posRef.current!.position.z -= el[1]; - } else { - posRef.current!.position.x += 0.03; - posRef.current!.position.z += 0.03; - } + // the ones that are coming from left move to negative X and Z + fromLeftStarRefsAndIncrementors.forEach((el) => { + el[0].current.forEach((posRef: RefObject) => { + if (posRef.current!.position.x > 3) { + posRef.current!.position.x -= el[1]; + posRef.current!.position.z -= el[1]; + } else { + posRef.current!.position.x += 0.03; + posRef.current!.position.z += 0.03; + } + }); }); - }); + } }); - return ( + const mainStarfieldObjects = [ + { + starPoses: posesBlueFromRight, + ref: blueFromRightRef, + rotation: [1.7, 0, 0.9], + positionSpecifier: [0, 0, 0], + uniform: blueUniforms, + }, + { + starPoses: posesBlueFromLeft, + ref: blueFromLeftRef, + rotation: [1.7, 0, -0.9], + positionSpecifier: [-2.4, -0.5, 2], + uniform: blueUniforms, + }, + { + starPoses: posesCyanFromRight, + ref: cyanFromRightRef, + rotation: [1.7, 0, 0.9], + positionSpecifier: [-1.3, 0, 1.5], + uniform: cyanUniforms, + }, + { + starPoses: posesCyanFromLeft, + ref: cyanFromLeftRef, + rotation: [1.7, 0, -0.9], + positionSpecifier: [-1.3, 0, 2.5], + uniform: cyanUniforms, + }, + { + starPoses: posesWhiteFromLeft, + ref: whiteFromLeftRef, + rotation: [1.7, 0, -0.9], + positionSpecifier: [-1.3, 0.5, 1.5], + uniform: whiteUniforms, + }, + ]; + + const introStarfieldObjects = [ + { starPoses: introPosesBlue, ref: introBlueRef, uniform: blueUniforms }, + { starPoses: introPosesCyan, ref: introCyanRef, uniform: cyanUniforms }, + { starPoses: introPosesWhite, ref: introWhiteRef, uniform: whiteUniforms }, + ]; + + return props.introStarfieldVisible ? ( + {introStarfieldObjects.map((obj: IntroStarfieldObjectData) => + obj.starPoses.map((pos: number[], idx: number) => { + return ( + + + + + ); + }) + )} + + ) : ( + - {posesBlueFromRight.map((pos: number[], idx: number) => { - return ( - - - - - ); - })} - {posesBlueFromLeft.map((pos: number[], idx: number) => { - return ( - - - - - ); - })} - {posesCyanFromRight.map((pos: number[], idx: number) => { - return ( - - - - - ); - })} - {posesCyanFromLeft.map((pos: number[], idx: number) => { - return ( - - - - - ); - })} - {posesWhiteFromLeft.map((pos: number[], idx: number) => { - return ( - - - - - ); - })} + {mainStarfieldObjects.map((obj: StarfieldObjectData) => + obj.starPoses.map((pos: number[], idx: number) => { + return ( + + + + + ); + }) + )} ); });