title: How to create a mask effect in tkinter?
body: <p>I was trying to create a game and wanted a masking effect in it, such that the area over which the character is will be visible, but am unable to do so, I thought of redrawing polygons but that seems quite naive. If you have a workaround for this please share it with me or if there is any function in tkinter canvas for it. </p>
  
  <p>The masking effect is like this jsfiddle : <a href="http://jsfiddle.net/w2t0fq41/" rel="nofollow noreferrer">http://jsfiddle.net/w2t0fq41/</a></p>
  
  <pre><code>import tkinter as tk
  from threading import Thread
  from time import sleep
  from math import sqrt
  from PIL import ImageTk, Image
  import random
  __author__ = "Avanish"
  
  
  class Bullet(object):
      def __init__(self, canvas = None, pos = [0, 0], direction = 1):# Direction will be calculated as per degrees
                  self.canvas = canvas
  
      def move(self):
          pass
  
      def checkCollision(self):
          pass
  
  
  
  class Character(object):
      def __init__(self, name = "Player1", canvas = None, pos = [0,0]):
          self.canvas = canvas
          self.name = name
          self.health = 100
          self.pos = pos
          self.image1 = ImageTk.PhotoImage(Image.open('Character1.png').resize((50, 50), Image.ANTIALIAS))
          self.image2 = ImageTk.PhotoImage(Image.open('Character2.png').resize((50, 50), Image.ANTIALIAS))
          #self.sprite = self.canvas.create_oval(pos[0], pos[1], pos[0] + 30, pos[1] + 30, fill = 'white', tag = 'Protagonist')
          self.sprite = self.canvas.create_image(pos[0], pos[1], image = self.image1, tag = 'Protagonist')
  
  
          self.legpos = True
          self.canvas.after(300, self.changeImage)
      def move(self, x, y):
          self.canvas.move(self.sprite, x, y)
  
      def attack(self):
          pass
  
  
      def changeImage(self):
          if self.legpos:
              self.canvas.itemconfig(self.sprite, image = self.image2)
              self.legpos = False
          else:
              self.canvas.itemconfig(self.sprite, image = self.image1)
              self.legpos = True
  
          self.canvas.after(300, self.changeImage)
  
  class Enemy(object):
      def __init__(self, name = "Killer", canvas = None, level = 1):
          self.canvas = canvas
          self.name = name
          self.level = level
          self.pos = []
  
          self.sprite = self.canvas.create_rectangle(pos[0], pos[1], pos[0] + 50, pos[1] + 50, fill = 'white')
  
      def move(self, x, y):
          self.canvas.move(self.sprite, x, y)
  
  
  class Main(tk.Frame):
      def __init__(self, master = None, width = 400, height = 700):
          super().__init__()
          self.master = master
          self.screenwidth = width
          self.screenheight = height
          self.place(x = 0, y = 0, width = width, height = height)
          self.draweverything()
          self.boxchange = 1
          self.mouseMotion()
  
      def draweverything(self):
  
          self.canvas = tk.Canvas(master = self, bg = 'black')
          self.canvas.place(x = 0, y = 0, width = self.screenwidth, height = self.screenheight)
          self.drawObstacles()
          self.player = Character(canvas = self.canvas, pos = [50, self.screenheight - 80])
  
      def drawObstacles(self):
          self.obstacles = []
          for a in range(20):
              x = random.choice(range(5, self.screenwidth - 50, 55))
              y = random.choice(range(5, self.screenheight - 100, 55))
  
              self.obstacles.append(self.canvas.create_rectangle(x, y, x + 50, y + 50, fill = 'red', tag = 'Box{}'.format(a)))
  
          self.obstacles = self.obstacles
          print(self.obstacles)
  
      def updateObstacles(self):
          spritey = self.canvas.coords('Protagonist')[1]
  
          if spritey &lt;= 400 or spritey &lt;= 350:
              for x in self.obstacles: self.canvas.move(x, 0, self.boxchange)
  
          for obstacle in self.obstacles:
              y = self.canvas.coords(obstacle)[1]
              if y &gt;= 650:
                  self.canvas.delete(obstacle)
                  b = random.choice(range(5, 300, 55))
                  self.obstacles.append(self.canvas.create_rectangle(5, b, 55, b + 50, fill = 'red'))
  
          self.canvas.after(15000, self.updateObstacles)
  
      def moveTowardsMouse(self, x, y):
          spritex, spritey = self.canvas.coords('Protagonist')
          # Code to make sure the player does not go out of the canvas
  
  
  
          if (spritex &lt;= 25 and x &lt; 0) or (spritex &gt;= 375 and x &gt; 0):
              if (spritey &lt;= 350 and y &lt; 0) or (spritey &gt;= 675 and y &gt; 0): pass
              else: self.canvas.move('Protagonist', 0, y)
          elif (spritey &lt;= 350 and y &lt; 0) or (spritey &gt;= 675 and y &gt; 0):
              if (spritex &lt;= 25 and x &lt; 0) or (spritex &gt;= 375 and x &gt; 0): pass
              else: self.canvas.move('Protagonist', x, 0)
          else:self.canvas.move('Protagonist', x, y)
  
      def mouseMotion(self):
          mx, my = (self.master.winfo_pointerx() - self.master.winfo_rootx()),(self.master.winfo_pointery() - self.master.winfo_rooty())
          x, y = self.canvas.coords('Protagonist')
          dist = sqrt(((mx - x) ** 2) + ((my - y) ** 2))
          speed = 1.0
          movex = ((mx - x) / dist) * speed
          movey = ((my - y) / dist) * speed
  
  
          self.moveTowardsMouse(movex, movey)
          self.updateObstacles()
          sleep(.01)
          self.canvas.after(10, self.mouseMotion)
  
  
  
  
  root = tk.Tk()
  root.geometry('400x700')
  app = Main(master = root)
  app.mainloop()
  
  </code></pre>