Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_interactive_ripple.py
- import tkinter as tk
- import math
- SPACING = 25
- PARTICLE_RADIUS = 2
- RIPPLE_MAX_RADIUS = 200
- RIPPLE_SPEED = 16
- RIPPLE_OPACITY_DECAY = 0.02
- MOUSE_REPULSION_DISTANCE = 200
- MOUSE_REPULSION_FORCE = 2
- FRICTION = 0.9
- RETURN_TO_ORIGIN_FORCE = 0.05
- particles = []
- ripples = []
- mouse_x, mouse_y = 0, 0
- def initialize_particles():
- global particles
- width = canvas.winfo_width()
- height = canvas.winfo_height()
- rows = math.ceil(height / SPACING)
- cols = math.ceil(width / SPACING)
- particles.clear()
- for y in range(rows):
- for x in range(cols):
- particle = {
- "origin_x": x * SPACING,
- "origin_y": y * SPACING,
- "x": x * SPACING,
- "y": y * SPACING,
- "vx": 0,
- "vy": 0
- }
- particles.append(particle)
- def update_particle(particle, mouse_x, mouse_y):
- dx = particle["x"] - mouse_x
- dy = particle["y"] - mouse_y
- distance = math.sqrt(dx * dx + dy * dy)
- if distance < MOUSE_REPULSION_DISTANCE:
- force = (MOUSE_REPULSION_DISTANCE - distance) / MOUSE_REPULSION_DISTANCE * MOUSE_REPULSION_FORCE
- if distance:
- particle["vx"] += (dx / distance) * force
- particle["vy"] += (dy / distance) * force
- for ripple in ripples:
- rdx = particle["x"] - ripple["x"]
- rdy = particle["y"] - ripple["y"]
- ripple_distance = math.sqrt(rdx * rdx + rdy * rdy)
- distance_from_ripple_edge = abs(ripple_distance - ripple["radius"])
- if distance_from_ripple_edge < 10:
- ripple_force = ripple["opacity"] * 0.5
- if ripple_distance:
- particle["vx"] += (rdx / ripple_distance) * ripple_force
- particle["vy"] += (rdy / ripple_distance) * ripple_force
- particle["vx"] += (particle["origin_x"] - particle["x"]) * RETURN_TO_ORIGIN_FORCE
- particle["vy"] += (particle["origin_y"] - particle["y"]) * RETURN_TO_ORIGIN_FORCE
- particle["vx"] *= FRICTION
- particle["vy"] *= FRICTION
- particle["x"] += particle["vx"]
- particle["y"] += particle["vy"]
- def draw_particle(particle):
- canvas.create_oval(
- particle["x"] - PARTICLE_RADIUS, particle["y"] - PARTICLE_RADIUS,
- particle["x"] + PARTICLE_RADIUS, particle["y"] + PARTICLE_RADIUS,
- fill="white", outline=""
- )
- def create_ripple(x, y):
- ripple = {
- "x": x,
- "y": y,
- "radius": 0,
- "opacity": 1
- }
- ripples.append(ripple)
- def update_ripple(ripple):
- ripple["radius"] += RIPPLE_SPEED
- ripple["opacity"] -= RIPPLE_OPACITY_DECAY
- return ripple["opacity"] > 0
- def draw_ripple(ripple):
- canvas.create_oval(
- ripple["x"] - ripple["radius"], ripple["y"] - ripple["radius"],
- ripple["x"] + ripple["radius"], ripple["y"] + ripple["radius"],
- outline=f"rgba(255, 255, 255, 255)"
- )
- def on_mouse_move(event):
- global mouse_x, mouse_y
- mouse_x, mouse_y = event.x, event.y
- def animate():
- canvas.delete("all")
- for particle in particles:
- update_particle(particle, mouse_x, mouse_y)
- draw_particle(particle)
- for ripple in ripples[:]:
- if not update_ripple(ripple):
- ripples.remove(ripple)
- else:
- draw_ripple(ripple)
- def on_resize(event):
- initialize_particles()
- root = tk.Tk()
- root.title("Particle Ripple Simulation")
- root.geometry("800x600+10+0")
- canvas = tk.Canvas(root, bg="black")
- canvas.pack(fill=tk.BOTH, expand=True)
- initialize_particles()
- canvas.bind("<Motion>", on_mouse_move)
- root.bind("<Configure>", lambda e: on_resize(e))
- while 1:
- animate()
- root.update()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement