83 lines
3.3 KiB
Python
83 lines
3.3 KiB
Python
import tkinter as tk
|
|
import math
|
|
|
|
class AnimatedSearchIcon(tk.Canvas):
|
|
def __init__(self, parent, bg_color, style="single", *args, **kwargs):
|
|
kwargs.setdefault('width', 22)
|
|
kwargs.setdefault('height', 22)
|
|
super().__init__(parent, *args, **kwargs)
|
|
self.configure(bg=bg_color, highlightthickness=0)
|
|
self.width = self.winfo_reqwidth()
|
|
self.height = self.winfo_reqheight()
|
|
|
|
self.angle1 = 0
|
|
self.angle2 = 0
|
|
self.color_angle = 0
|
|
self.base_color = (81, 149, 255) # #5195ff
|
|
self.is_animating = False
|
|
self.style = style
|
|
|
|
self.draw_initial_state()
|
|
|
|
def start_animation(self):
|
|
if self.is_animating:
|
|
return
|
|
self.is_animating = True
|
|
self.update_animation()
|
|
|
|
def stop_animation(self):
|
|
self.is_animating = False
|
|
self.draw_initial_state()
|
|
|
|
def update_animation(self):
|
|
if not self.is_animating:
|
|
return
|
|
|
|
if self.style == "single":
|
|
self.angle1 = (self.angle1 - 6) % 360
|
|
elif self.style == "double":
|
|
self.angle1 = (self.angle1 - 6) % 360
|
|
self.angle2 = (self.angle2 + 6) % 360
|
|
|
|
self.color_angle = (self.color_angle + 0.15) % (2 * math.pi)
|
|
self.draw_animated_arc()
|
|
self.after(25, self.update_animation)
|
|
|
|
def get_pulsating_color(self):
|
|
factor = 0.5 * (1 + math.sin(self.color_angle))
|
|
r = int(self.base_color[0] + (255 - self.base_color[0]) * factor * 0.6)
|
|
g = int(self.base_color[1] + (255 - self.base_color[1]) * factor * 0.6)
|
|
b = int(self.base_color[2] + (255 - self.base_color[2]) * factor * 0.6)
|
|
return f"#{r:02x}{g:02x}{b:02x}"
|
|
|
|
def draw_animated_arc(self):
|
|
self.delete("all")
|
|
color = self.get_pulsating_color()
|
|
if self.style == "single":
|
|
x0, y0 = 3, 3
|
|
x1, y1 = self.width - 3, self.height - 3
|
|
self.create_arc(x0, y0, x1, y1, start=self.angle1, extent=300, style=tk.ARC, width=4, outline=color)
|
|
elif self.style == "double":
|
|
# Outer arc
|
|
x0_outer, y0_outer = 3, 3
|
|
x1_outer, y1_outer = self.width - 3, self.height - 3
|
|
self.create_arc(x0_outer, y0_outer, x1_outer, y1_outer, start=self.angle1, extent=150, style=tk.ARC, width=2, outline=color)
|
|
# Inner arc
|
|
x0_inner, y0_inner = 7, 7
|
|
x1_inner, y1_inner = self.width - 7, self.height - 7
|
|
self.create_arc(x0_inner, y0_inner, x1_inner, y1_inner, start=self.angle2, extent=150, style=tk.ARC, width=2, outline=color)
|
|
|
|
def draw_initial_state(self):
|
|
self.delete("all")
|
|
if self.style == "single":
|
|
x0, y0 = 3, 3
|
|
x1, y1 = self.width - 3, self.height - 3
|
|
self.create_oval(x0, y0, x1, y1, outline="#5195ff", width=4, fill=self.cget("bg"))
|
|
elif self.style == "double":
|
|
x0_outer, y0_outer = 3, 3
|
|
x1_outer, y1_outer = self.width - 3, self.height - 3
|
|
self.create_oval(x0_outer, y0_outer, x1_outer, y1_outer, outline="#5195ff", width=2, fill=self.cget("bg"))
|
|
x0_inner, y0_inner = 7, 7
|
|
x1_inner, y1_inner = self.width - 7, self.height - 7
|
|
self.create_oval(x0_inner, y0_inner, x1_inner, y1_inner, outline="#5195ff", width=2, fill=self.cget("bg"))
|