Zoom to Point

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Zoom to Point

Jake Ross
Hello List

I have an Enable/Kiva question. Im trying to implement a zoomable 2D canvas with a zoom to point capability.  The zoom to point is achieved by translating the CTM so the mouse point is at the origin, scaling the CTM, then translating back.  

Everything seems to work fine except for one small issue. It seems that when you're zoomed in and you change position then zoom in or out the CTM is being translated as if the mouse coordinates are in the unscaled system ( scale =1).  Ive tried scaling the event using event.scale_xy(sx,sy) but that doesnt have the desired effect. 

Attached is a demo of the problem. 
Im running Snow Leopard with EPD 5.0.0 


Any thoughts ?

Jake Ross
NM Tech
[hidden email]
[hidden email]
575-835-5994 (office)



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Zoom to Point

Jake Ross
Sorry here is the code

from enthought.traits.api import HasTraits, Instance
from enthought.traits.ui.api import View, Item
from enthought.enable.api import ComponentEditor, Component


side=20.0
nx=12
ny=12
w=nx*side
h=ny*side

class ZoomCanvas(Component):
      _current_pos=(0,0)
      _scale=1.0
      def normal_mouse_wheel(self,event):
            #in/decrement _scale
            #dont let _scale be <1
            self._scale+=event.mouse_wheel/10.0
            if self._scale<1:
                  self._scale=1

            self.request_redraw()
      def normal_mouse_move(self,event):
            #keep track of the current mouse position
            #scaling the event to self._scale does not work
            self._current_pos=(event.x,event.y)
      def draw(self,gc,view_bounds=None,mode='default'):
        gc.save_state()
 try:
#perform zoom transfom
                self._zoom_(gc)
# draw a checkerboard
self._checkerboard_(gc)

 finally:
gc.restore_state()
      def _zoom_(self,gc):
            xm=self._current_pos[0]
            ym=self._current_pos[1]

            gc.translate_ctm(xm,ym)
            gc.scale_ctm(self._scale,self._scale)
            gc.translate_ctm(-xm,-ym)

      def _checkerboard_(self,gc):
            gc.rect(0,0,w,h)
            gc.stroke_path()
            color=True
            for i in range(nx):
                  color = not color
                  for j in range(ny):
                        color=not color
                        ci=int(color)
                        gc.set_fill_color((ci,ci,ci))
                        gc.fill_rect((i*side,j*side,side,side))


class ZoomDemo(HasTraits):
      zoom_canvas=Instance(ZoomCanvas)
      def _zoom_canvas_default(self):
            return ZoomCanvas()
      def traits_view(self):
            return View(Item('zoom_canvas',show_label=False,editor=ComponentEditor()),
                        resizable=True,
                        width=600,
                        height=600)

if __name__=='__main__':
      ZoomDemo().configure_traits()

On Feb 15, 2010, at 8:40 PM, Jake Ross wrote:

Hello List

I have an Enable/Kiva question. Im trying to implement a zoomable 2D canvas with a zoom to point capability.  The zoom to point is achieved by translating the CTM so the mouse point is at the origin, scaling the CTM, then translating back.  

Everything seems to work fine except for one small issue. It seems that when you're zoomed in and you change position then zoom in or out the CTM is being translated as if the mouse coordinates are in the unscaled system ( scale =1).  Ive tried scaling the event using event.scale_xy(sx,sy) but that doesnt have the desired effect. 

Attached is a demo of the problem. 
Im running Snow Leopard with EPD 5.0.0 


Any thoughts ?

Jake Ross
NM Tech
[hidden email]
[hidden email]
575-835-5994 (office)



Jake Ross
NM Tech
[hidden email]
[hidden email]
575-835-5994 (office)



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Zoom to Point

bryce hendrix-2
Jake,

Check out the BetterZoom._zoom_in_mapper. The difference in implementation is that the BetterZoom tool changes the range on the value and index mappers rather than applying a transform on the GC. Its another level of indirection, but its much simpler.

Bryce

Jake Ross wrote:
Sorry here is the code

from enthought.traits.api import HasTraits, Instance
from enthought.traits.ui.api import View, Item
from enthought.enable.api import ComponentEditor, Component


side=20.0
nx=12
ny=12
w=nx*side
h=ny*side

class ZoomCanvas(Component):
      _current_pos=(0,0)
      _scale=1.0
      def normal_mouse_wheel(self,event):
            #in/decrement _scale
            #dont let _scale be <1
            self._scale+=event.mouse_wheel/10.0
            if self._scale<1:
                  self._scale=1

            self.request_redraw()
      def normal_mouse_move(self,event):
            #keep track of the current mouse position
            #scaling the event to self._scale does not work
            self._current_pos=(event.x,event.y)
      def draw(self,gc,view_bounds=None,mode='default'):
        gc.save_state()
 try:
