Python实现水面涟漪效果

        小时候在安装盗版Windows7的时候,安装助手有一个鼠标滑过泛起涟漪的界面。这几天抽空用Python把这个效果实现了:

import tkinter as tk
from PIL import Image, ImageTk
import time

class RippleEffectSimulator:
    def __init__(self, root):
        self.root = root
        self.root.title("Ripple Effect Simulator")

        # 创建画布
        self.canvas = tk.Canvas(root, width=650, height=975)
        self.canvas.pack()

        # 加载背景图片
        # 加载背景图片
        self.background_image = Image.open("pool.png")
        self.background_image = self.background_image.resize((650, 975), Image.LANCZOS)
        self.background_photo = ImageTk.PhotoImage(self.background_image)
        self.canvas.create_image(0, 0, image=self.background_photo, anchor=tk.NW)

        # 创建标签和按钮
        self.label = tk.Label(root, text="Move the mouse to create ripple effects!")
        self.label.pack()

        self.reset_button = tk.Button(root, text="Reset", command=self.reset_simulation)
        self.reset_button.pack()

        # 绑定鼠标移动事件
        self.canvas.bind("<Motion>", self.on_mouse_move)

        self.circles = []
        self.last_ripple_time = 0
        self.ripple_interval = 0.1  # 50 ms between ripples

    def on_mouse_move(self, event):
        current_time = time.time()
        if current_time - self.last_ripple_time >= self.ripple_interval:
            self.add_ripple(event.x, event.y)
            self.last_ripple_time = current_time

    def add_ripple(self, x, y):
        # Define multiple layers with different characteristics
        layers = [
            {'color': (255, 255, 255), 'max_radius': 20, 'speed': 20, 'width': 2, 'delay': 0},  # Blue
            {'color': (173, 216, 230), 'max_radius': 30, 'speed': 15, 'width': 1, 'delay': 0.2},  # Light Blue
            {'color': (0, 255, 255), 'max_radius': 40, 'speed': 10, 'width': 1, 'delay': 0.4}   # Cyan
        ]        
        for layer in layers:
            self.root.after(int(layer['delay'] * 1000), self.create_ripple_layer, x, y, layer['color'], layer['max_radius'], layer['speed'], layer['width'])

    def create_ripple_layer(self, x, y, color, max_radius, speed, width):
        start_time = time.time()
        ripple_id = self.canvas.create_oval(x, y, x, y, outline="", width=width)
        self.circles.append((ripple_id, start_time, x, y, color, max_radius, speed))
        self.update_ripple(ripple_id, start_time, x, y, color, max_radius, speed)

    def update_ripple(self, ripple_id, start_time, x, y, color, max_radius, speed):
        current_time = time.time()
        duration = current_time - start_time
        radius = min(max_radius, duration * speed)

        if radius >= max_radius:
            self.canvas.delete(ripple_id)  # Directly remove ripple when it reaches max radius
            return

        # Calculate color fading by interpolating with the background color (assuming background is blue-ish)
        progress = radius / max_radius
        faded_color = self.fade_to_background(color, progress)

        self.canvas.itemconfig(ripple_id, outline=faded_color)

        x0 = x - radius
        y0 = y - radius
        x1 = x + radius
        y1 = y + radius
        self.canvas.coords(ripple_id, x0, y0, x1, y1)
        self.root.after(10, self.update_ripple, ripple_id, start_time, x, y, color, max_radius, speed)

    def fade_to_background(self, color, progress):
        """Interpolates the color towards the background color (blueish)."""
        bg_color = (135, 206, 235)  # Assume a light blue background color
        faded_color = tuple(int(c * (1 - progress) + bg_c * progress) for c, bg_c in zip(color, bg_color))
        return f'#{faded_color[0]:02x}{faded_color[1]:02x}{faded_color[2]:02x}'

    def reset_simulation(self):
        self.canvas.delete("all")
        self.canvas.create_image(0, 0, image=self.background_photo, anchor=tk.NW)
        self.label.config(text="Move the mouse to create ripple effects!")
        self.circles = []
        self.last_ripple_time = 0  # Reset the last ripple time

if __name__ == "__main__":
    root = tk.Tk()
    app = RippleEffectSimulator(root)
    root.mainloop()

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值