Files
shared_libs/cfd_animated_icon.py
2025-08-08 00:55:32 +02:00

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"))