Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FE] [06-04] 별 클릭시 해당 방향으로 카메라 시점 이동하도록 설정 #93

Merged
merged 4 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions packages/client/src/components/feature/Controls/Controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,25 @@ import { useRef } from 'react';
import { OrbitControls } from '@react-three/drei';
import * as THREE from 'three';
import { useCameraStore } from 'store/useCameraStore';
import { useFrame } from '@react-three/fiber';
import { Camera, useFrame } from '@react-three/fiber';
import type { OrbitControls as OrbitControlsImpl } from 'three-stdlib';

const setCameraPosition = (
camera: Camera,
currentView: THREE.Vector3,
distance: number,
) => {
const direction = currentView
.clone()
.sub(camera.position)
.setLength(camera.position.distanceTo(currentView) - distance);
camera.position.add(direction);
};

bananaba marked this conversation as resolved.
Show resolved Hide resolved
export default function Controls() {
const controlsRef = useRef<OrbitControlsImpl>(null!);
const { currentView, setCurrentView, targetView } = useCameraStore();
const { cameraToCurrentView, currentView, setCurrentView, targetView } =
useCameraStore();

useFrame((state, delta) => {
const targetPosition = new THREE.Vector3(0, 0, 0);
Expand All @@ -21,7 +34,7 @@ export default function Controls() {
if (direction.length() > LENGTH_LIMIT) direction.setLength(LENGTH_LIMIT);

setCurrentView(currentView.add(direction));
state.camera.position.add(direction);
setCameraPosition(state.camera, currentView, cameraToCurrentView);

controlsRef.current.target = currentView;
}
Expand Down
53 changes: 28 additions & 25 deletions packages/client/src/components/feature/Galaxy/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as THREE from 'three';
import Star from '../Star';
import { getRandomInt, getGaussianRandomFloat } from '@utils/random';
import { useRef } from 'react';
import { useRef, useMemo } from 'react';
import { useFrame } from '@react-three/fiber';
import {
ARMS,
Expand Down Expand Up @@ -31,43 +31,46 @@ const getSpiralPositions = (offset: number) => {

export default function Galaxy() {
const galaxyRef = useRef<THREE.Group>(null!);
const stars = [];

useFrame((_, delta) => (galaxyRef.current.rotation.y += delta / 100));

for (let arm = 0; arm < ARMS; arm++) {
const stars = useMemo(() => {
bananaba marked this conversation as resolved.
Show resolved Hide resolved
const starList = [];
for (let arm = 0; arm < ARMS; arm++) {
for (let star = 0; star < STARS_NUM / (ARMS + 1); star++) {
const size = getRandomInt(STAR_MIN_SIZE, STAR_MAX_SIZE);
const position = getSpiralPositions((arm * 2 * Math.PI) / ARMS);

starList.push(
<Star
key={`${arm}${star}`}
position={position}
size={size}
color={'#FFF'}
/>,
);
}
}

for (let star = 0; star < STARS_NUM / (ARMS + 1); star++) {
const size = getRandomInt(STAR_MIN_SIZE, STAR_MAX_SIZE);
const position = getSpiralPositions((arm * 2 * Math.PI) / ARMS);
const position = new THREE.Vector3(
getGaussianRandomFloat(0, (ARMS_X_MEAN + ARMS_X_DIST) / 4),
getGaussianRandomFloat(0, GALAXY_THICKNESS * 2),
getGaussianRandomFloat(0, (ARMS_X_MEAN + ARMS_X_DIST) / 4),
);

stars.push(
starList.push(
<Star
key={`${arm}${star}`}
key={`star_${star}`}
position={position}
size={size}
color={'#FFF'}
/>,
);
}
}

for (let star = 0; star < STARS_NUM / (ARMS + 1); star++) {
const size = getRandomInt(STAR_MIN_SIZE, STAR_MAX_SIZE);
const position = new THREE.Vector3(
getGaussianRandomFloat(0, (ARMS_X_MEAN + ARMS_X_DIST) / 4),
getGaussianRandomFloat(0, GALAXY_THICKNESS * 2),
getGaussianRandomFloat(0, (ARMS_X_MEAN + ARMS_X_DIST) / 4),
);

stars.push(
<Star
key={`star_${star}`}
position={position}
size={size}
color={'#FFF'}
/>,
);
}
return starList;
}, []);

return <group ref={galaxyRef}>{stars}</group>;
}
10 changes: 9 additions & 1 deletion packages/client/src/components/feature/Screen/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { EffectComposer, Bloom } from '@react-three/postprocessing';
import { useControls } from 'leva';
import { CAMERA_POSITION, CAMERA_ROTATION, CAMERA_FAR } from 'constants/camera';
import Controls from '../Controls/Controls.tsx';
import { useCameraStore } from 'store/useCameraStore.ts';

export default function Screen() {
const camera = {
Expand All @@ -13,6 +14,8 @@ export default function Screen() {
far: CAMERA_FAR,
};

const { cameraToCurrentView, setCameraToCurrentView } = useCameraStore();

const { intensity, mipmapBlur, luminanceThreshold, luminanceSmoothing } =
useControls('Bloom', {
intensity: { value: 0.4, min: 0, max: 1.5, step: 0.01 },
Expand All @@ -23,7 +26,12 @@ export default function Screen() {

return (
<div style={{ height: '100vh', width: '100vw' }}>
<Canvas camera={camera}>
<Canvas
camera={camera}
onWheel={(e) =>
setCameraToCurrentView(cameraToCurrentView + e.deltaY / 20)
}
bananaba marked this conversation as resolved.
Show resolved Hide resolved
>
<EffectComposer>
<Bloom
intensity={intensity}
Expand Down
1 change: 1 addition & 0 deletions packages/client/src/constants/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ type Vector3 = [number, number, number];
export const CAMERA_POSITION: Vector3 = [0, 2000, 2000];
export const CAMERA_ROTATION: Vector3 = [-0.5, 0, 0];
export const CAMERA_FAR = 100000;
export const CAMERA_MIN_DISTANCE = 100;
9 changes: 9 additions & 0 deletions packages/client/src/store/useCameraStore.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import { create } from 'zustand';
import * as THREE from 'three';
import { CAMERA_MIN_DISTANCE } from 'constants/camera';

interface cameraState {
currentView: THREE.Vector3;
setCurrentView: (position: THREE.Vector3) => void;
targetView: THREE.Mesh | null;
setTargetView: (star: THREE.Mesh | null) => void;
cameraToCurrentView: number;
setCameraToCurrentView: (distance: number) => void;
}

export const useCameraStore = create<cameraState>()((set) => ({
currentView: new THREE.Vector3(0, 0, 0),
setCurrentView: (position: THREE.Vector3) => set({ currentView: position }),
targetView: null,
setTargetView: (star: THREE.Mesh | null) => set({ targetView: star }),
cameraToCurrentView: CAMERA_MIN_DISTANCE,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

뭔가 camera에서 CurrentView로 이동해야할 것만 같은 이름인데..
더 좋은 네이밍이 있을 것 같은데 저도 마땅한게 안떠오르네요
DistanceBetweenAandB 형식으로 하면 너무 길 것 같은디..

setCameraToCurrentView: (distance: number) =>
set({
cameraToCurrentView:
distance > CAMERA_MIN_DISTANCE ? distance : CAMERA_MIN_DISTANCE,
}),
bananaba marked this conversation as resolved.
Show resolved Hide resolved
}));