Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to Set a Minimum Scale #71

Open
LOOHP opened this issue Jan 1, 2025 · 10 comments
Open

Option to Set a Minimum Scale #71

LOOHP opened this issue Jan 1, 2025 · 10 comments
Labels
enhancement New feature or request

Comments

@LOOHP
Copy link

LOOHP commented Jan 1, 2025

It would be great if an option is available to set the minimum scale the image. (So that you can restrict users from zooming out all the way)

@LOOHP LOOHP added the enhancement New feature or request label Jan 1, 2025
@panpf
Copy link
Owner

panpf commented Jan 1, 2025

By default, the minimum scale is calculated based on the image size, container size, and contentScale, but you can fully customize minScale, mediumScale, and maxScale through ScalesCalculator. Please refer to the documentation and the existing implementation of ScalesCalculator
https://github.com/panpf/zoomimage/blob/main/docs/wiki/scale.md#scalescalculator

@LOOHP
Copy link
Author

LOOHP commented Jan 1, 2025

I tried to create a custom implementation of ScalesCalculator that directly returns hardcoded values for minScale, mediumScale, and maxScale. For reference, here's the implementation:

data class PredefinedScalesCalculator(
    val minScale: Float,
    val mediumScale: Float,
    val maxScale: Float
): ScalesCalculator {

    override fun calculate(
        containerSize: IntSizeCompat,
        contentSize: IntSizeCompat,
        contentOriginSize: IntSizeCompat,
        contentScale: ContentScaleCompat,
        minScale: Float,
        initialScale: Float
    ): ScalesCalculator.Result {
        return ScalesCalculator.Result(
            minScale = this.minScale,
            mediumScale = this.mediumScale,
            maxScale = this.maxScale
        )
    }

}

However, I found that only the mediumScale and maxScale are respected when zooming (or double-clicking). The user can always zoom all the way out and double-clicking's minScale is always all the way out too.

@panpf
Copy link
Owner

panpf commented Jan 2, 2025

@panpf
Copy link
Owner

panpf commented Jan 2, 2025

@LOOHP
Copy link
Author

LOOHP commented Jan 2, 2025

I did have rubberBandScale and threeStepScale enabled. It's just that the minScale that it uses is not the minScale that I've set in the ScaleCalculator but the smallest possible fit of the image to the container area.

@panpf
Copy link
Owner

panpf commented Jan 2, 2025

Yes, the minScale returned by ScalesCalculator is not used. This is because minScale should usually always be determined by contentScale and keep it consistent with the initial zoom factor. Otherwise, when you double-click to cycle zoom, you will never be able to return to the initial zoom factor, which violates user intuition.

Can you explain in detail why you need to modify minScale? I'll consider whether there are other ways to achieve your goal.

return floatArrayOf(minScale, result.mediumScale, result.maxScale)

@LOOHP
Copy link
Author

LOOHP commented Jan 2, 2025

Since I'm trying to show a metro map. The initial zoom is set to a size that makes the map readable. Zooming all the way out does not make any sense as the map and the stations would be so tiny especially if your screen is in portrait mode.

@panpf
Copy link
Owner

panpf commented Jan 2, 2025

Don't use Fit for your contentScale, use None, and set rubberBandScale to false

@LOOHP
Copy link
Author

LOOHP commented Jan 2, 2025

Thanks for the suggestion, in kinda works. Although it is still not the best as it would be you can't zoom out more than the initial scale. Although the map is not readable at the smallest possible scale, allowing the user to zoom out just a little bit from the initial scale is still desirable.

Sorry for nitpicking on the library haha, make no mistake it is already great!

@panpf
Copy link
Owner

panpf commented Jan 2, 2025

I understand that you only want to zoom in and not zoom out, so I let you use None, which will not do any scaling on the image. When rubberBandScale is false, you can only zoom in.

If I understand it wrongly, please explain the requirements in more detail or give a demonstration video.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants