Enforce minimum zoom so page always fills viewport
Dynamic min zoom computed from page and view dimensions — page can never be smaller than the visible area. Combined with pan clamping from previous commit, the page always covers the full canvas with no non-drawable area visible. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -93,7 +93,7 @@ class PadCanvasView(context: Context) : View(context) {
|
||||
object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
|
||||
override fun onScale(detector: ScaleGestureDetector): Boolean {
|
||||
val newZoom = (zoom * detector.scaleFactor)
|
||||
.coerceIn(CanvasState.MIN_ZOOM, CanvasState.MAX_ZOOM)
|
||||
.coerceIn(minZoom(), CanvasState.MAX_ZOOM)
|
||||
if (newZoom != zoom) {
|
||||
val focusX = detector.focusX
|
||||
val focusY = detector.focusY
|
||||
@@ -639,6 +639,23 @@ class PadCanvasView(context: Context) : View(context) {
|
||||
|
||||
// --- Coordinate transforms ---
|
||||
|
||||
/**
|
||||
* Minimum zoom so the page always fills the viewport.
|
||||
* At fitScale (zoom=1), the page fills the screen width.
|
||||
* We need both dimensions covered, so min zoom = max(1, viewH/(pageH*fitScale)).
|
||||
*/
|
||||
private fun minZoom(): Float {
|
||||
val pageW = canvasState.pageSize.widthPt.toFloat()
|
||||
val pageH = canvasState.pageSize.heightPt.toFloat()
|
||||
val viewW = width.toFloat().coerceAtLeast(1f)
|
||||
val viewH = height.toFloat().coerceAtLeast(1f)
|
||||
val fitScale = viewW / pageW
|
||||
// Page must fill both dimensions
|
||||
val minForWidth = 1f // zoom=1 means page width = view width
|
||||
val minForHeight = viewH / (pageH * fitScale)
|
||||
return maxOf(minForWidth, minForHeight)
|
||||
}
|
||||
|
||||
private fun rebuildViewMatrix() {
|
||||
viewMatrix.reset()
|
||||
val pageW = canvasState.pageSize.widthPt.toFloat()
|
||||
|
||||
Reference in New Issue
Block a user