fix: 캔버스 확대 오버레이 — img 스냅샷 → 라이브 캔버스 복사
- toDataURL 대신 requestAnimationFrame으로 소스 캔버스를 실시간 복사 - 화면 90% 이내에서 최대 정수 배율로 선명하게 확대 (imageSmoothingEnabled:false) - 라이브 뷰이므로 애니메이션도 확대 창에서 실시간 반영 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -138,7 +138,7 @@
|
||||
}
|
||||
#canvas-zoom-overlay.open { display:flex; }
|
||||
#canvas-zoom-img {
|
||||
image-rendering:pixelated; max-width:90vw; max-height:90vh;
|
||||
image-rendering:pixelated;
|
||||
border:2px solid #333; border-radius:4px;
|
||||
box-shadow:0 8px 40px rgba(0,0,0,.8);
|
||||
}
|
||||
@@ -7927,31 +7927,54 @@ function mobToggleBoard(){
|
||||
(function() {
|
||||
const overlay = document.createElement('div');
|
||||
overlay.id = 'canvas-zoom-overlay';
|
||||
overlay.innerHTML = '<img id="canvas-zoom-img"><div id="canvas-zoom-hint">클릭 또는 ESC로 닫기</div>';
|
||||
const zoomCanvas = document.createElement('canvas');
|
||||
zoomCanvas.id = 'canvas-zoom-img';
|
||||
overlay.appendChild(zoomCanvas);
|
||||
const hint = document.createElement('div');
|
||||
hint.id = 'canvas-zoom-hint';
|
||||
hint.textContent = '클릭 또는 ESC로 닫기';
|
||||
overlay.appendChild(hint);
|
||||
document.body.appendChild(overlay);
|
||||
|
||||
function openZoom(canvas) {
|
||||
const img = document.getElementById('canvas-zoom-img');
|
||||
img.src = canvas.toDataURL();
|
||||
// 자연 크기의 3배, 화면 90% 이내
|
||||
const scale = Math.min(3, window.innerWidth * 0.9 / canvas.width, window.innerHeight * 0.9 / canvas.height);
|
||||
img.style.width = (canvas.width * scale) + 'px';
|
||||
img.style.height = (canvas.height * scale) + 'px';
|
||||
overlay.classList.add('open');
|
||||
let _src = null, _rafId = null;
|
||||
|
||||
function _loop() {
|
||||
if (!_src || !overlay.classList.contains('open')) return;
|
||||
const ctx = zoomCanvas.getContext('2d');
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
ctx.drawImage(_src, 0, 0, zoomCanvas.width, zoomCanvas.height);
|
||||
_rafId = requestAnimationFrame(_loop);
|
||||
}
|
||||
|
||||
function closeZoom() { overlay.classList.remove('open'); }
|
||||
function openZoom(canvas) {
|
||||
_src = canvas;
|
||||
// 화면의 90% 이내에서 최대 정수 배율
|
||||
const maxScale = Math.min(
|
||||
Math.floor(window.innerWidth * 0.9 / canvas.width),
|
||||
Math.floor(window.innerHeight * 0.9 / canvas.height)
|
||||
);
|
||||
const scale = Math.max(1, maxScale);
|
||||
zoomCanvas.width = canvas.width * scale;
|
||||
zoomCanvas.height = canvas.height * scale;
|
||||
overlay.classList.add('open');
|
||||
cancelAnimationFrame(_rafId);
|
||||
_loop();
|
||||
}
|
||||
|
||||
function closeZoom() {
|
||||
overlay.classList.remove('open');
|
||||
cancelAnimationFrame(_rafId);
|
||||
_src = null;
|
||||
}
|
||||
|
||||
overlay.addEventListener('click', closeZoom);
|
||||
document.addEventListener('keydown', e => { if (e.key === 'Escape') closeZoom(); });
|
||||
|
||||
// body 끝에서 실행되므로 DOM 이미 준비됨 — 직접 연결
|
||||
['tft-canvas', 'oled-canvas'].forEach(id => {
|
||||
const c = document.getElementById(id);
|
||||
if (c) c.addEventListener('click', () => openZoom(c));
|
||||
if (c) c.addEventListener('click', e => { e.stopPropagation(); openZoom(c); });
|
||||
});
|
||||
|
||||
// canvas가 나중에 그려질 수 있으므로 전역 노출
|
||||
window._canvasZoomOpen = openZoom;
|
||||
})();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user