#perform zoom transfom
                self._zoom_(gc)
# draw a checkerboard
self._checkerboard_(gc)

 finally:
gc.restore_state()
      def _zoom_(self,gc):
            xm=self._current_pos[0]
            ym=self._current_pos[1]

            gc.translate_ctm(xm,ym)
            gc.scale_ctm(self._scale,self._scale)
            gc.translate_ctm(-xm,-ym)

      def _checkerboard_(self,gc):
            gc.rect(0,0,w,h)
            gc.stroke_path()
            color=True
            for i in range(nx):
                  color = not color
                  for j in range(ny):
                        color=not color
                        ci=int(color)
                        gc.set_fill_color((ci,ci,ci))
                        gc.fill_rect((i*side,j*side,side,side))


class ZoomDemo(HasTraits):
      zoom_canvas=Instance(ZoomCanvas)
      def _zoom_canvas_default(self):
            return ZoomCanvas()
      def traits_view(self):
            return View(Item('zoom_canvas',show_label=False,editor=ComponentEditor()),
                        resizable=True,
                        width=600,
                        height=600)

if __name__=='__main__':
      ZoomDemo().configure_traits()

On Feb 15, 2010, at 8:40 PM, Jake Ross wrote:

Hello List

I have an Enable/Kiva question. Im trying to implement a zoomable 2D canvas with a zoom to point capability.  The zoom to point is achieved by translating the CTM so the mouse point is at the origin, scaling the CTM, then translating back.  

Everything seems to work fine except for one small issue. It seems that when you're zoomed in and you change position then zoom in or out the CTM is being translated as if the mouse coordinates are in the unscaled system ( scale =1).  Ive tried scaling the event using event.scale_xy(sx,sy) but that doesnt have the desired effect. 

Attached is a demo of the problem. 
Im running Snow Leopard with EPD 5.0.0 


Any thoughts ?

Jake Ross
NM Tech
[hidden email]
[hidden email]
575-835-5994 (office)



Jake Ross
NM Tech
[hidden email]
[hidden email]
575-835-5994 (office)



_______________________________________________ Enthought-Dev mailing list [hidden email] https://mail.enthought.com/mailman/listinfo/enthought-dev


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev
Reply | Threaded
Open this post in threaded view
|

Re: Zoom to Point

Peter Wang
In reply to this post by Jake Ross
On 2/15/10 9:40 PM, Jake Ross wrote:

> Hello List
>
> I have an Enable/Kiva question. Im trying to implement a zoomable 2D
> canvas with a zoom to point capability. The zoom to point is achieved by
> translating the CTM so the mouse point is at the origin, scaling the
> CTM, then translating back.
>
> Everything seems to work fine except for one small issue. It seems that
> when you're zoomed in and you change position then zoom in or out the
> CTM is being translated as if the mouse coordinates are in the unscaled
> system ( scale =1). Ive tried scaling the event using
> event.scale_xy(sx,sy) but that doesnt have the desired effect.
Jake,

You might want to try using the Zoom feature of Viewports.  This is, I
think, a better fit for what you are trying to do.  See that attached
example, based on a modification of your code.

-Peter


_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev

jake_zoom.py (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Zoom to Point

Jake Ross
Hi Peter

Thanks for the help.  
Your attached code provides the behavior I was looking for. 

Do you have any insight as to why my approach was not working?

I really love working with ETS and it has greatly sped development of our laboratory's code.  

Thanks,
Jake

On Feb 17, 2010, at 3:23 PM, Peter Wang wrote:

On 2/15/10 9:40 PM, Jake Ross wrote:
Hello List

I have an Enable/Kiva question. Im trying to implement a zoomable 2D
canvas with a zoom to point capability. The zoom to point is achieved by
translating the CTM so the mouse point is at the origin, scaling the
CTM, then translating back.

Everything seems to work fine except for one small issue. It seems that
when you're zoomed in and you change position then zoom in or out the
CTM is being translated as if the mouse coordinates are in the unscaled
system ( scale =1). Ive tried scaling the event using
event.scale_xy(sx,sy) but that doesnt have the desired effect.

Jake,

You might want to try using the Zoom feature of Viewports.  This is, I think, a better fit for what you are trying to do.  See that attached example, based on a modification of your code.

-Peter

<jake_zoom.py>_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev

Jake Ross
NM Tech
[hidden email]
[hidden email]
575-835-5994 (office)



_______________________________________________
Enthought-Dev mailing list
[hidden email]
https://mail.enthought.com/mailman/listinfo/enthought-dev