Advertisement
here2share

# tk_interactive_ripple.py

Dec 27th, 2024
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.59 KB | None | 0 0
  1. # tk_interactive_ripple.py
  2.  
  3. import tkinter as tk
  4. import math
  5.  
  6. SPACING = 25
  7. PARTICLE_RADIUS = 2
  8. RIPPLE_MAX_RADIUS = 200
  9. RIPPLE_SPEED = 16
  10. RIPPLE_OPACITY_DECAY = 0.02
  11. MOUSE_REPULSION_DISTANCE = 200
  12. MOUSE_REPULSION_FORCE = 2
  13. FRICTION = 0.9
  14. RETURN_TO_ORIGIN_FORCE = 0.05
  15.  
  16. particles = []
  17. ripples = []
  18. mouse_x, mouse_y = 0, 0
  19.  
  20. def initialize_particles():
  21.     global particles
  22.     width = canvas.winfo_width()
  23.     height = canvas.winfo_height()
  24.     rows = math.ceil(height / SPACING)
  25.     cols = math.ceil(width / SPACING)
  26.     particles.clear()
  27.     for y in range(rows):
  28.         for x in range(cols):
  29.             particle = {
  30.                 "origin_x": x * SPACING,
  31.                 "origin_y": y * SPACING,
  32.                 "x": x * SPACING,
  33.                 "y": y * SPACING,
  34.                 "vx": 0,
  35.                 "vy": 0
  36.             }
  37.             particles.append(particle)
  38.  
  39. def update_particle(particle, mouse_x, mouse_y):
  40.     dx = particle["x"] - mouse_x
  41.     dy = particle["y"] - mouse_y
  42.     distance = math.sqrt(dx * dx + dy * dy)
  43.  
  44.     if distance < MOUSE_REPULSION_DISTANCE:
  45.         force = (MOUSE_REPULSION_DISTANCE - distance) / MOUSE_REPULSION_DISTANCE * MOUSE_REPULSION_FORCE
  46.         if distance:
  47.             particle["vx"] += (dx / distance) * force
  48.             particle["vy"] += (dy / distance) * force
  49.  
  50.     for ripple in ripples:
  51.         rdx = particle["x"] - ripple["x"]
  52.         rdy = particle["y"] - ripple["y"]
  53.         ripple_distance = math.sqrt(rdx * rdx + rdy * rdy)
  54.  
  55.         distance_from_ripple_edge = abs(ripple_distance - ripple["radius"])
  56.         if distance_from_ripple_edge < 10:
  57.             ripple_force = ripple["opacity"] * 0.5
  58.             if ripple_distance:
  59.                 particle["vx"] += (rdx / ripple_distance) * ripple_force
  60.                 particle["vy"] += (rdy / ripple_distance) * ripple_force
  61.  
  62.     particle["vx"] += (particle["origin_x"] - particle["x"]) * RETURN_TO_ORIGIN_FORCE
  63.     particle["vy"] += (particle["origin_y"] - particle["y"]) * RETURN_TO_ORIGIN_FORCE
  64.  
  65.     particle["vx"] *= FRICTION
  66.     particle["vy"] *= FRICTION
  67.  
  68.     particle["x"] += particle["vx"]
  69.     particle["y"] += particle["vy"]
  70.  
  71. def draw_particle(particle):
  72.     canvas.create_oval(
  73.         particle["x"] - PARTICLE_RADIUS, particle["y"] - PARTICLE_RADIUS,
  74.         particle["x"] + PARTICLE_RADIUS, particle["y"] + PARTICLE_RADIUS,
  75.         fill="white", outline=""
  76.     )
  77.  
  78. def create_ripple(x, y):
  79.     ripple = {
  80.         "x": x,
  81.         "y": y,
  82.         "radius": 0,
  83.         "opacity": 1
  84.     }
  85.     ripples.append(ripple)
  86.  
  87. def update_ripple(ripple):
  88.     ripple["radius"] += RIPPLE_SPEED
  89.     ripple["opacity"] -= RIPPLE_OPACITY_DECAY
  90.     return ripple["opacity"] > 0
  91.  
  92. def draw_ripple(ripple):
  93.     canvas.create_oval(
  94.         ripple["x"] - ripple["radius"], ripple["y"] - ripple["radius"],
  95.         ripple["x"] + ripple["radius"], ripple["y"] + ripple["radius"],
  96.         outline=f"rgba(255, 255, 255, 255)"
  97.     )
  98.  
  99. def on_mouse_move(event):
  100.     global mouse_x, mouse_y
  101.     mouse_x, mouse_y = event.x, event.y
  102.  
  103. def animate():
  104.     canvas.delete("all")
  105.  
  106.     for particle in particles:
  107.         update_particle(particle, mouse_x, mouse_y)
  108.         draw_particle(particle)
  109.  
  110.     for ripple in ripples[:]:
  111.         if not update_ripple(ripple):
  112.             ripples.remove(ripple)
  113.         else:
  114.             draw_ripple(ripple)
  115.  
  116. def on_resize(event):
  117.     initialize_particles()
  118.  
  119. root = tk.Tk()
  120. root.title("Particle Ripple Simulation")
  121. root.geometry("800x600+10+0")
  122.  
  123. canvas = tk.Canvas(root, bg="black")
  124. canvas.pack(fill=tk.BOTH, expand=True)
  125.  
  126. initialize_particles()
  127.  
  128. canvas.bind("<Motion>", on_mouse_move)
  129. root.bind("<Configure>", lambda e: on_resize(e))
  130.  
  131. while 1:
  132.     animate()
  133.     root.update()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement