From 59645f22dca5c78e4dd2c6a04cae6dd48d5c96ba Mon Sep 17 00:00:00 2001 From: ad044 Date: Wed, 16 Sep 2020 00:08:23 +0400 Subject: [PATCH] middle ring up motion done, changed intro font --- src/App.tsx | 13 ++- src/components/InputHandler.tsx | 74 ++++++++++++- src/components/MiddleRing/MiddleRing.tsx | 109 ++++++++++++++----- src/components/MiddleRing/MiddleRingAtom.tsx | 26 +++++ 4 files changed, 186 insertions(+), 36 deletions(-) create mode 100644 src/components/MiddleRing/MiddleRingAtom.tsx diff --git a/src/App.tsx b/src/App.tsx index 43ab895..c832b17 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,6 +4,7 @@ import "./static/css/hub.css"; import "./static/css/main.css"; import { Canvas } from "react-three-fiber"; import { RecoilRoot } from "recoil"; +import Intro from "./components/Intro"; const App = () => { const [moveToGame, setMoveToGame] = useState(false); @@ -18,13 +19,13 @@ const App = () => { return (
+ {/**/} {/* {moveToGame ? : } */} - {/* */} - - - - - + + + + +
); }; diff --git a/src/components/InputHandler.tsx b/src/components/InputHandler.tsx index b9dc4e4..dcb242e 100644 --- a/src/components/InputHandler.tsx +++ b/src/components/InputHandler.tsx @@ -7,7 +7,7 @@ import { LainStanding, } from "./Lain/Lain"; import { useRecoilState, useSetRecoilState } from "recoil"; -import { hudActiveAtom, currentHUDAtom } from "./HUD/HUDElementAtom"; +import { currentHUDAtom, hudActiveAtom } from "./HUD/HUDElementAtom"; import { currentSpriteAtom } from "./LevelSprite/CurrentSpriteAtom"; import lain_animations from "../resources/lain_animations.json"; import level_sprite_huds from "../resources/level_sprite_huds.json"; @@ -22,6 +22,13 @@ import { starfieldPosYAtom } from "./Starfield/StarfieldAtom"; import { SpriteHuds } from "./HUD/HUDElement"; import { orthoCamPosYAtom } from "./OrthoCamera/OrthoCameraAtom"; import { grayPlanesPosYAtom } from "./GrayPlanes/GrayPlanesAtom"; +import { + middleRingNoiseAtom, + middleRingPosYAtom, + middleRingRotatingAtom, + middleRingRotXAtom, + middleRingWobbleStrengthAtom, +} from "./MiddleRing/MiddleRingAtom"; type KeyCodeAssociations = { [keyCode: number]: string; @@ -66,6 +73,14 @@ const InputHandler = () => { const setStarfieldPosY = useSetRecoilState(starfieldPosYAtom); + const setMiddleRingWobbleStrength = useSetRecoilState( + middleRingWobbleStrengthAtom + ); + const setMiddleRingRotating = useSetRecoilState(middleRingRotatingAtom); + const setMiddleRingNoise = useSetRecoilState(middleRingNoiseAtom); + const setMiddleRingPosY = useSetRecoilState(middleRingPosYAtom); + const setMiddleRingRotX = useSetRecoilState(middleRingRotXAtom); + const moveCamera = useCallback( (val: number) => { setCamPosY((prev: number) => prev + val); @@ -73,6 +88,14 @@ const InputHandler = () => { setStarfieldPosY((prev: number) => prev - val); setOrthoCamPosY((prev: number) => prev - val); setGrayPlanePosY((prev: number) => prev - val); + + setTimeout(() => { + setMiddleRingPosY((prev: number) => prev - (val - 0.2)); + }, 1300); + + setTimeout(() => { + setMiddleRingPosY((prev: number) => prev - 0.2); + }, 1800); }, [ setCamPosY, @@ -80,6 +103,7 @@ const InputHandler = () => { setStarfieldPosY, setOrthoCamPosY, setGrayPlanePosY, + setMiddleRingPosY, ] ); @@ -119,9 +143,46 @@ const InputHandler = () => { break; case "up": setLainMoveState(); + setTimeout(() => { moveCamera(-1.87); }, 1300); + + // change noise to 0, make the ring bend downwards + setTimeout(() => { + setMiddleRingNoise(false); + setMiddleRingWobbleStrength(0.2); + }, 300); + + // disable rotation of the ring + setTimeout(() => { + setMiddleRingRotating(false); + }, 700); + + // make the ring bend upwards + setTimeout(() => { + setMiddleRingWobbleStrength(-0.3); + }, 1300); + + // reset the ring bend, set the rotation to slightly curve + // to replicate a motion effect (since its moving upwards) + // and enable rotation again + setTimeout(() => { + setMiddleRingWobbleStrength(0.0); + setMiddleRingRotX(-0.2); + setMiddleRingRotating(true); + }, 1500); + + // reset the rotation value to 0 + setTimeout(() => { + setMiddleRingRotX(0); + }, 2500); + + // enable noise again in about 8~ secs + setTimeout(() => { + setMiddleRingNoise(true); + }, 7800); + break; case "right": rotateCamera(-0.1); @@ -143,7 +204,16 @@ const InputHandler = () => { }, 300); }, (lain_animations as LainAnimations)[key]["duration"]); }, - [moveCamera, rotateCamera, setLainMoveState, setLainMoving] + [ + moveCamera, + rotateCamera, + setLainMoveState, + setLainMoving, + setMiddleRingNoise, + setMiddleRingRotX, + setMiddleRingRotating, + setMiddleRingWobbleStrength, + ] ); const updateHUD = useCallback(() => { diff --git a/src/components/MiddleRing/MiddleRing.tsx b/src/components/MiddleRing/MiddleRing.tsx index 6cd52a0..90d97f5 100644 --- a/src/components/MiddleRing/MiddleRing.tsx +++ b/src/components/MiddleRing/MiddleRing.tsx @@ -1,10 +1,19 @@ -import React, { memo, useRef } from "react"; +import React, { memo, useMemo, useRef } from "react"; import { useFrame, useLoader } from "react-three-fiber"; import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; import middleRingTexture from "../../static/sprites/middle_ring_tex.png"; import { draco } from "drei"; import * as THREE from "three"; +import { useSpring, a } from "@react-spring/three"; +import { + middleRingNoiseAtom, + middleRingPosYAtom, + middleRingRotatingAtom, + middleRingRotXAtom, + middleRingWobbleStrengthAtom, +} from "./MiddleRingAtom"; +import { useRecoilValue } from "recoil"; type GLTFResult = GLTF & { nodes: { @@ -15,7 +24,7 @@ type GLTFResult = GLTF & { }; }; -const MiddleRing = memo(() => { +const MiddleRing = () => { const { nodes, materials } = useLoader( GLTFLoader, "/models/ring2.glb", @@ -24,15 +33,40 @@ const MiddleRing = memo(() => { const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture); - const uniforms = { - tex: { type: "t", value: middleRingTex }, - uTime: { value: 1.0 }, - }; + const middleRingWobbleStrength = useRecoilValue(middleRingWobbleStrengthAtom); + const middleRingRotating = useRecoilValue(middleRingRotatingAtom); + const middleRingNoise = useRecoilValue(middleRingNoiseAtom); + const middleRingPosY = useRecoilValue(middleRingPosYAtom); + const middleRingRotX = useRecoilValue(middleRingRotXAtom); + + const middleRingWobbleState = useSpring({ + middleRingWobbleStrength: middleRingWobbleStrength, + config: { duration: 200 }, + }); + + const middleRingPosState = useSpring({ + middleRingPosY: middleRingPosY, + config: { duration: 500 }, + }); + + const middleRingRotState = useSpring({ + middleRingRotX: middleRingRotX, + config: { duration: 1000 }, + }); + + const uniforms = useMemo( + () => ({ + tex: { type: "t", value: middleRingTex }, + uTime: { value: 1.0 }, + wobbleStrength: { value: 0.0 }, + }), + [middleRingTex] + ); const middleRingMaterialRef = useRef(); const middleRingRef = useRef(); - const vertexShader = ` + const noiseVertexShader = ` varying vec2 vUv; uniform float uTime; @@ -143,7 +177,7 @@ const MiddleRing = memo(() => { vec3 pos = position; float noiseFreq = 0.5; - float noiseAmp = 0.05; + float noiseAmp = 0.03; vec3 noisePos = vec3(pos.x * noiseFreq + uTime, pos.y, pos.z); pos.y += snoise(noisePos) * noiseAmp; @@ -151,24 +185,28 @@ const MiddleRing = memo(() => { } `; - const testVertex = ` + const sineVertexShader = ` varying vec2 vUv; + uniform float wobbleStrength; void main() { vUv = uv; + const float angleOffset = -0.8f; + // compute world position of the vertex // (ie, position after model rotation and translation) - vec3 worldPos = modelMatrix * vec3(position, 1.0f); + vec4 worldPos = modelMatrix * vec4(position, 0.0f); + float wobbleAngle = atan(worldPos.x, worldPos.z) + angleOffset; // use the world position to move the original point up or down vec3 pos = position; - pos.y += 3.5 * sin(0.3 * worldPos.x) * sin(0.3 * worldPos.z); + pos.y += wobbleStrength * sin(wobbleAngle * 2.0f); // transform this position into final viewspace gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.); } -` +`; const fragmentShader = ` uniform sampler2D tex; @@ -186,35 +224,50 @@ const MiddleRing = memo(() => { useFrame(() => { if (middleRingMaterialRef.current) { middleRingMaterialRef.current.uniforms.uTime.value = clock.getElapsedTime(); + middleRingMaterialRef.current.uniforms.wobbleStrength.value = middleRingWobbleState.middleRingWobbleStrength.get(); + middleRingMaterialRef.current.needsUpdate = true; + } + if (middleRingRotating) { + middleRingRef.current!.rotation.y += 0.05; } - // middleRingRef.current!.rotation.y += 0.06; }); - // -0.15, 03 return ( - - + + {middleRingNoise ? ( - - - + ) : ( + + )} + ); -}); +}; export default MiddleRing; diff --git a/src/components/MiddleRing/MiddleRingAtom.tsx b/src/components/MiddleRing/MiddleRingAtom.tsx new file mode 100644 index 0000000..52d39cc --- /dev/null +++ b/src/components/MiddleRing/MiddleRingAtom.tsx @@ -0,0 +1,26 @@ +import { atom } from "recoil"; + +export const middleRingWobbleStrengthAtom = atom({ + key: "middleRingWobbleStrengthAtom", + default: 0.0, +}); + +export const middleRingRotatingAtom = atom({ + key: "middleRingRotatingAtom", + default: true, +}); + +export const middleRingNoiseAtom = atom({ + key: "middleRingNoiseAtom", + default: true, +}); + +export const middleRingPosYAtom = atom({ + key: "middleRingPosYAtom", + default: -0.15, +}); + +export const middleRingRotXAtom = atom({ + key: "middleRingRotXAtom", + default: 0, +});