From 7f6c2134cd14d9651e5b68a857110856ba2d3181 Mon Sep 17 00:00:00 2001 From: okorion Date: Mon, 3 Aug 2026 15:48:43 +0900 Subject: [PATCH] =?UTF-8?q?[refactor]=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=ED=9D=90=EB=A6=84=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 변경 유형: refactor - 주된 영역: src/components/GalaxyScene.tsx - 변경 의도: src/components/GalaxyScene.tsx의 구조를 정리해 이후 기능 개선과 검증 비용을 낮춥니다. Co-authored-by: Codex --- src/components/GalaxyScene.tsx | 62 ++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/components/GalaxyScene.tsx b/src/components/GalaxyScene.tsx index 4450bf5..de368d0 100644 --- a/src/components/GalaxyScene.tsx +++ b/src/components/GalaxyScene.tsx @@ -5,11 +5,11 @@ import { type ComponentRef, type RefObject, useEffect, useMemo, useRef } from 'r import * as THREE from 'three' import type { ActivityBucket, ActivityKind } from '../activity-data' -type ActivityPoint = { - key: string - kind: ActivityKind - color: string - position: [number, number, number] +type ActivityPointPosition = [number, number, number] + +type ActivityOrbit = { + bucket: ActivityBucket + pointPositions: ActivityPointPosition[] } type GalaxyProps = { @@ -34,30 +34,32 @@ const INITIAL_CAMERA = { const CANVAS_PIXEL_RATIO: [number, number] = [1, 1.75] const CANVAS_BACKGROUND: [string] = ['#f8fbff'] -const createActivityPoint = (bucket: ActivityBucket, bucketIndex: number, index: number): ActivityPoint => { +const createActivityPointPosition = ( + bucket: ActivityBucket, + bucketIndex: number, + index: number, +): ActivityPointPosition => { const angle = (index / bucket.count) * Math.PI * 2 + bucketIndex * 0.7 const spiral = bucket.radius + index * 0.006 - return { - key: `${bucket.kind}-${index}`, - kind: bucket.kind, - color: bucket.color, - position: [ - Math.cos(angle) * spiral, - Math.sin(index * 1.7) * 0.22 + bucketIndex * 0.08, - Math.sin(angle) * spiral, - ], - } + return [ + Math.cos(angle) * spiral, + Math.sin(index * 1.7) * 0.22 + bucketIndex * 0.08, + Math.sin(angle) * spiral, + ] } -const createActivityPoints = (buckets: readonly ActivityBucket[]) => - buckets.flatMap((bucket, bucketIndex) => - Array.from({ length: bucket.count }, (_, index) => createActivityPoint(bucket, bucketIndex, index)), - ) +const createActivityOrbits = (buckets: readonly ActivityBucket[]): ActivityOrbit[] => + buckets.map((bucket, bucketIndex) => ({ + bucket, + pointPositions: Array.from({ length: bucket.count }, (_, index) => + createActivityPointPosition(bucket, bucketIndex, index), + ), + })) function Galaxy({ buckets, selectedKind, isRotating }: GalaxyProps) { const groupRef = useRef(null) - const activityPoints = useMemo(() => createActivityPoints(buckets), [buckets]) + const activityOrbits = useMemo(() => createActivityOrbits(buckets), [buckets]) useFrame((_, delta) => { if (groupRef.current && isRotating) groupRef.current.rotation.y += Math.min(delta, 0.1) * 0.08 @@ -65,7 +67,7 @@ function Galaxy({ buckets, selectedKind, isRotating }: GalaxyProps) { return ( - {buckets.map((bucket) => { + {activityOrbits.map(({ bucket }) => { const isSelected = bucket.kind === selectedKind return ( @@ -75,23 +77,23 @@ function Galaxy({ buckets, selectedKind, isRotating }: GalaxyProps) { ) })} - {activityPoints.map((point) => { - const isSelected = point.kind === selectedKind + {activityOrbits.flatMap(({ bucket, pointPositions }) => { + const isSelected = bucket.kind === selectedKind - return ( - + return pointPositions.map((position, index) => ( + - ) + )) })} - {buckets.map((bucket, index) => ( + {activityOrbits.map(({ bucket }, index) => (