Search code examples
pythondrawingpython-turtle

How to gradually change the saturation of a color in python turtle


I would like to make a color change its saturation. Like when you first draw a color (red), then you make it a little lighter so that it doesn't become white right away. It slowly gets lighter and lighter until it is the color white. Its not this post: Changing the color gradually turtle (python) because it is changing the color instantly.

I tried this:

colors = ["red","white"]
for i in range(2):
   turtle.color(colors[i])
   turtle.circle(100)
done()

but it immediately changes the color which is what I don't want. Can someone help me?


Solution

  • The issue you face is that the circle method is doing it's own thing. Once that routine starts there doesn't seem to be a way to affect any of it's properties while it is drawing. This means you have to get creative and make your own circle drawing function. The below is an example that gets you in the ballpark.

    import turtle as t
    from math import cos, sin, radians
    
    
    # gradients
    RED_GRAD   = [f'#{(c<<20|c<<16):06x}' for c in range(0, 16)]
    GREEN_GRAD = [f'#{(c<<12|c<<8):06x}' for c in range(0, 16)]
    BLUE_GRAD  = [f'#{(c<<4|c):06x}' for c in range(0, 16)]
    
    CC_TRIGGER = 360//15 # degrees to draw before going to next color
    
    
    def move_pen(x:int, y:int) -> None:
        t.penup()
        t.goto(x, y)
        t.pendown()
    
    
    def draw_circle(radius:int, x:int, y:int, thickness:int=2, gradient:list=RED_GRAD, speed:float=5) -> None:
        speed = max(1, min(5, speed))  # constrain speed
                                       
        t.tracer(1.6*speed, 3.2*speed) # set speed
        t.width(thickness)             # set line thickness
                                       
        move_pen(x + radius, y)        # set pen at drawing start location
                                       
        # draw circle                  
        for i in range(1, 361):        
            t.settiltangle(i+90)       # emulate turtle behavior for circle method
    
            # change color 
            t.color(gradient[i//CC_TRIGGER])
    
            # draw step
            r = radians(i)
            t.goto(radius * cos(r) + x, radius * sin(r) + y)
    
    
    if __name__ == "__main__":    
        draw_circle(50, 0, 0, gradient=BLUE_GRAD, speed=1.3)
        t.mainloop()