Spaces:
Running
Running
Commit ·
d8a4502
1
Parent(s): a58047e
Refactor scaling logic in app.js to improve viewport calculations
Browse files- Introduced a new function `viewportMaxCornerPx()` to calculate the maximum distance from the camera to the canvas corners.
- Updated the `resize()` and `applyZoom()` functions to use the new scaling logic based on the calculated viewport dimensions and a defined base view radius.
- Added a new constant `BASE_VIEW_RADIUS_KM` for better control over scaling behavior.
app.js
CHANGED
|
@@ -23,6 +23,8 @@
|
|
| 23 |
var camCY = 0
|
| 24 |
var SCALE = 0
|
| 25 |
var zoomLevel = 1.0
|
|
|
|
|
|
|
| 26 |
/** Keeps map labels readable vs panel type (~15% bump; pair with .coastal-surveillance-sim font-size). */
|
| 27 |
var MAP_LABEL_SCALE = 1.15
|
| 28 |
|
|
@@ -373,7 +375,7 @@
|
|
| 373 |
if (px >= 100 && px <= 240) { ringInterval = nice[i]; break }
|
| 374 |
if (px < 100) ringInterval = nice[i]
|
| 375 |
}
|
| 376 |
-
var maxDist =
|
| 377 |
var maxRing = Math.ceil(maxDist / ringInterval) + 1
|
| 378 |
var fs = 12 * MAP_LABEL_SCALE / SCALE
|
| 379 |
var tw = 5 / SCALE
|
|
@@ -442,6 +444,16 @@
|
|
| 442 |
refreshSvgHitBox()
|
| 443 |
}
|
| 444 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 445 |
function resize() {
|
| 446 |
if (!svg || !wrap) return
|
| 447 |
W = wrap.clientWidth
|
|
@@ -450,7 +462,7 @@
|
|
| 450 |
svg.setAttribute('height', H)
|
| 451 |
camCX = W / 2
|
| 452 |
camCY = H * 0.9
|
| 453 |
-
SCALE =
|
| 454 |
updateWorldTransform()
|
| 455 |
if (bgSky) { bgSky.setAttribute('width', W); bgSky.setAttribute('height', camCY) }
|
| 456 |
if (bgSea) { bgSea.setAttribute('y', camCY); bgSea.setAttribute('width', W); bgSea.setAttribute('height', H - camCY) }
|
|
@@ -476,7 +488,7 @@
|
|
| 476 |
function applyZoom(delta) {
|
| 477 |
var factor = delta > 0 ? 1.12 : 1 / 1.12
|
| 478 |
zoomLevel = Math.max(0.3, Math.min(8, zoomLevel * factor))
|
| 479 |
-
SCALE =
|
| 480 |
updateWorldTransform()
|
| 481 |
scheduleZoomVisuals()
|
| 482 |
updateZoomLabel()
|
|
|
|
| 23 |
var camCY = 0
|
| 24 |
var SCALE = 0
|
| 25 |
var zoomLevel = 1.0
|
| 26 |
+
/** World km from camera to farthest canvas corner when zoom label = 100%; +/- zoom scales this radius. */
|
| 27 |
+
var BASE_VIEW_RADIUS_KM = 1.15
|
| 28 |
/** Keeps map labels readable vs panel type (~15% bump; pair with .coastal-surveillance-sim font-size). */
|
| 29 |
var MAP_LABEL_SCALE = 1.15
|
| 30 |
|
|
|
|
| 375 |
if (px >= 100 && px <= 240) { ringInterval = nice[i]; break }
|
| 376 |
if (px < 100) ringInterval = nice[i]
|
| 377 |
}
|
| 378 |
+
var maxDist = viewportMaxCornerPx() / SCALE
|
| 379 |
var maxRing = Math.ceil(maxDist / ringInterval) + 1
|
| 380 |
var fs = 12 * MAP_LABEL_SCALE / SCALE
|
| 381 |
var tw = 5 / SCALE
|
|
|
|
| 444 |
refreshSvgHitBox()
|
| 445 |
}
|
| 446 |
|
| 447 |
+
function viewportMaxCornerPx() {
|
| 448 |
+
if (W <= 0 || H <= 0) return 1
|
| 449 |
+
return Math.max(
|
| 450 |
+
Math.hypot(camCX, camCY),
|
| 451 |
+
Math.hypot(W - camCX, camCY),
|
| 452 |
+
Math.hypot(camCX, H - camCY),
|
| 453 |
+
Math.hypot(W - camCX, H - camCY)
|
| 454 |
+
)
|
| 455 |
+
}
|
| 456 |
+
|
| 457 |
function resize() {
|
| 458 |
if (!svg || !wrap) return
|
| 459 |
W = wrap.clientWidth
|
|
|
|
| 462 |
svg.setAttribute('height', H)
|
| 463 |
camCX = W / 2
|
| 464 |
camCY = H * 0.9
|
| 465 |
+
SCALE = viewportMaxCornerPx() / BASE_VIEW_RADIUS_KM * zoomLevel
|
| 466 |
updateWorldTransform()
|
| 467 |
if (bgSky) { bgSky.setAttribute('width', W); bgSky.setAttribute('height', camCY) }
|
| 468 |
if (bgSea) { bgSea.setAttribute('y', camCY); bgSea.setAttribute('width', W); bgSea.setAttribute('height', H - camCY) }
|
|
|
|
| 488 |
function applyZoom(delta) {
|
| 489 |
var factor = delta > 0 ? 1.12 : 1 / 1.12
|
| 490 |
zoomLevel = Math.max(0.3, Math.min(8, zoomLevel * factor))
|
| 491 |
+
SCALE = viewportMaxCornerPx() / BASE_VIEW_RADIUS_KM * zoomLevel
|
| 492 |
updateWorldTransform()
|
| 493 |
scheduleZoomVisuals()
|
| 494 |
updateZoomLabel()
|