Files
sam-kd/draw/index4.html
hskwon aca1767eb9 초기 커밋: 5130 레거시 시스템
- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경
- DB 연결 하드코딩 → .env 기반으로 변경
- MySQL strict mode DATE 오류 수정
2025-12-10 20:14:31 +09:00

246 lines
8.6 KiB
HTML

<?php
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
?>
<head>
<meta charset="UTF-8">
<title>이미지 에디터 통합 예제</title>
<style>
body { padding: 1rem; }
dialog {
width: 800px; height: 600px;
border: none; border-radius: .5rem;
padding: 0; overflow: hidden;
}
dialog::backdrop { background: rgba(0,0,0,.5); }
#editorHeader {
background: #f8f9fa; padding: .5rem 1rem;
border-bottom: 1px solid #dee2e6;
display: flex; align-items: center;
}
#editorHeader h5 { margin: 0; flex-grow: 1; }
#editorHeader .btn-close { margin-left: .5rem; }
#editorToolbar, #editorToolbar2 {
background: #fff;
padding: .5rem; gap: .25rem;
}
#editorToolbar { display: flex; align-items: center; flex-wrap: wrap; }
#editorToolbar2 { display: flex; align-items: center; }
.toolbar-btn { width: 40px; height: 40px; padding: 0; }
.toolbar-btn i { font-size: 1.2rem; }
.toolbar-btn.active { background-color: #0d6efd; color: #fff; }
.color-btn { width: 24px; height: 24px; padding: 0; border: 2px solid #fff; cursor: pointer; }
.color-btn.active { border-color: #000; }
#editorBody { position: relative; width: 100%; height: calc(100% - 128px); }
#editorBody canvas { width: 100%; height: 100%; cursor: crosshair; }
.canvas-text-input {
position: absolute;
border: 1px dashed #666;
background: transparent;
resize: none;
outline: none;
padding: 2px;
font-family: sans-serif;
}
/* 이미지 컨테이너 스타일 */
.image-container {
position: relative;
display: inline-block;
}
.paste-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 123, 255, 0.8);
color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 0.375rem;
font-size: 0.875rem;
opacity: 0;
transition: opacity 0.2s;
}
.paste-overlay.show {
opacity: 1;
}
.paste-overlay i {
font-size: 2rem;
margin-bottom: 0.5rem;
}
</style>
</head>
<body>
<!-- 편집 대상 이미지 -->
<div class="image-container mb-3">
<img id="targetImage"
src="/guiderail/images/2025_07_16_15_53_07_drawing.png"
class="img-thumbnail"
alt="편집할 이미지"
style="max-width:400px; cursor: pointer;">
<div class="paste-overlay" style="display: none;">
<i class="bi bi-clipboard-plus"></i>
<span>Ctrl+V로 이미지 붙여넣기</span>
</div>
</div>
<!-- 에디터 열기 버튼 -->
<button id="openEditorBtn" class="btn btn-primary mb-3">
<i class="bi bi-pencil-square"></i> 그리기 시작
</button>
<!-- 다이얼로그(편집기) 마크업: imageEditor.js 호출 시 참조 -->
<dialog id="editorDialog">
<div id="editorHeader">
<h5>이미지 편집기</h5>
<button id="applyBtn" class="btn btn-success btn-sm">적용하기</button>
<button type="button" class="btn-close" aria-label="닫기" id="closeEditorBtn"></button>
</div>
<!-- 툴바 -->
<div id="editorToolbar">
<button id="polyBtn" class="btn btn-outline-primary toolbar-btn" title="폴리라인"><i class="bi bi-vector-pen"></i></button>
<button id="freeBtn" class="btn btn-outline-primary toolbar-btn" title="자유선"><i class="bi bi-brush"></i></button>
<button id="lineBtn" class="btn btn-outline-primary toolbar-btn" title="직선 (L키)"><i class="bi bi-slash-lg"></i></button>
<button id="textBtn" class="btn btn-outline-primary toolbar-btn" title="문자입력"><i class="bi bi-type"></i></button>
<button id="eraserBtn" class="btn btn-outline-warning toolbar-btn" title="지우개"><i class="bi bi-eraser-fill"></i></button>
<button id="selectBtn" class="btn btn-outline-secondary toolbar-btn" title="객체선택"><i class="bi bi-cursor-text"></i></button>
<div class="form-check form-switch ms-3">
<input class="form-check-input" type="checkbox" id="rightAngle" checked>
<label class="form-check-label" for="rightAngle">직각 고정</label>
</div>
<button id="clearBtn" class="btn btn-outline-danger ms-auto">전체 지우기</button>
</div>
<!-- 지우개 크기 & 색상 -->
<div id="editorToolbar2" class="d-flex align-items-center px-3 pb-2">
<div class="btn-group" role="group" id="colorPicker">
<button type="button" class="btn color-btn active" data-color="#000000" style="background:#000;"></button>
<button type="button" class="btn color-btn" data-color="#ff0000" style="background:#f00;"></button>
<button type="button" class="btn color-btn" data-color="#0000ff" style="background:#00f;"></button>
<button type="button" class="btn color-btn" data-color="#00aa00" style="background:#0a0;"></button>
<button type="button" class="btn color-btn" data-color="#ff8800" style="background:#f80;"></button>
<button type="button" class="btn color-btn" data-color="#800080" style="background:#808;"></button>
<button type="button" class="btn color-btn" data-color="#888888" style="background:#888;"></button>
</div>
<label class="mb-0 me-2">지우개 크기</label>
<input type="range" class="form-range me-2" id="eraserRange" min="5" max="100" step="1" value="20">
<span id="eraserSizeLabel" class="fw-bold">20</span>px
</div>
<!-- 캔버스 영역 -->
<div id="editorBody">
<canvas id="c" width="800" height="600"></canvas>
</div>
</dialog>
<!-- 모듈 스크립트 -->
<script type="module">
import { openImageEditor } from '/js/imageEditor.js';
const openBtn = document.getElementById('openEditorBtn');
const targetImg = document.getElementById('targetImage');
const imageContainer = document.querySelector('.image-container');
const pasteOverlay = document.querySelector('.paste-overlay');
// 붙여넣기 이벤트 처리 함수
function handlePaste(event) {
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
for (let item of items) {
if (item.type.indexOf('image') !== -1) {
const blob = item.getAsFile();
const reader = new FileReader();
reader.onload = function(e) {
targetImg.src = e.target.result;
console.log('이미지가 붙여넣기되었습니다:', e.target.result);
// 붙여넣기 성공 피드백
showPasteFeedback(true);
};
reader.readAsDataURL(blob);
event.preventDefault();
break;
}
}
}
// 붙여넣기 피드백 표시
function showPasteFeedback(success = false) {
if (success) {
pasteOverlay.innerHTML = '<i class="bi bi-check-circle"></i><span>이미지가 붙여넣기되었습니다!</span>';
pasteOverlay.style.background = 'rgba(40, 167, 69, 0.8)';
} else {
pasteOverlay.innerHTML = '<i class="bi bi-clipboard-plus"></i><span>Ctrl+V로 이미지 붙여넣기</span>';
pasteOverlay.style.background = 'rgba(0, 123, 255, 0.8)';
}
pasteOverlay.classList.add('show');
setTimeout(() => {
pasteOverlay.classList.remove('show');
}, 2000);
}
// 그리기 관련 코드
// 붙여넣기 이벤트 리스너 추가
document.addEventListener('paste', handlePaste);
// 이미지 컨테이너 클릭 시 포커스
imageContainer.addEventListener('click', () => {
imageContainer.focus();
});
// 이미지 컨테이너에 포커스 가능하도록 설정
imageContainer.tabIndex = 0;
imageContainer.title = '클릭 후 Ctrl+V로 이미지 붙여넣기';
// 포커스 시 오버레이 표시
imageContainer.addEventListener('focus', () => {
showPasteFeedback();
});
// 포커스 해제 시 오버레이 숨김
imageContainer.addEventListener('blur', () => {
pasteOverlay.classList.remove('show');
});
openBtn.addEventListener('click', () => {
const src = targetImg.src;
openImageEditor(src)
.then(newUrl => {
// 편집된 이미지를 화면에 반영
targetImg.src = newUrl;
})
.catch(err => {
// 사용자가 취소했을 때
console.log('편집 취소:', err.message);
});
});
$(document).ready(function(){
var loader = document.getElementById('loadingOverlay');
if(loader)
loader.style.display = 'none';
});
</script>
</body>
</html>