Skip to content Skip to sidebar Skip to footer

Kivy: Scroll To Zoom

Is there a way to zoom into an image on a desktop kivy app (e.g. zoom with a mouse scroll-wheel)? It appears to be discussed here: https://github.com/kivy/kivy/issues/3563 but I do

Solution 1:

To achieve my goal, I used a combination of the information in kivy python3 detect mousewheel, as pointed out ikolim, and the code given here: https://github.com/kivy/kivy/wiki/Draggable-Scalable-Button

To keep my answer brief, here's the minimalistic object that extends Scatter object.

classResizableDraggablePicture(Scatter):
    defon_touch_down(self, touch):
        # Override Scatter's `on_touch_down` behavior for mouse scrollif touch.is_mouse_scrolling:
            if touch.button == 'scrolldown':
                if self.scale < 10:
                    self.scale = self.scale * 1.1elif touch.button == 'scrollup':
                if self.scale > 1:
                    self.scale = self.scale * 0.8# If some other kind of "touch": Fall back on Scatter's behaviorelse:
            super(ResizableDraggablePicture, self).on_touch_down(touch)

The layout is slightly different and I changed the text on the button, but the functionality of my code can be seen in the following gif:

demo of zooming and panning

For anybody wanting to see my entire toy project to adapt for their own purposes, the entire code is on my github: https://github.com/melissadale/Learning-Kivy/tree/master/ZoomPanning

UPDATE my code has been edited to be far more correct from an object-orientated approach, and so I could not reject the edits with a clear conscience. However, when I was first starting with kivy, I would have found this code confusing. If you want to just see the simple version that you can apply directly to verify the relevant, this is my original code:

if touch.is_mouse_scrolling:
    if touch.button == 'scrolldown':
        print('down')
        ## zoom inif self.scale < 10:
            self.scale = self.scale * 1.1elif touch.button == 'scrollup':
        ## zoom outprint('up')
        if self.scale > 1:
            self.scale = self.scale * 0.8

Solution 2:

The other answer by @mdoc-2011 has the problem that it doesn't anchor onto the mouse pointer, meaning that it is quite annoying to use, since the content will scroll around a lot. This can be fixed by not using the .scale property and instead directly calling apply_transform:

if touch.is_mouse_scrolling:
    factor = Noneif touch.button == 'scrolldown':
        if self.scale < self.scale_max:
            factor = 1.1elif touch.button == 'scrollup':
        if self.scale > self.scale_min:
            factor = 1 / 1.1if factor isnotNone:
        self.apply_transform(Matrix().scale(factor, factor, factor),
                             anchor=touch.pos)

This version also uses the.scale_(min/max) properties, and instead of 1.1 and 0.8 uses 1/1.1 which will make it more intuitive to scroll in an out.

Post a Comment for "Kivy: Scroll To Zoom"