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

InteractiveViewer: zoom(...) ignores min_scale/max_scale, pan ignores control bounds #4642

Open
1 task done
jgersti opened this issue Jan 1, 2025 · 1 comment
Open
1 task done

Comments

@jgersti
Copy link

jgersti commented Jan 1, 2025

Duplicate Check

Describe the bug

Using the zoom(...) method ignores the zoom limits set with min_scale / max_scale.
Using pan(...) moves the content regardless of bounds.

Code sample

Code

copied from #4451

import flet as ft

def main(page: ft.Page):

    page.add(
        i := ft.InteractiveViewer(
            min_scale=0.1,
            max_scale=15,
            boundary_margin=ft.margin.all(20),
            content=ft.Image(
                src="https://picsum.photos/500/500",
            ),
        ),
        ft.Row(
            wrap=True,
            controls=[
                ft.Button("Reset", on_click=lambda e: i.reset()),
                ft.Button("Reset 10", on_click=lambda e: i.reset(2000)),
                ft.Button("Zoom In", on_click=lambda e: i.zoom(1.2)),
                ft.Button("Zoom Out", on_click=lambda e: i.zoom(0.8)),
                ft.Button("Pan", on_click=lambda e: i.pan(50, 50)),
                ft.Button("Save State", on_click=lambda e: i.save_state()),
                ft.Button("Restore State", on_click=lambda e: i.restore_state()),
            ],
        ),
    )

ft.app(target=main)

To reproduce

  1. Repeatedly click the either "Zoom In", "Zoom Out", or "Pan"
  2. Observe infinite pan and zoom.

Expected behavior

  • Values for min_scale and max_scale are honored.
  • Panning and Zooming behave the same programmatically and interactivly (e.g. mouse interactions)

Operating System

Windows

Flet version

25.2

Regression

No, it isn't

@jgersti
Copy link
Author

jgersti commented Jan 3, 2025

The proper behavior for these operations is implemented in the in class _InteractiveViewerState methods _matrixScale(...) and _matrixTranslate(...). Unfortunately these are all private.

As quite a few people stated in various flutter github issues: the sanest way to work with with InteractiveViewer (flutter widget) is to copy the code and fix the shortcomings yourself, especially because the implementation is needlessly complicated.

Currently the Matrix4 object will only ever have 6 values that are not zero. The first three entries of the diagonal are the same and represent the current scale level, the fourth is always 1, the first and second value of the last row contain the x resp. y translation. (Note: this representation of a affine transformation is transposed to the one usually found in math text books / Wikipedia.)

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

No branches or pull requests

1 participant