ADD : 갤러리 추가
This commit is contained in:
parent
287879240f
commit
79fd7f22f6
BIN
Studio_Image/커튼 걷은 360 이미지.webp
Normal file
BIN
Studio_Image/커튼 걷은 360 이미지.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
BIN
Studio_Image/커튼친 360 이미지.webp
Normal file
BIN
Studio_Image/커튼친 360 이미지.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
341
css/gallery.css
341
css/gallery.css
@ -234,6 +234,291 @@
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* 360도 이미지 뷰어 스타일 */
|
||||
.panorama-section {
|
||||
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
||||
padding: var(--spacing-3xl) 0;
|
||||
margin: var(--spacing-3xl) 0;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
.panorama-section h2 {
|
||||
text-align: center;
|
||||
font-size: var(--font-4xl);
|
||||
margin-bottom: var(--spacing-md);
|
||||
color: var(--text-dark);
|
||||
}
|
||||
|
||||
.panorama-section .section-subtitle {
|
||||
text-align: center;
|
||||
font-size: var(--font-lg);
|
||||
color: var(--text-light);
|
||||
margin-bottom: var(--spacing-2xl);
|
||||
}
|
||||
|
||||
.panorama-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
|
||||
gap: var(--spacing-xl);
|
||||
margin-top: var(--spacing-2xl);
|
||||
}
|
||||
|
||||
.panorama-viewer {
|
||||
position: relative;
|
||||
background: var(--bg-white);
|
||||
border-radius: var(--border-radius);
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12);
|
||||
transition: var(--transition);
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.panorama-viewer:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
|
||||
.panorama-viewer:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
.panorama-clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.panorama-clickable:hover {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
.panorama-clickable:hover .panorama-help {
|
||||
opacity: 1;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.panorama-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.panorama-preview {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.panorama-controls {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: linear-gradient(transparent, rgba(0, 0, 0, 0.8));
|
||||
padding: var(--spacing-lg);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.panorama-title {
|
||||
color: var(--text-white);
|
||||
font-weight: 600;
|
||||
font-size: var(--font-base);
|
||||
}
|
||||
|
||||
.panorama-buttons {
|
||||
display: flex;
|
||||
gap: var(--spacing-sm);
|
||||
}
|
||||
|
||||
.panorama-btn {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
color: var(--text-white);
|
||||
padding: var(--spacing-xs) var(--spacing-sm);
|
||||
border-radius: var(--border-radius-sm);
|
||||
cursor: pointer;
|
||||
font-size: var(--font-sm);
|
||||
transition: var(--transition);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.panorama-btn:hover {
|
||||
background: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.panorama-btn.active {
|
||||
background: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
.panorama-indicator {
|
||||
position: absolute;
|
||||
top: var(--spacing-md);
|
||||
right: var(--spacing-md);
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
color: var(--text-white);
|
||||
padding: var(--spacing-xs) var(--spacing-sm);
|
||||
border-radius: var(--border-radius-full);
|
||||
font-size: var(--font-xs);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.panorama-help {
|
||||
position: absolute;
|
||||
top: var(--spacing-md);
|
||||
left: var(--spacing-md);
|
||||
background: rgba(255, 136, 0, 0.9);
|
||||
color: var(--text-white);
|
||||
padding: var(--spacing-xs) var(--spacing-sm);
|
||||
border-radius: var(--border-radius-sm);
|
||||
font-size: var(--font-xs);
|
||||
animation: fadeInOut 3s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes fadeInOut {
|
||||
0%, 100% { opacity: 0; }
|
||||
20%, 80% { opacity: 1; }
|
||||
}
|
||||
|
||||
/* Pannellum 360도 이미지 전체화면 모달 */
|
||||
.panorama-modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: rgba(0, 0, 0, 0.95);
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.panorama-modal.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.panorama-modal-content {
|
||||
position: relative;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.panorama-modal-viewer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.panorama-modal-controls {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: linear-gradient(transparent, rgba(0, 0, 0, 0.9));
|
||||
padding: var(--spacing-xl);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.panorama-modal-title {
|
||||
color: var(--text-white);
|
||||
font-weight: 600;
|
||||
font-size: var(--font-xl);
|
||||
}
|
||||
|
||||
.panorama-modal-buttons {
|
||||
display: flex;
|
||||
gap: var(--spacing-md);
|
||||
}
|
||||
|
||||
.panorama-modal-btn {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
color: var(--text-white);
|
||||
padding: var(--spacing-sm) var(--spacing-lg);
|
||||
border-radius: var(--border-radius);
|
||||
cursor: pointer;
|
||||
font-size: var(--font-base);
|
||||
transition: var(--transition);
|
||||
backdrop-filter: blur(10px);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.panorama-modal-btn:hover {
|
||||
background: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.panorama-modal-btn.active {
|
||||
background: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
.panorama-modal-close {
|
||||
position: absolute;
|
||||
top: var(--spacing-lg);
|
||||
right: var(--spacing-lg);
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
color: var(--text-white);
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: var(--font-xl);
|
||||
transition: var(--transition);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.panorama-modal-close:hover {
|
||||
background: var(--primary-color);
|
||||
border-color: var(--primary-color);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.panorama-modal-close::before {
|
||||
content: '✕';
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.panorama-modal-help {
|
||||
position: absolute;
|
||||
top: var(--spacing-lg);
|
||||
left: var(--spacing-lg);
|
||||
background: rgba(255, 136, 0, 0.9);
|
||||
color: var(--text-white);
|
||||
padding: var(--spacing-sm) var(--spacing-lg);
|
||||
border-radius: var(--border-radius);
|
||||
font-size: var(--font-base);
|
||||
font-weight: 500;
|
||||
animation: fadeInOut 4s ease-in-out;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.panorama-modal-indicator {
|
||||
position: absolute;
|
||||
top: var(--spacing-lg);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
color: var(--text-white);
|
||||
padding: var(--spacing-sm) var(--spacing-lg);
|
||||
border-radius: var(--border-radius-full);
|
||||
font-size: var(--font-base);
|
||||
font-weight: 600;
|
||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
/* 반응형 디자인 */
|
||||
@media (max-width: 768px) {
|
||||
.page-header h1 {
|
||||
@ -322,4 +607,60 @@
|
||||
font-size: var(--font-xs);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
}
|
||||
|
||||
.panorama-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--spacing-lg);
|
||||
}
|
||||
|
||||
.panorama-container {
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
.panorama-controls {
|
||||
padding: var(--spacing-md);
|
||||
}
|
||||
|
||||
.panorama-title {
|
||||
font-size: var(--font-sm);
|
||||
}
|
||||
|
||||
.panorama-btn {
|
||||
font-size: var(--font-xs);
|
||||
padding: var(--spacing-xs);
|
||||
}
|
||||
|
||||
.panorama-modal-content {
|
||||
width: 95vw;
|
||||
height: 60vh;
|
||||
}
|
||||
|
||||
.panorama-modal-controls {
|
||||
padding: var(--spacing-lg);
|
||||
}
|
||||
|
||||
.panorama-modal-title {
|
||||
font-size: var(--font-base);
|
||||
}
|
||||
|
||||
.panorama-modal-btn {
|
||||
font-size: var(--font-sm);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
}
|
||||
|
||||
.panorama-modal-close {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: var(--font-base);
|
||||
}
|
||||
|
||||
.panorama-modal-help {
|
||||
font-size: var(--font-sm);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
}
|
||||
|
||||
.panorama-modal-indicator {
|
||||
font-size: var(--font-sm);
|
||||
padding: var(--spacing-xs) var(--spacing-md);
|
||||
}
|
||||
}
|
||||
41
gallery.html
41
gallery.html
@ -39,6 +39,10 @@
|
||||
|
||||
<!-- 아이콘 폰트 (이모지 대체용) -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" rel="stylesheet">
|
||||
|
||||
<!-- Pannellum 360도 뷰어 -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pannellum@2.5.6/build/pannellum.css">
|
||||
|
||||
<link rel="stylesheet" href="css/common.css">
|
||||
<link rel="stylesheet" href="css/gallery.css">
|
||||
</head>
|
||||
@ -117,8 +121,45 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 360도 이미지 섹션 -->
|
||||
<section class="panorama-section">
|
||||
<div class="container">
|
||||
<h2>360° Studio View</h2>
|
||||
<p class="section-subtitle">드래그하여 스튜디오를 360도로 둘러보세요</p>
|
||||
|
||||
<div class="panorama-grid">
|
||||
<div class="panorama-viewer" data-panorama="curtain-open">
|
||||
<div class="panorama-container panorama-clickable"
|
||||
data-image="Studio_Image/커튼 걷은 360 이미지.webp"
|
||||
data-title="스튜디오 전경 (커튼 열림)">
|
||||
<div id="panorama-preview-1" class="panorama-preview"></div>
|
||||
<div class="panorama-help">클릭하여 360도로 보기</div>
|
||||
<div class="panorama-indicator">360° VR</div>
|
||||
</div>
|
||||
<div class="panorama-controls">
|
||||
<div class="panorama-title">스튜디오 전경 (커튼 열림)</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panorama-viewer" data-panorama="curtain-closed">
|
||||
<div class="panorama-container panorama-clickable"
|
||||
data-image="Studio_Image/커튼친 360 이미지.webp"
|
||||
data-title="스튜디오 전경 (커튼 닫힘)">
|
||||
<div id="panorama-preview-2" class="panorama-preview"></div>
|
||||
<div class="panorama-help">클릭하여 360도로 보기</div>
|
||||
<div class="panorama-indicator">360° VR</div>
|
||||
</div>
|
||||
<div class="panorama-controls">
|
||||
<div class="panorama-title">스튜디오 전경 (커튼 닫힘)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div id="footer-placeholder"></div>
|
||||
<script src="js/common.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/pannellum@2.5.6/build/pannellum.js"></script>
|
||||
<script src="js/gallery.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
199
js/gallery.js
199
js/gallery.js
@ -6,6 +6,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
initGallery();
|
||||
initLightbox();
|
||||
initGalleryAnimations();
|
||||
initPannellumViewers();
|
||||
});
|
||||
|
||||
// 갤러리 초기화
|
||||
@ -264,3 +265,201 @@ function handleSwipe() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Pannellum 기반 360도 이미지 뷰어 기능
|
||||
// ========================================
|
||||
|
||||
let currentPanoramaViewer = null;
|
||||
|
||||
function initPannellumViewers() {
|
||||
// 모달 생성
|
||||
createPannellumModal();
|
||||
|
||||
// 미리보기 이미지 설정
|
||||
initPanoramaPreviews();
|
||||
}
|
||||
|
||||
function initPanoramaPreviews() {
|
||||
const containers = document.querySelectorAll('.panorama-clickable');
|
||||
|
||||
containers.forEach(container => {
|
||||
const preview = container.querySelector('.panorama-preview');
|
||||
const imageSrc = container.dataset.image;
|
||||
const title = container.dataset.title;
|
||||
|
||||
// 미리보기 이미지 설정
|
||||
preview.style.backgroundImage = `url('${imageSrc}')`;
|
||||
|
||||
// 클릭 이벤트 - 전체화면 Pannellum 뷰어 열기
|
||||
container.addEventListener('click', () => {
|
||||
openPannellumModal(imageSrc, title);
|
||||
});
|
||||
|
||||
// 도움말 자동 숨김
|
||||
setTimeout(() => {
|
||||
const help = container.querySelector('.panorama-help');
|
||||
if (help) {
|
||||
help.style.opacity = '0';
|
||||
setTimeout(() => help.remove(), 1000);
|
||||
}
|
||||
}, 4000);
|
||||
});
|
||||
}
|
||||
|
||||
function createPannellumModal() {
|
||||
const modalHTML = `
|
||||
<div id="pannellum-modal" class="panorama-modal">
|
||||
<div class="panorama-modal-content">
|
||||
<div id="pannellum-viewer" class="panorama-modal-viewer"></div>
|
||||
<div class="panorama-modal-controls">
|
||||
<div id="pannellum-modal-title" class="panorama-modal-title"></div>
|
||||
<div class="panorama-modal-buttons">
|
||||
<button class="panorama-modal-btn" id="pannellum-reset-btn">
|
||||
<i class="fas fa-redo"></i> 리셋
|
||||
</button>
|
||||
<button class="panorama-modal-btn" id="pannellum-auto-btn">
|
||||
<i class="fas fa-play"></i> 자동회전
|
||||
</button>
|
||||
<button class="panorama-modal-btn" id="pannellum-fullscreen-btn">
|
||||
<i class="fas fa-expand"></i> 전체화면
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="panorama-modal-close" id="pannellum-modal-close">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.insertAdjacentHTML('beforeend', modalHTML);
|
||||
|
||||
// 모달 이벤트 리스너 설정
|
||||
setupPannellumModalListeners();
|
||||
}
|
||||
|
||||
function setupPannellumModalListeners() {
|
||||
const modal = document.getElementById('pannellum-modal');
|
||||
const closeBtn = document.getElementById('pannellum-modal-close');
|
||||
const resetBtn = document.getElementById('pannellum-reset-btn');
|
||||
const autoBtn = document.getElementById('pannellum-auto-btn');
|
||||
const fullscreenBtn = document.getElementById('pannellum-fullscreen-btn');
|
||||
|
||||
let isAutoRotating = false;
|
||||
|
||||
// 모달 닫기 이벤트
|
||||
closeBtn.addEventListener('click', closePannellumModal);
|
||||
|
||||
// ESC 키로 모달 닫기
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && modal.classList.contains('active')) {
|
||||
closePannellumModal();
|
||||
}
|
||||
});
|
||||
|
||||
// 리셋 버튼
|
||||
resetBtn.addEventListener('click', () => {
|
||||
if (currentPanoramaViewer) {
|
||||
currentPanoramaViewer.setPitch(0);
|
||||
currentPanoramaViewer.setYaw(0);
|
||||
stopAutoRotate();
|
||||
}
|
||||
});
|
||||
|
||||
// 자동 회전 버튼
|
||||
autoBtn.addEventListener('click', () => {
|
||||
if (isAutoRotating) {
|
||||
stopAutoRotate();
|
||||
} else {
|
||||
startAutoRotate();
|
||||
}
|
||||
});
|
||||
|
||||
// 전체화면 버튼
|
||||
fullscreenBtn.addEventListener('click', () => {
|
||||
if (currentPanoramaViewer) {
|
||||
currentPanoramaViewer.toggleFullscreen();
|
||||
}
|
||||
});
|
||||
|
||||
function startAutoRotate() {
|
||||
if (currentPanoramaViewer) {
|
||||
currentPanoramaViewer.startAutoRotate(0.5); // 초당 0.5도 회전
|
||||
isAutoRotating = true;
|
||||
autoBtn.innerHTML = '<i class="fas fa-pause"></i> 정지';
|
||||
autoBtn.classList.add('active');
|
||||
}
|
||||
}
|
||||
|
||||
function stopAutoRotate() {
|
||||
if (currentPanoramaViewer) {
|
||||
currentPanoramaViewer.stopAutoRotate();
|
||||
isAutoRotating = false;
|
||||
autoBtn.innerHTML = '<i class="fas fa-play"></i> 자동회전';
|
||||
autoBtn.classList.remove('active');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function openPannellumModal(imageSrc, title) {
|
||||
const modal = document.getElementById('pannellum-modal');
|
||||
const modalTitle = document.getElementById('pannellum-modal-title');
|
||||
|
||||
modalTitle.textContent = title;
|
||||
modal.classList.add('active');
|
||||
document.body.style.overflow = 'hidden';
|
||||
|
||||
// Pannellum 뷰어 초기화
|
||||
currentPanoramaViewer = pannellum.viewer('pannellum-viewer', {
|
||||
type: 'equirectangular',
|
||||
panorama: imageSrc,
|
||||
autoLoad: true,
|
||||
autoRotate: 0,
|
||||
compass: true,
|
||||
northOffset: 0,
|
||||
preview: imageSrc,
|
||||
hfov: 100,
|
||||
minHfov: 50,
|
||||
maxHfov: 120,
|
||||
pitch: 0,
|
||||
yaw: 0,
|
||||
mouseZoom: true,
|
||||
keyboardZoom: true,
|
||||
draggable: true,
|
||||
disableKeyboardCtrl: false,
|
||||
showControls: false,
|
||||
showFullscreenCtrl: false,
|
||||
showZoomCtrl: false,
|
||||
hotSpotDebug: false,
|
||||
backgroundColor: [0, 0, 0],
|
||||
orientationOnByDefault: false
|
||||
});
|
||||
|
||||
// 뷰어 로드 완료 이벤트
|
||||
currentPanoramaViewer.on('load', function() {
|
||||
console.log('Pannellum 360도 뷰어 로드 완료');
|
||||
});
|
||||
}
|
||||
|
||||
function closePannellumModal() {
|
||||
const modal = document.getElementById('pannellum-modal');
|
||||
const autoBtn = document.getElementById('pannellum-auto-btn');
|
||||
|
||||
// 자동 회전 정지
|
||||
if (autoBtn.classList.contains('active')) {
|
||||
autoBtn.click();
|
||||
}
|
||||
|
||||
// 뷰어 정리
|
||||
if (currentPanoramaViewer) {
|
||||
currentPanoramaViewer.destroy();
|
||||
currentPanoramaViewer = null;
|
||||
}
|
||||
|
||||
modal.classList.remove('active');
|
||||
document.body.style.overflow = '';
|
||||
|
||||
// 뷰어 컨테이너 초기화
|
||||
document.getElementById('pannellum-viewer').innerHTML = '';
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user