Update index.html
Browse files- index.html +73 -10
index.html
CHANGED
@@ -325,6 +325,9 @@
|
|
325 |
const scales = [2500, 5000, 10000, 25000, 50000];
|
326 |
let currentScaleIndex = 1; // 기본 1:5000
|
327 |
let currentScale = scales[currentScaleIndex];
|
|
|
|
|
|
|
328 |
|
329 |
// 지형 데이터를 저장할 변수들
|
330 |
let heightMap = [];
|
@@ -337,6 +340,9 @@
|
|
337 |
let showRivers = true;
|
338 |
let terrainType = 'mountain';
|
339 |
let seed = Math.random() * 10000;
|
|
|
|
|
|
|
340 |
|
341 |
// 개선된 노이즈 함수
|
342 |
function noise(x, y, scale, octaves, seed) {
|
@@ -595,6 +601,12 @@
|
|
595 |
function drawMap() {
|
596 |
ctx.clearRect(0, 0, WIDTH, HEIGHT);
|
597 |
|
|
|
|
|
|
|
|
|
|
|
|
|
598 |
const gridSize = heightMap.length;
|
599 |
const cellWidth = WIDTH / gridSize;
|
600 |
const cellHeight = HEIGHT / gridSize;
|
@@ -742,6 +754,7 @@
|
|
742 |
});
|
743 |
|
744 |
// 축척 막대 그리기
|
|
|
745 |
drawScaleBar();
|
746 |
}
|
747 |
|
@@ -840,8 +853,19 @@
|
|
840 |
// 마우스 이벤트
|
841 |
canvas.addEventListener('mousemove', (e) => {
|
842 |
const rect = canvas.getBoundingClientRect();
|
843 |
-
|
844 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
845 |
|
846 |
const gridSize = heightMap.length;
|
847 |
const gridX = Math.floor(x / (WIDTH / gridSize));
|
@@ -859,9 +883,11 @@
|
|
859 |
slope = Math.round(Math.sqrt(dx * dx + dy * dy) * 100);
|
860 |
}
|
861 |
|
862 |
-
// 실제 거리 계산
|
863 |
-
const
|
864 |
-
const
|
|
|
|
|
865 |
|
866 |
document.getElementById('coordinates').textContent = `${gridX}, ${gridY}`;
|
867 |
document.getElementById('elevation').textContent = `${elevation}m`;
|
@@ -875,7 +901,24 @@
|
|
875 |
}
|
876 |
});
|
877 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
878 |
canvas.addEventListener('mouseleave', () => {
|
|
|
|
|
879 |
tooltip.style.display = 'none';
|
880 |
document.getElementById('coordinates').textContent = '-';
|
881 |
document.getElementById('elevation').textContent = '-';
|
@@ -883,6 +926,19 @@
|
|
883 |
document.getElementById('realDistance').textContent = '-';
|
884 |
});
|
885 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
886 |
// 컨트롤 함수들
|
887 |
function generateNewTerrain() {
|
888 |
generateTerrain();
|
@@ -919,6 +975,9 @@
|
|
919 |
if (currentScaleIndex > 0) {
|
920 |
currentScaleIndex--;
|
921 |
currentScale = scales[currentScaleIndex];
|
|
|
|
|
|
|
922 |
updateScaleInfo();
|
923 |
drawMap();
|
924 |
}
|
@@ -928,24 +987,28 @@
|
|
928 |
if (currentScaleIndex < scales.length - 1) {
|
929 |
currentScaleIndex++;
|
930 |
currentScale = scales[currentScaleIndex];
|
|
|
|
|
|
|
931 |
updateScaleInfo();
|
932 |
drawMap();
|
933 |
}
|
934 |
}
|
935 |
|
936 |
function updateScaleInfo() {
|
937 |
-
|
|
|
938 |
|
939 |
-
// 지도 전체 크기 계산
|
940 |
-
const widthKm = (WIDTH *
|
941 |
-
const heightKm = (HEIGHT *
|
942 |
|
943 |
// 최대 20km x 15km 제한
|
944 |
const actualWidthKm = Math.min(20, widthKm);
|
945 |
const actualHeightKm = Math.min(15, heightKm);
|
946 |
|
947 |
document.getElementById('mapSizeInfo').textContent =
|
948 |
-
`지도 범위: ${actualWidthKm}km × ${actualHeightKm}km`;
|
949 |
}
|
950 |
|
951 |
function exportMap() {
|
|
|
325 |
const scales = [2500, 5000, 10000, 25000, 50000];
|
326 |
let currentScaleIndex = 1; // 기본 1:5000
|
327 |
let currentScale = scales[currentScaleIndex];
|
328 |
+
let zoomLevel = 1; // 줌 레벨 (0.5 ~ 4)
|
329 |
+
let offsetX = 0; // 뷰포트 오프셋
|
330 |
+
let offsetY = 0;
|
331 |
|
332 |
// 지형 데이터를 저장할 변수들
|
333 |
let heightMap = [];
|
|
|
340 |
let showRivers = true;
|
341 |
let terrainType = 'mountain';
|
342 |
let seed = Math.random() * 10000;
|
343 |
+
let isDragging = false;
|
344 |
+
let dragStartX = 0;
|
345 |
+
let dragStartY = 0;
|
346 |
|
347 |
// 개선된 노이즈 함수
|
348 |
function noise(x, y, scale, octaves, seed) {
|
|
|
601 |
function drawMap() {
|
602 |
ctx.clearRect(0, 0, WIDTH, HEIGHT);
|
603 |
|
604 |
+
// 줌과 오프셋 적용
|
605 |
+
ctx.save();
|
606 |
+
ctx.translate(WIDTH/2, HEIGHT/2);
|
607 |
+
ctx.scale(zoomLevel, zoomLevel);
|
608 |
+
ctx.translate(-WIDTH/2 + offsetX, -HEIGHT/2 + offsetY);
|
609 |
+
|
610 |
const gridSize = heightMap.length;
|
611 |
const cellWidth = WIDTH / gridSize;
|
612 |
const cellHeight = HEIGHT / gridSize;
|
|
|
754 |
});
|
755 |
|
756 |
// 축척 막대 그리기
|
757 |
+
ctx.restore(); // 줌 효과 제거 후 축척 막대 그리기
|
758 |
drawScaleBar();
|
759 |
}
|
760 |
|
|
|
853 |
// 마우스 이벤트
|
854 |
canvas.addEventListener('mousemove', (e) => {
|
855 |
const rect = canvas.getBoundingClientRect();
|
856 |
+
|
857 |
+
if (isDragging) {
|
858 |
+
const dx = e.clientX - dragStartX;
|
859 |
+
const dy = e.clientY - dragStartY;
|
860 |
+
offsetX = dx / zoomLevel;
|
861 |
+
offsetY = dy / zoomLevel;
|
862 |
+
drawMap();
|
863 |
+
return;
|
864 |
+
}
|
865 |
+
|
866 |
+
// 줌을 고려한 마우스 좌표 계산
|
867 |
+
const x = ((e.clientX - rect.left) * (WIDTH / rect.width) - WIDTH/2) / zoomLevel + WIDTH/2 - offsetX;
|
868 |
+
const y = ((e.clientY - rect.top) * (HEIGHT / rect.height) - HEIGHT/2) / zoomLevel + HEIGHT/2 - offsetY;
|
869 |
|
870 |
const gridSize = heightMap.length;
|
871 |
const gridX = Math.floor(x / (WIDTH / gridSize));
|
|
|
883 |
slope = Math.round(Math.sqrt(dx * dx + dy * dy) * 100);
|
884 |
}
|
885 |
|
886 |
+
// 실제 거리 계산 (줌 레벨 고려)
|
887 |
+
const mapWidthKm = (WIDTH * currentScale / zoomLevel) / 1000000;
|
888 |
+
const mapHeightKm = (HEIGHT * currentScale / zoomLevel) / 1000000;
|
889 |
+
const realX = (gridX * mapWidthKm / gridSize).toFixed(2);
|
890 |
+
const realY = (gridY * mapHeightKm / gridSize).toFixed(2);
|
891 |
|
892 |
document.getElementById('coordinates').textContent = `${gridX}, ${gridY}`;
|
893 |
document.getElementById('elevation').textContent = `${elevation}m`;
|
|
|
901 |
}
|
902 |
});
|
903 |
|
904 |
+
// 드래그 이벤트
|
905 |
+
canvas.addEventListener('mousedown', (e) => {
|
906 |
+
if (e.button === 0) { // 왼쪽 버튼
|
907 |
+
isDragging = true;
|
908 |
+
dragStartX = e.clientX - offsetX * zoomLevel;
|
909 |
+
dragStartY = e.clientY - offsetY * zoomLevel;
|
910 |
+
canvas.style.cursor = 'grabbing';
|
911 |
+
}
|
912 |
+
});
|
913 |
+
|
914 |
+
canvas.addEventListener('mouseup', () => {
|
915 |
+
isDragging = false;
|
916 |
+
canvas.style.cursor = 'crosshair';
|
917 |
+
});
|
918 |
+
|
919 |
canvas.addEventListener('mouseleave', () => {
|
920 |
+
isDragging = false;
|
921 |
+
canvas.style.cursor = 'crosshair';
|
922 |
tooltip.style.display = 'none';
|
923 |
document.getElementById('coordinates').textContent = '-';
|
924 |
document.getElementById('elevation').textContent = '-';
|
|
|
926 |
document.getElementById('realDistance').textContent = '-';
|
927 |
});
|
928 |
|
929 |
+
// 마우스 휠 줌
|
930 |
+
canvas.addEventListener('wheel', (e) => {
|
931 |
+
e.preventDefault();
|
932 |
+
const delta = e.deltaY > 0 ? 0.9 : 1.1;
|
933 |
+
const newZoom = zoomLevel * delta;
|
934 |
+
|
935 |
+
if (newZoom >= 0.5 && newZoom <= 4) {
|
936 |
+
zoomLevel = newZoom;
|
937 |
+
updateScaleInfo();
|
938 |
+
drawMap();
|
939 |
+
}
|
940 |
+
});
|
941 |
+
|
942 |
// 컨트롤 함수들
|
943 |
function generateNewTerrain() {
|
944 |
generateTerrain();
|
|
|
975 |
if (currentScaleIndex > 0) {
|
976 |
currentScaleIndex--;
|
977 |
currentScale = scales[currentScaleIndex];
|
978 |
+
zoomLevel = Math.min(4, zoomLevel * 1.5);
|
979 |
+
offsetX = 0;
|
980 |
+
offsetY = 0;
|
981 |
updateScaleInfo();
|
982 |
drawMap();
|
983 |
}
|
|
|
987 |
if (currentScaleIndex < scales.length - 1) {
|
988 |
currentScaleIndex++;
|
989 |
currentScale = scales[currentScaleIndex];
|
990 |
+
zoomLevel = Math.max(0.5, zoomLevel / 1.5);
|
991 |
+
offsetX = 0;
|
992 |
+
offsetY = 0;
|
993 |
updateScaleInfo();
|
994 |
drawMap();
|
995 |
}
|
996 |
}
|
997 |
|
998 |
function updateScaleInfo() {
|
999 |
+
const effectiveScale = currentScale / zoomLevel;
|
1000 |
+
document.getElementById('scaleInfo').textContent = `1:${Math.round(effectiveScale)}`;
|
1001 |
|
1002 |
+
// 지도 전체 크기 계산 (줌 고려)
|
1003 |
+
const widthKm = (WIDTH * effectiveScale / 1000000).toFixed(1);
|
1004 |
+
const heightKm = (HEIGHT * effectiveScale / 1000000).toFixed(1);
|
1005 |
|
1006 |
// 최대 20km x 15km 제한
|
1007 |
const actualWidthKm = Math.min(20, widthKm);
|
1008 |
const actualHeightKm = Math.min(15, heightKm);
|
1009 |
|
1010 |
document.getElementById('mapSizeInfo').textContent =
|
1011 |
+
`지도 범위: ${actualWidthKm}km × ${actualHeightKm}km (줌: ${(zoomLevel * 100).toFixed(0)}%)`;
|
1012 |
}
|
1013 |
|
1014 |
function exportMap() {
|