1

I have made a piece of code, this code has a animated side panel. when I make it dissapear it works fine but when I make it reappear it kind of jumps and enters faster than it exited code. i changed the self.pos = self.start_c from self.pos = start_c but it didnt help even thought i thought it would.

import customtkinter as ctk
import time

class sidepanel(ctk.CTkFrame):
    def __init__(self,parent, start_c, end_c):
        super().__init__(parent)

        self.start_c = start_c + 0.02
        self.end_c = end_c
        self.width = abs(start_c - end_c)

        self.pos = self.start_c
        self.in_start_pos = True

        self.place(relx = self.start_c, rely = 0.05, relwidth = self.width, relheight = 0.9)
    def animate(self):
        if self.in_start_pos:
            self.animate_forward()
        else:
            self.animate_backward()

    def animate_forward(self):
        if self.pos > self.end_c:
            self.pos -= 0.002
            self.place(relx = self.pos, rely = 0.05, relwidth = self.width, relheight = 0.9)
            self.after(2, self.animate_forward)
        else:
            self.in_start_pos = False
    def animate_backward(self):
        if self.pos < self.start_c:
            self.pos += 0.002
            self.place(relx=self.pos, rely=0.05, relwidth=self.width, relheight=0.9)
            self.after(2, self.animate_backward)
        else:
            self.in_start_pos = True

def move_btn():
    global button_x
    button_x += 0.001
    button.place(relx=button_x, rely=0.5, anchor='center')

    if button_x < 0.9:
        window.after(10, move_btn   )

def inf_print():
    global button_x
    print("infinite")
    button_x += 0.5
    if button_x > 10:
        window.after(1, inf_print)

window = ctk.CTk()
window.geometry('600x400')
button_x = 0.5
animpanel = sidepanel(window,0, -0.3)
ctk.CTkLabel(animpanel, text = 'label').pack(fill= 'both', expand = True, pady = 10)
ctk.CTkLabel(animpanel, text = 'label').pack(fill= 'both', expand = True, pady = 10)
ctk.CTkButton(animpanel, text = 'label', corner_radius= 5).pack(fill= 'both', expand = True, pady = 10)

button = ctk.CTkButton(window, text = 'animation', command = animpanel.animate)
button.place(relx=button_x, rely= 0.5,anchor = 'center')

window.mainloop()```

1 Answers1

0

The jumping behavior you're experiencing when the panel reappears after disappearing is likely due to the difference in animation timing between the forward and backward animations. In your code, you are using a fixed delay (self.after(2, ...)) for both animation directions, which might cause one direction to finish faster than the other, leading to the jumping effect.

To be sure that you have a smooth animation in both directions, you have to consider adjusting the delay for the backward animation to match the duration of the forward animation, and to get this done, you should start by calculating the total number of animation steps required for each direction and then adjusting the delay accordingly. Please try the updated the piece of code below:

class sidepanel(ctk.CTkFrame):
def __init__(self, parent, start_c, end_c):
    super().__init__(parent)

    self.start_c = start_c + 0.02
    self.end_c = end_c
    self.width = abs(start_c - end_c)

    self.pos = self.start_c
    self.in_start_pos = True

    self.place(relx=self.start_c, rely=0.05, relwidth=self.width, relheight=0.9)

    # Calculate total animation steps for each direction
    self.total_steps_forward = int((self.start_c - self.end_c) / 0.002)
    self.total_steps_backward = int((self.end_c - self.start_c) / 0.002)

def animate(self):
    if self.in_start_pos:
        self.animate_forward()
    else:
        self.animate_backward()

def animate_forward(self):
    if self.pos > self.end_c:
        self.pos -= 0.002
        self.place(relx=self.pos, rely=0.05, relwidth=self.width, relheight=0.9)
        self.after(2, self.animate_forward)
    else:
        self.in_start_pos = False

def animate_backward(self, step=None):
    if step is None:
        step = self.total_steps_backward  # Start from the total steps backward

    if self.pos < self.start_c and step > 0:
        self.pos += 0.002
        self.place(relx=self.pos, rely=0.05, relwidth=self.width, relheight=0.9)
        self.after(2, self.animate_backward, step - 1)
    else:
        self.in_start_pos = True

I have added the total_steps_forward and total_steps_backward variables to calculate the total animation steps required for each direction. By doing that, the backward animation now will accept a step parameter to keep track of the current step, and then it decrements the step value in each recursive call. This way, the delay is adjusted according to the calculated steps for a smoother animation.

Maged Almaweri
  • 312
  • 4
  • 11