import tkinter as tk
from tkinter import ttk
import colorsys
import math
class LEDBorderApp:
def __init__(self):
self.running = True
self.border_width = 8
self.animation_speed = 2 # Changed to frame skip value
self.hue_offset = 0
self.borders = []
self.control_window = None
self.is_visible = True
self.frame_counter = 0
# Get screen dimensions
temp_root = tk.Tk()
self.screen_width = temp_root.winfo_screenwidth()
self.screen_height = temp_root.winfo_screenheight()
temp_root.destroy()
self.create_borders()
self.create_control_panel()
self.start_animation()
def create_borders(self):
"""Create transparent windows at screen edges"""
positions = [
# (x, y, width, height, orientation)
(0, 0, self.screen_width, self.border_width, 'horizontal'), # top
(self.screen_width - self.border_width, 0, self.border_width, self.screen_height, 'vertical'), # right
(0, self.screen_height - self.border_width, self.screen_width, self.border_width, 'horizontal'), # bottom
(0, 0, self.border_width, self.screen_height, 'vertical'), # left
]
for i, (x, y, width, height, orientation) in enumerate(positions):
border = tk.Toplevel()
border.title(f"LED Border {i}")
border.geometry(f"{width}x{height}+{x}+{y}")
# Make window stay on top and be click-through
border.wm_attributes("-topmost", True)
border.wm_attributes("-transparentcolor", "black")
border.configure(bg='black')
border.overrideredirect(True) # Remove window decorations
# Make it click-through on Windows
try:
border.wm_attributes("-disabled", True)
except:
pass
# Create canvas for drawing
canvas = tk.Canvas(border, width=width, height=height,
bg='black', highlightthickness=0)
canvas.pack(fill='both', expand=True)
self.borders.append({
'window': border,
'canvas': canvas,
'width': width,
'height': height,
'orientation': orientation,
'phase_offset': i * math.pi / 2
})
def create_control_panel(self):
"""Create a small control panel"""
self.control_window = tk.Tk()
self.control_window.title("LED Border Controls")
self.control_window.geometry("300x250+50+50")
self.control_window.wm_attributes("-topmost", True)
# Toggle visibility
toggle_btn = tk.Button(self.control_window, text="Toggle Borders",
command=self.toggle_visibility, font=('Arial', 10))
toggle_btn.pack(pady=5)
# Border width control
tk.Label(self.control_window, text="Border Width:", font=('Arial', 9)).pack()
self.width_var = tk.IntVar(value=self.border_width)
width_scale = tk.Scale(self.control_window, from_=2, to=20,
orient=tk.HORIZONTAL, variable=self.width_var,
command=self.update_border_width)
width_scale.pack(pady=5)
# Animation speed control
tk.Label(self.control_window, text="Animation Speed:", font=('Arial', 9)).pack()
self.speed_var = tk.IntVar(value=self.animation_speed)
speed_scale = tk.Scale(self.control_window, from_=1, to=10,
orient=tk.HORIZONTAL, variable=self.speed_var,
command=self.update_animation_speed)
speed_scale.pack(pady=5)
# Status label
self.status_label = tk.Label(self.control_window, text="Status: Running",
fg="green", font=('Arial', 9))
self.status_label.pack(pady=5)
# Exit button
exit_btn = tk.Button(self.control_window, text="Exit",
command=self.exit_app, bg='red', fg='white',
font=('Arial', 10))
exit_btn.pack(pady=10)
# Minimize button
minimize_btn = tk.Button(self.control_window, text="Minimize Controls",
command=self.minimize_controls, font=('Arial', 9))
minimize_btn.pack(pady=2)
# Instructions
instructions = tk.Label(self.control_window,
text="Borders work with all apps!\\nYouTube, games, everything!",
font=('Arial', 8), fg="blue")
instructions.pack(pady=5)
# Bind close event
self.control_window.protocol("WM_DELETE_WINDOW", self.exit_app)
def update_border_width(self, value):
self.border_width = int(value)
# Recreate borders with new width
self.destroy_borders()
self.create_borders()
def update_animation_speed(self, value):
self.animation_speed = int(value)
def toggle_visibility(self):
self.is_visible = not self.is_visible
for border in self.borders:
if self.is_visible:
border['window'].deiconify()
else:
border['window'].withdraw()
# Update status
status_text = "Status: Running" if self.is_visible else "Status: Hidden"
status_color = "green" if self.is_visible else "orange"
self.status_label.config(text=status_text, fg=status_color)
def minimize_controls(self):
self.control_window.iconify()
def destroy_borders(self):
for border in self.borders:
try:
border['window'].destroy()
except:
pass
self.borders.clear()
def get_rainbow_color(self, position, time_offset=0):
"""Generate rainbow color based on position and time"""
hue = (position + self.hue_offset + time_offset) % 1.0
rgb = colorsys.hsv_to_rgb(hue, 1.0, 1.0)
return f"#{int(rgb[0]*255):02x}{int(rgb[1]*255):02x}{int(rgb[2]*255):02x}"
def animate_frame(self):
"""Animate one frame - called by tkinter's after method"""
if not self.running:
return
try:
# Only update every N frames based on animation speed
if self.frame_counter % (11 - self.animation_speed) == 0:
if self.is_visible and self.borders:
for border in self.borders:
canvas = border['canvas']
canvas.delete("all") # Clear previous frame
if border['orientation'] == 'horizontal':
# Draw horizontal gradient
width = border['width']
height = border['height']
segments = min(width // 4, 50) # Reduced segments for better performance
for i in range(segments):
x1 = (i * width) // segments
x2 = ((i + 1) * width) // segments
position = i / segments + border['phase_offset']
color = self.get_rainbow_color(position)
canvas.create_rectangle(x1, 0, x2, height,
fill=color, outline=color)
else:
# Draw vertical gradient
width = border['width']
height = border['height']
segments = min(height // 4, 50) # Reduced segments for better performance
for i in range(segments):
y1 = (i * height) // segments
y2 = ((i + 1) * height) // segments
position = i / segments + border['phase_offset']
color = self.get_rainbow_color(position)
canvas.create_rectangle(0, y1, width, y2,
fill=color, outline=color)
# Update hue offset for animation
self.hue_offset = (self.hue_offset + 0.01) % 1.0
self.frame_counter += 1
# Schedule next frame
if self.control_window:
self.control_window.after(16, self.animate_frame) # ~60 FPS
except Exception as e:
print(f"Animation error: {e}")
# Try to continue
if self.control_window:
self.control_window.after(100, self.animate_frame)
def start_animation(self):
"""Start animation using tkinter's after method"""
self.animate_frame()
def exit_app(self):
"""Clean exit"""
print("Shutting down LED Border Application...")
self.running = False
self.destroy_borders()
if self.control_window:
try:
self.control_window.quit()
self.control_window.destroy()
except:
pass
def run(self):
"""Start the application"""
try:
print("LED Border Application is running!")
print("- Minimize the control panel to hide it")
print("- The borders will stay active")
print("- Try watching YouTube or opening any app!")
self.control_window.mainloop()
except KeyboardInterrupt:
self.exit_app()
def main():
print("🌈 Starting LED Border Application...")
print("✨ Creates rainbow LED borders around your entire screen")
print("🎮 Works with any application - YouTube, games, work apps!")
print("🎛️ Use the control panel to adjust settings")
print("⚡ Press Ctrl+C in terminal to force exit if needed")
print("")
try:
app = LEDBorderApp()
app.run()
except Exception as e:
print(f"Error starting application: {e}")
print("Make sure you have Python with tkinter installed.")
input("Press Enter to exit...")
if __name__ == "__main__":
main()