From ca4bfaa8b3d6075d1ec953c54e92a8edfa7a746d Mon Sep 17 00:00:00 2001 From: wnsgur393 <2021301022@skuniv.ac.kr> Date: Mon, 25 Aug 2025 22:50:59 +0900 Subject: [PATCH 1/8] update code --- src/components/ArtworkFrame.jsx | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/components/ArtworkFrame.jsx b/src/components/ArtworkFrame.jsx index 7007c84..babd243 100644 --- a/src/components/ArtworkFrame.jsx +++ b/src/components/ArtworkFrame.jsx @@ -27,6 +27,27 @@ function SafeImagePlane({ console.log("이미지 로딩 시작:", imageUrl); + // S3 URL에서 파일명만 추출하는 함수 + const extractFilenameFromS3Url = (url) => { + if (!url) return ''; + + // S3 URL 패턴 확인 + const s3Pattern = /https:\/\/likelion13-artium\.s3\.ap-northeast-2\.amazonaws\.com\/piece\/(.+)/; + const match = url.match(s3Pattern); + + if (match && match[1]) { + // 파일명 부분만 반환 + return match[1]; + } + + // S3 URL이 아닌 경우 원본 URL 반환 + return url; + }; + + // 파일명 추출 + const filename = extractFilenameFromS3Url(imageUrl); + console.log("추출된 파일명:", filename); + // HTML Image 객체를 사용하여 백엔드 프록시를 통해 이미지 로드 const img = new Image(); img.crossOrigin = "anonymous"; @@ -37,7 +58,7 @@ function SafeImagePlane({ // HTML Image를 Three.js TextureLoader로 변환 const loader = new TextureLoader(); const texture = loader.load( - `https://api.artium.life/api/piece?filename=${encodeURIComponent(imageUrl)}`, // 백엔드 프록시 URL + `https://api.artium.life/api/piece?filename=${encodeURIComponent(filename)}`, // 파일명만 전송 undefined, undefined, (err) => { @@ -59,8 +80,8 @@ function SafeImagePlane({ console.error("❌ HTML Image 로드 실패:", imageUrl); console.error("에러 상세:", err); - // 백엔드 프록시 URL로 재시도 - const proxyUrl = `https://api.artium.life/api/piece?filename=${encodeURIComponent(imageUrl)}`; + // 백엔드 프록시 URL로 재시도 (파일명만 사용) + const proxyUrl = `https://api.artium.life/api/piece?filename=${encodeURIComponent(filename)}`; console.log("🔄 백엔드 프록시 URL로 재시도:", proxyUrl); const retryImg = new Image(); @@ -95,8 +116,8 @@ function SafeImagePlane({ retryImg.src = proxyUrl; }; - // 백엔드 프록시 URL로 이미지 로드 시작 - const proxyUrl = `https://api.artium.life/api/piece?filename=${encodeURIComponent(imageUrl)}`; + // 백엔드 프록시 URL로 이미지 로드 시작 (파일명만 사용) + const proxyUrl = `https://api.artium.life/api/piece?filename=${encodeURIComponent(filename)}`; img.src = proxyUrl; }, [imageUrl]); From 2b9e8f4301ae6289eba6673ce95384ff7e7bc041 Mon Sep 17 00:00:00 2001 From: wnsgur393 <2021301022@skuniv.ac.kr> Date: Mon, 25 Aug 2025 22:56:43 +0900 Subject: [PATCH 2/8] z --- src/components/ArtworkFrame.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ArtworkFrame.jsx b/src/components/ArtworkFrame.jsx index babd243..0b9b40b 100644 --- a/src/components/ArtworkFrame.jsx +++ b/src/components/ArtworkFrame.jsx @@ -58,7 +58,7 @@ function SafeImagePlane({ // HTML Image를 Three.js TextureLoader로 변환 const loader = new TextureLoader(); const texture = loader.load( - `https://api.artium.life/api/piece?filename=${encodeURIComponent(filename)}`, // 파일명만 전송 + `https://api.artium.life/api/piece?filename=${(filename)}`, // 파일명만 전송 undefined, undefined, (err) => { @@ -71,7 +71,7 @@ function SafeImagePlane({ // 이미지 뒤집기 설정 texture.flipY = true; - setTexture(texture); + setTexture(texture);ㅎ setLoading(false); console.log("🎨 Three.js 텍스처 변환 완료!"); }; From 5e291d89eae5e4d98a1596b8058c09fd03e3401b Mon Sep 17 00:00:00 2001 From: wnsgur393 <2021301022@skuniv.ac.kr> Date: Mon, 25 Aug 2025 23:01:59 +0900 Subject: [PATCH 3/8] z --- src/components/ArtworkFrame.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/ArtworkFrame.jsx b/src/components/ArtworkFrame.jsx index 0b9b40b..52d6e58 100644 --- a/src/components/ArtworkFrame.jsx +++ b/src/components/ArtworkFrame.jsx @@ -58,7 +58,7 @@ function SafeImagePlane({ // HTML Image를 Three.js TextureLoader로 변환 const loader = new TextureLoader(); const texture = loader.load( - `https://api.artium.life/api/piece?filename=${(filename)}`, // 파일명만 전송 + `https://api.artium.life/api/piece?filename=${filename}`, // 파일명만 전송 undefined, undefined, (err) => { @@ -81,7 +81,7 @@ function SafeImagePlane({ console.error("에러 상세:", err); // 백엔드 프록시 URL로 재시도 (파일명만 사용) - const proxyUrl = `https://api.artium.life/api/piece?filename=${encodeURIComponent(filename)}`; + const proxyUrl = `https://api.artium.life/api/piece?filename=${filename}`; console.log("🔄 백엔드 프록시 URL로 재시도:", proxyUrl); const retryImg = new Image(); @@ -117,7 +117,7 @@ function SafeImagePlane({ }; // 백엔드 프록시 URL로 이미지 로드 시작 (파일명만 사용) - const proxyUrl = `https://api.artium.life/api/piece?filename=${encodeURIComponent(filename)}`; + const proxyUrl = `https://api.artium.life/api/piece?filename=${filename}`; img.src = proxyUrl; }, [imageUrl]); From 94e93751dc9e190600078fd9885eb5d5195e4266 Mon Sep 17 00:00:00 2001 From: wnsgur393 <2021301022@skuniv.ac.kr> Date: Mon, 25 Aug 2025 23:07:19 +0900 Subject: [PATCH 4/8] z --- src/components/ArtworkFrame.jsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/ArtworkFrame.jsx b/src/components/ArtworkFrame.jsx index 52d6e58..22db086 100644 --- a/src/components/ArtworkFrame.jsx +++ b/src/components/ArtworkFrame.jsx @@ -31,16 +31,19 @@ function SafeImagePlane({ const extractFilenameFromS3Url = (url) => { if (!url) return ''; - // S3 URL 패턴 확인 - const s3Pattern = /https:\/\/likelion13-artium\.s3\.ap-northeast-2\.amazonaws\.com\/piece\/(.+)/; - const match = url.match(s3Pattern); + console.log("원본 URL:", url); + // UUID 패턴으로 파일명 추출 (가장 우선순위) + const uuidPattern = /([a-f0-9-]{36})/; + const match = url.match(uuidPattern); if (match && match[1]) { - // 파일명 부분만 반환 - return match[1]; + const filename = match[1]; + console.log("UUID 패턴에서 추출:", filename); + return filename; } - // S3 URL이 아닌 경우 원본 URL 반환 + // UUID가 없는 경우 원본 반환 + console.log("UUID 패턴 매칭 실패, 원본 반환:", url); return url; }; From 235d325a68e84339dbb75e6133ef4856f3c81ace Mon Sep 17 00:00:00 2001 From: wnsgur393 <2021301022@skuniv.ac.kr> Date: Mon, 25 Aug 2025 23:12:35 +0900 Subject: [PATCH 5/8] asdf --- src/components/ArtworkFrame.jsx | 94 +++++++++++++-------------------- 1 file changed, 36 insertions(+), 58 deletions(-) diff --git a/src/components/ArtworkFrame.jsx b/src/components/ArtworkFrame.jsx index 22db086..f801121 100644 --- a/src/components/ArtworkFrame.jsx +++ b/src/components/ArtworkFrame.jsx @@ -3,6 +3,7 @@ import { useFrame } from "@react-three/fiber"; import { Text, Box, Plane } from "@react-three/drei"; import { TextureLoader } from "three"; import PropTypes from "prop-types"; +import { APIService } from "../apis/axios"; // 안전한 이미지 로더 컴포넌트 function SafeImagePlane({ @@ -51,77 +52,54 @@ function SafeImagePlane({ const filename = extractFilenameFromS3Url(imageUrl); console.log("추출된 파일명:", filename); - // HTML Image 객체를 사용하여 백엔드 프록시를 통해 이미지 로드 - const img = new Image(); - img.crossOrigin = "anonymous"; - - img.onload = () => { - console.log("✅ HTML Image 로드 성공, TextureLoader로 변환 중..."); - - // HTML Image를 Three.js TextureLoader로 변환 - const loader = new TextureLoader(); - const texture = loader.load( - `https://api.artium.life/api/piece?filename=${filename}`, // 파일명만 전송 - undefined, - undefined, - (err) => { - console.error("❌ TextureLoader 로드 실패", err); - setError(true); - setLoading(false); - } - ); - - // 이미지 뒤집기 설정 - texture.flipY = true; + // APIService.private를 사용하여 인증된 이미지 요청 + const loadImageWithAuth = async () => { + try { + console.log("🔑 APIService.private로 이미지 요청:", filename); + + // APIService.private.get을 사용하여 이미지 요청 + const response = await APIService.private.get(`/api/piece?filename=${filename}`, { + responseType: 'blob', // 이미지 데이터를 blob으로 받기 + }); + + console.log("✅ APIService로 이미지 로드 성공, TextureLoader로 변환 중..."); - setTexture(texture);ㅎ - setLoading(false); - console.log("🎨 Three.js 텍스처 변환 완료!"); - }; + // Blob 데이터를 URL로 변환 + const blob = new Blob([response], { type: 'image/jpeg' }); + const imageUrl = URL.createObjectURL(blob); - img.onerror = (err) => { - console.error("❌ HTML Image 로드 실패:", imageUrl); - console.error("에러 상세:", err); - - // 백엔드 프록시 URL로 재시도 (파일명만 사용) - const proxyUrl = `https://api.artium.life/api/piece?filename=${filename}`; - console.log("🔄 백엔드 프록시 URL로 재시도:", proxyUrl); - - const retryImg = new Image(); - retryImg.crossOrigin = "anonymous"; - - retryImg.onload = () => { - console.log("✅ 백엔드 프록시로 로딩 성공:", proxyUrl); - - const retryLoader = new TextureLoader(); - const retryTexture = retryLoader.load( - proxyUrl, + // Blob URL을 TextureLoader로 변환 + const loader = new TextureLoader(); + const texture = loader.load( + imageUrl, undefined, undefined, - (retryErr) => { - console.error("❌ 백엔드 프록시로도 실패:", retryErr); + (err) => { + console.error("❌ TextureLoader 로드 실패", err); setError(true); setLoading(false); } ); - - retryTexture.flipY = true; - setTexture(retryTexture); + + // 이미지 뒤집기 설정 + texture.flipY = true; + + setTexture(texture); setLoading(false); - }; - - retryImg.onerror = (retryErr) => { - console.error("❌ 백엔드 프록시로도 실패:", retryErr); + console.log("🎨 Three.js 텍스처 변환 완료!"); + + // Blob URL 정리 + URL.revokeObjectURL(imageUrl); + + } catch (error) { + console.error("❌ 이미지 로드 실패:", error); setError(true); setLoading(false); - }; - - retryImg.src = proxyUrl; + } }; - // 백엔드 프록시 URL로 이미지 로드 시작 (파일명만 사용) - const proxyUrl = `https://api.artium.life/api/piece?filename=${filename}`; - img.src = proxyUrl; + // 이미지 로드 시작 + loadImageWithAuth(); }, [imageUrl]); if (loading) { From 9dd664c4d6a1f24e2f386fdf74a9a9b157facc24 Mon Sep 17 00:00:00 2001 From: wnsgur393 <2021301022@skuniv.ac.kr> Date: Mon, 25 Aug 2025 23:17:55 +0900 Subject: [PATCH 6/8] z --- src/components/ArtworkFrame.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ArtworkFrame.jsx b/src/components/ArtworkFrame.jsx index f801121..dc015c0 100644 --- a/src/components/ArtworkFrame.jsx +++ b/src/components/ArtworkFrame.jsx @@ -58,7 +58,7 @@ function SafeImagePlane({ console.log("🔑 APIService.private로 이미지 요청:", filename); // APIService.private.get을 사용하여 이미지 요청 - const response = await APIService.private.get(`/api/piece?filename=${filename}`, { + const response = await APIService.private.get(`/api/s3/${filename}`, { responseType: 'blob', // 이미지 데이터를 blob으로 받기 }); From bf1924d4ac98533af4e54f0d0aab1d614c5ed194 Mon Sep 17 00:00:00 2001 From: wnsgur393 <2021301022@skuniv.ac.kr> Date: Mon, 25 Aug 2025 23:25:08 +0900 Subject: [PATCH 7/8] z --- src/components/ArtworkFrame.jsx | 118 +++++++++++++------------------- 1 file changed, 48 insertions(+), 70 deletions(-) diff --git a/src/components/ArtworkFrame.jsx b/src/components/ArtworkFrame.jsx index dc015c0..42ab866 100644 --- a/src/components/ArtworkFrame.jsx +++ b/src/components/ArtworkFrame.jsx @@ -3,7 +3,6 @@ import { useFrame } from "@react-three/fiber"; import { Text, Box, Plane } from "@react-three/drei"; import { TextureLoader } from "three"; import PropTypes from "prop-types"; -import { APIService } from "../apis/axios"; // 안전한 이미지 로더 컴포넌트 function SafeImagePlane({ @@ -27,79 +26,58 @@ function SafeImagePlane({ } console.log("이미지 로딩 시작:", imageUrl); - - // S3 URL에서 파일명만 추출하는 함수 - const extractFilenameFromS3Url = (url) => { - if (!url) return ''; - - console.log("원본 URL:", url); - - // UUID 패턴으로 파일명 추출 (가장 우선순위) - const uuidPattern = /([a-f0-9-]{36})/; - const match = url.match(uuidPattern); - if (match && match[1]) { - const filename = match[1]; - console.log("UUID 패턴에서 추출:", filename); - return filename; - } - - // UUID가 없는 경우 원본 반환 - console.log("UUID 패턴 매칭 실패, 원본 반환:", url); - return url; - }; - - // 파일명 추출 - const filename = extractFilenameFromS3Url(imageUrl); - console.log("추출된 파일명:", filename); - - // APIService.private를 사용하여 인증된 이미지 요청 - const loadImageWithAuth = async () => { - try { - console.log("🔑 APIService.private로 이미지 요청:", filename); - - // APIService.private.get을 사용하여 이미지 요청 - const response = await APIService.private.get(`/api/s3/${filename}`, { - responseType: 'blob', // 이미지 데이터를 blob으로 받기 - }); - - console.log("✅ APIService로 이미지 로드 성공, TextureLoader로 변환 중..."); - - // Blob 데이터를 URL로 변환 - const blob = new Blob([response], { type: 'image/jpeg' }); - const imageUrl = URL.createObjectURL(blob); + const loader = new TextureLoader(); - // Blob URL을 TextureLoader로 변환 - const loader = new TextureLoader(); - const texture = loader.load( - imageUrl, - undefined, - undefined, - (err) => { - console.error("❌ TextureLoader 로드 실패", err); - setError(true); - setLoading(false); - } - ); + + loader.load( + imageUrl, // 프록시 URL 사용 + (loadedTexture) => { + console.log("✅ 이미지 로딩 성공:", imageUrl); + console.log("텍스처 정보:", loadedTexture); + loadedTexture.flipY = true; // 이미지 뒤집힘 문제 해결 + setTexture(loadedTexture); + setLoading(false); + }, + (progress) => { + console.log("📥 이미지 로딩 진행:", imageUrl, progress); + }, + (err) => { + console.error("❌ 이미지 로드 실패:", imageUrl); + console.error("에러 상세:", err); + console.error("에러 타입:", typeof err); + console.error("에러 메시지:", err?.message); - // 이미지 뒤집기 설정 - texture.flipY = true; + // 원본 URL로 직접 시도해보기 + if (imageUrl.startsWith("/s3-proxy/")) { + const originalUrl = `https://likelion13-artium.s3.ap-northeast-2.amazonaws.com${imageUrl.replace( + "/s3-proxy", + "" + )}`; + console.log("🔄 원본 URL로 재시도:", originalUrl); - setTexture(texture); - setLoading(false); - console.log("🎨 Three.js 텍스처 변환 완료!"); - - // Blob URL 정리 - URL.revokeObjectURL(imageUrl); - - } catch (error) { - console.error("❌ 이미지 로드 실패:", error); - setError(true); - setLoading(false); + const retryLoader = new TextureLoader(); + retryLoader.setCrossOrigin("anonymous"); + retryLoader.load( + originalUrl, + (loadedTexture) => { + console.log("✅ 원본 URL로 로딩 성공:", originalUrl); + loadedTexture.flipY = true; + setTexture(loadedTexture); + setLoading(false); + }, + undefined, + (retryErr) => { + console.error("❌ 원본 URL로도 실패:", retryErr); + setError(true); + setLoading(false); + } + ); + } else { + setError(true); + setLoading(false); + } } - }; - - // 이미지 로드 시작 - loadImageWithAuth(); + ); }, [imageUrl]); if (loading) { From 9572296d4ebf3217b45293f4b5d321b4d0985ec8 Mon Sep 17 00:00:00 2001 From: wnsgur393 <2021301022@skuniv.ac.kr> Date: Mon, 25 Aug 2025 23:32:33 +0900 Subject: [PATCH 8/8] =?UTF-8?q?=E3=85=81=E3=84=B4=E3=85=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ArtworkFrame.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/ArtworkFrame.jsx b/src/components/ArtworkFrame.jsx index 42ab866..3265160 100644 --- a/src/components/ArtworkFrame.jsx +++ b/src/components/ArtworkFrame.jsx @@ -148,9 +148,9 @@ function ArtworkFrame({ artwork, position, onArtworkClick }) { else if (x > 16) { return [0, -Math.PI / 2, 0]; // -90도 회전 } - // 앞쪽 벽 (z > 7) + // 앞쪽 벽 (z > 7) - 카메라를 향하도록 else if (z > 7) { - return [0, Math.PI, 0]; // 180도 회전 + return [0, 0, 0]; // 회전 없음 (카메라를 향함) } // 뒷벽 (z < -7) 또는 기본 else {