title: Tkinter Canvas : Scale on moving object
body: <p>I do not know if my question is a stupid one or a tricky one.</p>
  
  <p>So, using Tkinter and Canvas, I succeed to implement a scrolling/zooming function that work perfectly, thanks to this post <a href="https://stackoverflow.com/questions/25787523/move-and-zoom-a-tkinter-canvas-with-mouse">Move and zoom a tkinter canvas with mouse</a>. I also add a binding to resize the canvas size when the window size change without trouble.</p>
  
  <p>Using <code>coords</code> and <code>after</code>, I have no trouble to move <code>object</code> around.</p>
  
  <p>The trouble came when I tried to combine everything.</p>
  
  <ul>
  <li>Moving and scrolling : no trouble </li>
  <li>Scrolling and Zooming : ok</li>
  <li>Zooming, moving and scrolling : do not work</li>
  </ul>
  
  <p>The code bellow reproduce the trouble (<code>python 2.7</code>, work on windows). For what I can see, the trouble come from the scaling, maybe caused by the change of <code>coords</code> of the objects, that induce the canvas resizing, and then disable the scaling? If it is the case, I need help to solve this issue. If it is not the case, I need help to found the issue...</p>
  
  <p>By removing/disable the line <code>self.master.after(50, self.Display)</code>, moving do no occur anymore.</p>
  
  <pre><code>import Tkinter as tk
  import math
  
  class Example:
      def __init__ (self, master):
          self.master = master
          self.interval = 0
          self.SizeX, self.SizeY = master.winfo_width(), master.winfo_height()
          #Canvas Frame
          self.SystemCanvasFrame = tk.Frame(master, bg='black')
          self.SystemCanvasFrame.grid(row=0, column=0)
  
          #Canvas
          self.SystemCanvas = tk.Canvas(self.SystemCanvasFrame, width=int(self.SizeX*0.75)-20, height=self.SizeY-20, bg="black")
          self.SystemCanvas.focus_set()
          self.xsb = tk.Scrollbar(self.SystemCanvasFrame, orient="horizontal", command=self.SystemCanvas.xview)
          self.ysb = tk.Scrollbar(self.SystemCanvasFrame, orient="vertical", command=self.SystemCanvas.yview)
          self.SystemCanvas.configure(scrollregion=(-500,-500,500,500))
          self.SystemCanvas.configure(yscrollcommand=self.ysb.set, xscrollcommand=self.xsb.set)
          #add the canvas with scroll bar in grid format
          self.xsb.grid(row=1, column=0, sticky="ew")
          self.ysb.grid(row=0, column=1, sticky="ns")
          self.SystemCanvas.grid(row=0, column=0, sticky="nsew")
  
          # This is what enables using the mouse to slide the window:
          self.SystemCanvas.bind("&lt;ButtonPress-1&gt;", self.move_start)
          self.SystemCanvas.bind("&lt;B1-Motion&gt;", self.move_move)
          #windows scroll
          self.SystemCanvas.bind("&lt;MouseWheel&gt;",self.zoomer)        
          #resize the main window
          self.master.bind('&lt;Configure&gt;', self.UpdateCanvasSize)
  
          #Create Objects
          self.Size = 5 #object Size
          x0 = 0
          y0 = 0
          x1 = self.Size
          y1 = self.Size
          self.SystemCanvas.create_oval(x0,y0,x1,y1, fill='green', outline='green', width=3, tags='Green')
          self.SystemCanvas.create_oval(x0,y0,x1,y1, fill='red', outline='red', width=3, tags='Red')
          self.SystemCanvas.create_oval(x0,y0,x1,y1, fill='yellow', outline='yellow', width=1, tags='Yellow')
  
          self.Display()
  
      def Display(self):
          self.interval += 0.5 #speed parameter
          GreenPos = self.UpdatePosition(0.1*self.interval, (0,0), 50)
          RedPos = self.UpdatePosition(0.02*self.interval+180, (0,0), 200)
          YellowPos = self.UpdatePosition(0.3*self.interval, RedPos, 10)
  
          self.MoveObject('Green', GreenPos)
          self.MoveObject('Red', RedPos)
          self.MoveObject('Yellow', YellowPos)
  
          self.master.after(50, self.Display) #Disable to zoom
  
      def MoveObject (self, Obj, pos): #only move object that are in the field of view
          """Move Obj to the given position (tuple - xy)"""
          ID = self.SystemCanvas.find_withtag(Obj)      
          #Convert the Center of the object to the coo need for tk
          x0 = pos[0] - self.Size/2.0 #radius of the circle
          y0 = pos[1] - self.Size/2.0
          x1 = pos[0] + self.Size/2.0
          y1 = pos[1] + self.Size/2.0
          self.SystemCanvas.coords(ID, x0,y0,x1,y1)
  
      def UpdatePosition(self, angle, center, distance):
          """Calculate next object position around the Center at the Distance and speed determine by Angle (in Radian) - Center of the object"""
          h = center[0]
          k = center[1]
          radius = distance
          Rad = angle
          x = h+radius*math.cos(Rad)
          y = k+radius*math.sin(Rad)
          return (x, y)
  
      def UpdateCanvasSize(self, event):
          """Permit to resize the canvas to the window"""
          self.SizeX, self.SizeY = self.master.winfo_width(), self.master.winfo_height()
          self.SystemCanvas.config(width=int(self.SizeX*0.75)-20, height=self.SizeY-20)
  
      def move_start(self, event):
          """Detect the beginning of the move"""
          self.SystemCanvas.scan_mark(event.x, event.y)
          self.SystemCanvas.focus_set() #security, set the focus on the Canvas
  
      def move_move(self, event):
          """Detect the move of the mouse"""
          self.SystemCanvas.scan_dragto(event.x, event.y, gain=1)
  
      def zoomer(self,event):
          """Detect the zoom action by the mouse. Zoom on the mouse focus"""
          true_x = self.SystemCanvas.canvasx(event.x)
          true_y = self.SystemCanvas.canvasy(event.y)
          if (event.delta &gt; 0):
              self.SystemCanvas.scale("all", true_x, true_y, 1.2, 1.2)
          elif (event.delta &lt; 0):
              self.SystemCanvas.scale("all", true_x, true_y, 0.8, 0.8)
          self.SystemCanvas.configure(scrollregion = self.SystemCanvas.bbox("all"))
  
  if __name__ == '__main__':
      root = tk.Tk()
      root.geometry('1125x750')
      app = Example(root)
      root.mainloop()
  </code></pre>