Files
sam-kd/filedrive/view_tmpimg.php

324 lines
10 KiB
PHP
Raw Normal View History

<?php
$img = isset($_GET['img']) ? $_GET['img'] : '';
$rotation = isset($_GET['rotation']) ? intval($_GET['rotation']) : 0;
// 보안: tmpimg 경로만 허용
if (strpos($img, '/tmpimg/') !== 0) {
die('잘못된 접근');
}
?>
<!DOCTYPE html>
<html>
<head>
<title>이미지 보기</title>
<style>
body, html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: #000;
cursor: pointer;
}
.image-container {
width: 100vw;
height: 100vh;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
.image-container img {
max-width: none;
max-height: none;
width: auto;
height: auto;
display: block;
transform: rotate(<?php echo $rotation; ?>deg);
object-fit: contain;
transition: transform 0.3s ease;
cursor: move;
}
.close-button {
position: fixed;
top: 20px;
right: 20px;
background: rgba(0, 0, 0, 0.7);
color: white;
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
font-size: 20px;
cursor: pointer;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
}
.close-button:hover {
background: rgba(0, 0, 0, 0.9);
}
.zoom-controls {
position: fixed;
top: 20px;
left: 20px;
display: flex;
gap: 10px;
z-index: 1000;
}
.zoom-button {
background: rgba(0, 0, 0, 0.7);
color: white;
border: none;
border-radius: 50%;
width: 40px;
height: 40px;
font-size: 18px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.3s ease;
}
.zoom-button:hover {
background: rgba(0, 0, 0, 0.9);
}
.zoom-button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.reset-button {
background: rgba(0, 0, 0, 0.7);
color: white;
border: none;
border-radius: 20px;
padding: 8px 16px;
font-size: 14px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.3s ease;
}
.reset-button:hover {
background: rgba(0, 0, 0, 0.9);
}
.loading {
color: white;
font-size: 18px;
text-align: center;
}
.error {
color: #ff6b6b;
font-size: 18px;
text-align: center;
padding: 20px;
}
.zoom-info {
position: fixed;
bottom: 20px;
left: 20px;
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 8px 12px;
border-radius: 20px;
font-size: 14px;
z-index: 1000;
}
</style>
</head>
<body>
<button class="close-button" onclick="closeWindow()" title="닫기 (ESC)">×</button>
<div class="zoom-controls">
<button class="zoom-button" onclick="zoomIn()" title="확대 (Ctrl + +)">+</button>
<button class="zoom-button" onclick="zoomOut()" title="축소 (Ctrl + -)"></button>
<button class="reset-button" onclick="resetZoom()" title="원본 크기 (Ctrl + 0)">원본</button>
</div>
<div class="zoom-info" id="zoomInfo">100%</div>
<div class="image-container">
<img src="<?php echo htmlspecialchars($img); ?>" alt="이미지" id="popupImage" style="display: none;">
<div id="loadingMessage" class="loading">이미지를 불러오는 ...</div>
<div id="errorMessage" class="error" style="display: none;">이미지를 불러올 없습니다.</div>
</div>
<script>
let currentZoom = 1;
let isDragging = false;
let startX, startY, translateX = 0, translateY = 0;
const MIN_ZOOM = 0.1;
const MAX_ZOOM = 5;
const ZOOM_STEP = 0.2;
// 창 닫기 함수
function closeWindow() {
window.close();
}
// 줌 인
function zoomIn() {
if (currentZoom < MAX_ZOOM) {
currentZoom = Math.min(currentZoom + ZOOM_STEP, MAX_ZOOM);
updateZoom();
}
}
// 줌 아웃
function zoomOut() {
if (currentZoom > MIN_ZOOM) {
currentZoom = Math.max(currentZoom - ZOOM_STEP, MIN_ZOOM);
updateZoom();
}
}
// 줌 리셋
function resetZoom() {
currentZoom = 1;
translateX = 0;
translateY = 0;
updateZoom();
}
// 줌 업데이트
function updateZoom() {
const img = document.getElementById('popupImage');
const zoomInfo = document.getElementById('zoomInfo');
const zoomInBtn = document.querySelector('.zoom-button:first-child');
const zoomOutBtn = document.querySelector('.zoom-button:nth-child(2)');
// 회전, 확대/축소, 이동을 모두 적용
img.style.transform = `rotate(<?php echo $rotation; ?>deg) scale(${currentZoom}) translate(${translateX}px, ${translateY}px)`;
zoomInfo.textContent = Math.round(currentZoom * 100) + '%';
// 버튼 활성화/비활성화
zoomInBtn.disabled = currentZoom >= MAX_ZOOM;
zoomOutBtn.disabled = currentZoom <= MIN_ZOOM;
}
// 마우스 드래그 시작
function startDrag(e) {
if (currentZoom > 1) {
isDragging = true;
startX = e.clientX - translateX;
startY = e.clientY - translateY;
document.body.style.cursor = 'grabbing';
e.preventDefault();
}
}
// 마우스 드래그 중
function drag(e) {
if (isDragging) {
translateX = e.clientX - startX;
translateY = e.clientY - startY;
updateZoom();
e.preventDefault();
}
}
// 마우스 드래그 종료
function endDrag() {
isDragging = false;
document.body.style.cursor = 'pointer';
}
// 이미지 로딩이 완료되면 실행될 함수
function onImageLoad() {
// 로딩 메시지 숨기기
document.getElementById('loadingMessage').style.display = 'none';
// 이미지 표시
document.getElementById('popupImage').style.display = 'block';
// 이 창을 연 부모 창(opener)이 있고, 닫히지 않았는지 확인
if (window.opener && !window.opener.closed) {
// 부모 창에 hideImageLoadingModal 함수가 있는지 확인하고 호출
if (typeof window.opener.hideImageLoadingModal === 'function') {
window.opener.hideImageLoadingModal();
}
}
}
// 이미지 로딩 실패 시 실행될 함수
function onImageError() {
// 로딩 메시지 숨기기
document.getElementById('loadingMessage').style.display = 'none';
// 에러 메시지 표시
document.getElementById('errorMessage').style.display = 'block';
// 부모 창의 로딩 모달도 숨기기
if (window.opener && !window.opener.closed) {
if (typeof window.opener.hideImageLoadingModal === 'function') {
window.opener.hideImageLoadingModal();
}
}
}
const imgElement = document.getElementById('popupImage');
// 이미지의 load 이벤트에 리스너 추가
imgElement.addEventListener('load', onImageLoad);
imgElement.addEventListener('error', onImageError);
// 만약 이미지가 이미 캐시되어 있다면 'load' 이벤트가 발생하지 않을 수 있으므로,
// complete 속성을 확인하여 수동으로 함수를 호출합니다.
if (imgElement.complete) {
if (imgElement.naturalWidth > 0) {
onImageLoad();
} else {
onImageError();
}
}
// 마우스 이벤트 리스너 추가
imgElement.addEventListener('mousedown', startDrag);
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', endDrag);
// 휠 줌 기능 (이미지 위에서만)
imgElement.addEventListener('wheel', function(e) {
e.preventDefault();
if (e.deltaY < 0) {
zoomIn();
} else {
zoomOut();
}
});
// 키보드 단축키
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
closeWindow();
} else if (event.ctrlKey || event.metaKey) {
switch(event.key) {
case '=':
case '+':
event.preventDefault();
zoomIn();
break;
case '-':
event.preventDefault();
zoomOut();
break;
case '0':
event.preventDefault();
resetZoom();
break;
}
}
});
// 배경 클릭으로 창 닫기 (줌이 1일 때만)
document.addEventListener('click', function(event) {
if (currentZoom <= 1 && (event.target === document.body || event.target.classList.contains('image-container'))) {
closeWindow();
}
});
</script>
</body>
</html>