title: Removing Effect Of tkinter canvas.scan_mark on mouse coordinates
body: <p>I'm developing a GUI with python using tkinter. I've written the code for providing zooming functionalities such as "zoom in", "zoom out", "window zoom", "previous zoom", "restore full zoom" and, finally, "pan". For 'pan' command I used canvas.scan_mark() and canvas.scan_dragto() methods. All the mentioned commands work fine except that when I press 'pan' and then 'window zoom' or try to draw selection rectangle, where I find, unexpectedly, that the window zoom or selection rectangles are shifted from the current mouse position by the shift value of pan command, although I unbound all the mouse events at the end of the 'pan' command.
  I tried something like <code>xi, yi = canvas.xview()[0], canvas.yview()[0]</code> and then 
  <code>canvas.xview_moveto(xi), canvas.yview_moveto(yi)</code>. It gets the canvas view back to its orginal position but has not solved the problem. In addition, it disturbs the 'Restore full zoom' and 'zoom previous' commands.
  Please help me fixing this problem up.</p>
  
  <p>Many thanks.</p>
  
  <p>For short description of the problem, please see the code below. It's not what I'm using in my program, but it describe the problem. Try to press the zoom button first and pan. Give it another trial by pressing pan button first followed by zoom one and see the difference. </p>
  
  <pre><code>from tkinter import *
  
  root = Tk()
  root.resizable(False, False)
  frame = Frame(root)
  frame.pack(expand=YES, fill=BOTH)
  
  canv = Canvas(frame, bg='white', width=800, height=600)
  canv.pack(side=TOP, expand=YES, fill=BOTH)
  canv.create_rectangle(100,100,200,200, fill='red', width=3)
  canv.create_oval(250,250,450,450, fill='blue', width=3)
  
  canv.create_line(500,500,500,500, fill='white')
  
  def pan():
      canv.bind('&lt;Button-1&gt;', startpan)
      canv.bind('&lt;B1-Motion&gt;', dragpan)
      canv.bind('&lt;ButtonRelease-1&gt;', endpan)
      canv.config(cursor='hand1')
  
  def startpan(event):
      canv.scan_mark(event.x, event.y)
  
  def dragpan(event):
      canv.scan_dragto(event.x, event.y, 1)
  
  def endpan(event):
      unbind_events()
  
  def unbind_events():
      canv.unbind('&lt;Button-1&gt;')
      canv.unbind('&lt;B1-Motion&gt;')
      canv.unbind('&lt;ButtonRelease-1&gt;')
      canv.config(cursor='arrow')
  
  def zoom_window():
      canv.bind('&lt;Button-1&gt;', startzoomwindow)
      canv.bind('&lt;B1-Motion&gt;', dragzoomwindow)
      canv.bind('&lt;ButtonRelease-1&gt;', endzoomwindow)
  
  def startzoomwindow(event):
      global x1, y1
      x1, y1 = event.x, event.y
  
  def dragzoomwindow(event):
      global rect
      x2, y2 = event.x, event.y
      rect = canv.create_rectangle(x1, y1, x2, y2, width=2, outline='red')
      canv.delete(canv.find_below(rect))
  
  def endzoomwindow(event):
      canv.delete(rect)
      x, y =  0.5 * (x1 + event.x), 0.5 * (y1 + event.y)
      rect_width = abs(event.x - x1)
      rect_height = abs(event.y - y1)
      canvwidth = canv.winfo_width() 
      canvheight = canv.winfo_height()
      factor = min(canvwidth / rect_width, canvheight / rect_height)
      canv.scale(ALL, x, y, factor, factor)
      unbind_events()
  
  butnframe = Frame(frame)
  butnframe.pack(side=TOP, expand=YES, fill=X)
  Button(butnframe, text='Zoom Window', command=zoom_window).pack(side=LEFT)
  Button(butnframe, text='Pan', command=pan).pack(side=RIGHT)
  </code></pre>