前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >跳动的爱心(源码)

跳动的爱心(源码)

原创
作者头像
Pocker_Spades_A
修改于 2025-03-31 13:13:06
修改于 2025-03-31 13:13:06
9100
代码可运行
举报
文章被收录于专栏:CSDNCSDN
运行总次数:0
代码可运行

引言

在代码的世界里,浪漫也能通过代码来实现。今天我们就来详细讲解如何使用 Python 实现一个跳动的爱心,也就是李洵同款的跳动爱心效果。通过这个项目,我们可以学习到 Python 的图形绘制、数学函数的运用以及动画的实现。

实现思路

要实现跳动的爱心效果,我们主要分为以下几个步骤:

  1. 定义爱心的数学函数:通过数学公式来确定爱心的形状。
  2. 生成爱心的点:在爱心的形状上随机生成一些点,模拟爱心的扩散效果。
  3. 实现跳动效果:通过改变点的位置和大小,实现爱心的跳动效果。
  4. 绘制动画:使用 Tkinter 库来绘制爱心,并通过定时更新画面来实现动画效果。

代码详解

1. 导入必要的库

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
import random
from math import sin, cos, pi, log
from tkinter import *

这里我们导入了 random 库用于生成随机数,math 库中的三角函数和对数函数用于计算爱心的形状,tkinter 库用于创建图形界面。

2. 定义常量

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
CANVAS_WIDTH = 640
CANVAS_HEIGHT = 640
CANVAS_CENTER_X = CANVAS_WIDTH / 2
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2
IMAGE_ENLARGE = 11
HEART_COLOR = "#Fd798f"

这些常量定义了画布的大小、中心点的位置、图像的放大倍数以及爱心的颜色。

3. 定义爱心的数学函数

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
def heart_function(t, shrink_ratio: float = IMAGE_ENLARGE):
    x = 16 * (sin(t) ** 3)
    y = -(15 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(3 * t))

    x *= shrink_ratio
    y *= shrink_ratio

    x += CANVAS_CENTER_X
    y += CANVAS_CENTER_Y
    return int(x), int(y)

这个函数根据参数 t 计算爱心上的点的坐标,通过三角函数的组合来实现爱心的形状。shrink_ratio 参数用于调整爱心的大小。

4. 生成扩散点

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
def scatter_inside(x, y, beta=0.15):
    ratio_x = -beta * log(random.random())
    ratio_y = -beta * log(random.random())

    dx = ratio_x * (x - CANVAS_CENTER_X)
    dy = ratio_y * (y - CANVAS_CENTER_Y)
    return x - dx, y - dy

这个函数用于在爱心内部随机生成扩散点,通过对数函数和随机数来实现扩散效果。

5. 收缩函数

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
def shrink(x, y, ratio):
    force = -1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.6)

    dx = ratio * force * (x - CANVAS_CENTER_X)
    dy = ratio * force * (y - CANVAS_CENTER_Y)
    return x - dx, y - dy

这个函数用于收缩点的位置,根据点到中心点的距离来计算收缩的力度。

6. 曲线函数

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
def curve(p):
    return 2 * (2 * sin(4 * p)) / (2 * pi)

这个函数用于生成一个周期性的曲线,用于控制爱心的跳动效果。

7. 定义 Heart

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
class Heart:
    def __init__(self, generate_frame=20):
        self._points = set()
        self._edge_diffusion_points = set()
        self._center_diffusion_points = set()
        self.all_points = {}
        self.build(2000)

        self.random_halo = 1000
        self.generate_frame = generate_frame
        for frame in range(generate_frame):
            self.calc(frame)

    def build(self, number):
        for _ in range(number):
            t = random.uniform(0, 2 * pi)
            x, y = heart_function(t)
            self._points.add((x, y))

        for _x, _y in list(self._points):
            for _ in range(3):
                x, y = scatter_inside(_x, _y, 0.3)
                self._edge_diffusion_points.add((x, y))
        point_list = list(self._points)
        for _ in range(4000):
            x, y = random.choice(point_list)
            x, y = scatter_inside(x, y, 0.2)
            self._center_diffusion_points.add((x, y))

    @staticmethod
    def calc_position(x, y, ratio):
        force = 1 / (((x - CANVAS_CENTER_X) ** 2 + (y - CANVAS_CENTER_Y) ** 2) ** 0.520)
        dx = ratio * force * (x - CANVAS_CENTER_X) + random.randint(-2, 2)
        dy = ratio * force * (y - CANVAS_CENTER_Y) + random.randint(-2, 2)
        return x - dx, y - dy

    def calc(self, generate_frame):
        ratio = 15 * curve(generate_frame / 15 * pi)
        halo_radius = int(4 + 6 * (1 + curve(generate_frame / 15 * pi)))
        halo_number = int(3000 + 4000 * abs(curve(generate_frame / 15 * pi) ** 2))
        all_points = []
        heart_halo_point = set()
        for _ in range(halo_number):
            t = random.uniform(0, 2 * pi)
            x, y = heart_function(t, shrink_ratio=11.5)
            x, y = shrink(x, y, halo_radius)
            if (x, y) not in heart_halo_point:
                heart_halo_point.add((x, y))
                x += random.randint(-16, 16)
                y += random.randint(-16, 16)
                size = random.choice((2, 2, 1))
                all_points.append((x, y, size))

        for x, y in self._points:
            x, y = self.calc_position(x, y, ratio)
            size = random.randint(1, 2)
            all_points.append((x, y, size))

        for x, y in self._edge_diffusion_points:
            x, y = self.calc_position(x, y, ratio)
            size = random.randint(1, 2)
            all_points.append((x, y, size))

        for x, y in self._center_diffusion_points:
            x, y = self.calc_position(x, y, ratio)
            size = random.randint(1, 2)
            all_points.append((x, y, size))
        self.all_points[generate_frame] = all_points

    def render(self, render_canvas, render_frame):
        for x, y, size in self.all_points[render_frame % self.generate_frame]:
            render_canvas.create_rectangle(x, y, x + size, y + size, width=0, fill=HEART_COLOR)

Heart 类是整个程序的核心,负责生成爱心的点、计算点的位置和大小,并将其绘制到画布上。具体来说:

  • __init__ 方法:初始化爱心的点集,并调用 build 方法生成点,然后调用 calc 方法计算每一帧的点的位置。
  • build 方法:生成爱心的基本点、边缘扩散点和中心扩散点。
  • calc_position 方法:计算点的位置,根据点到中心点的距离和收缩比例来调整点的位置。
  • calc 方法:计算每一帧的点的位置和大小,通过曲线函数来控制跳动效果。
  • render 方法:将每一帧的点绘制到画布上。

8. 绘制动画

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
def draw(main: Tk, render_canvas: Canvas, render_heart: Heart, render_frame=0):
    render_canvas.delete('all')
    render_heart.render(render_canvas, render_frame)
    main.after(160, draw, main, render_canvas, render_heart, render_frame + 1)


if __name__ == '__main__':
    root = Tk()
    root.title("")
    canvas = Canvas(root, bg="black", height=CANVAS_HEIGHT, width=CANVAS_WIDTH)
    canvas.pack()
    heart = Heart()
    draw(root, canvas, heart)
    root.mainloop()

draw 函数用于绘制动画,通过定时调用自身来更新画面。在主程序中,我们创建了一个 Tkinter 窗口和画布,实例化了 Heart 类,并调用 draw 函数开始绘制动画。

9.最后代码:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
import random
from math import sin, cos, pi,log
from tkinter import *
CANVAS_WIDTH = 640
CANVAS_HEIGHT = 640
CANVAS_CENTER_X = CANVAS_WIDTH / 2
CANVAS_CENTER_Y = CANVAS_HEIGHT / 2
IMAGE_ENLARGE = 11
HEART_COLOR ="#Fd798f"
 
 
def heart_function(t,shrink_ratio:float = IMAGE_ENLARGE):
    x = 16*(sin(t)**3)
    y = -(15*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(3*t))
 
    x*=shrink_ratio
    y*=shrink_ratio
 
    x+=CANVAS_CENTER_X
    y+=CANVAS_CENTER_Y
    return int(x),int(y)
 
 
def scatter_inside(x,y,beta=0.15):
    ratio_x=-beta*log(random.random())
    ratio_y=-beta*log(random.random())
 
    dx=ratio_x*(x-CANVAS_CENTER_X)
    dy=ratio_y*(y-CANVAS_CENTER_Y)
    return x-dx,y-dy
 
 
def shrink(x,y,ratio):
    force=-1/(((x-CANVAS_CENTER_X)**2+(y-CANVAS_CENTER_Y)**2)**0.6)
 
    dx=ratio*force*(x-CANVAS_CENTER_X)
    dy=ratio*force*(y-CANVAS_CENTER_Y)
    return x-dx,y-dy
 
 
def curve(p):
    return 2*(2*sin(4*p))/(2*pi)
 
 
class Heart:
    def __init__(self,generate_frame=20):
        self._points=set()
        self._edge_diffusion_points=set()
        self._center_diffusion_points=set()
        self.all_points={}
        self.build(2000)
 
        self.random_halo=1000
        self.generate_frame=generate_frame
        for frame in range(generate_frame):
            self.calc(frame)
 
    def build(self,number):
        for _ in range(number):
            t=random.uniform(0,2*pi)
            x,y=heart_function(t)
            self._points.add((x,y))
 
        for _x, _y in list(self._points):
            for _ in range(3):
                x,y=scatter_inside(_x,_y,0.3)
                self._edge_diffusion_points.add((x,y))
        point_list=list(self._points)
        for _ in range(4000):
            x,y=random.choice(point_list)
            x,y=scatter_inside(x,y,0.2)
            self._center_diffusion_points.add((x,y))
 
 
    @staticmethod
    def calc_position(x,y,ratio):
        force=1/(((x-CANVAS_CENTER_X)**2+(y-CANVAS_CENTER_Y)**2)**0.520)
        dx=ratio*force*(x-CANVAS_CENTER_X)+random.randint(-2,2)
        dy=ratio*force*(y-CANVAS_CENTER_Y)+random.randint(-2,2)
        return x-dx,y-dy
 
    def calc(self,generate_frame):
        ratio=15*curve(generate_frame/15*pi)
        halo_radius=int(4+6*(1+curve(generate_frame/15*pi)))
        halo_number=int(3000+4000*abs(curve(generate_frame/15*pi)**2))
        all_points=[]
        heart_halo_point=set()
        for _ in range(halo_number):
            t=random.uniform(0,2*pi)
            x,y=heart_function(t,shrink_ratio=11.5)
            x,y=shrink(x,y,halo_radius)
            if (x,y) not in heart_halo_point:
                heart_halo_point.add((x,y))
                x+=random.randint(-16,16)
                y+=random.randint(-16,16)
                size=random.choice((2,2,1))
                all_points.append((x,y,size))
 
        for x,y in self._points:
            x,y=self.calc_position(x,y,ratio)
            size=random.randint(1,2)
            all_points.append((x,y,size))
 
        for x,y in self._edge_diffusion_points:
            x,y=self.calc_position(x,y,ratio)
            size=random.randint(1,2)
            all_points.append((x,y,size))
        # self.all_point[generate_frame]=all_points
        for x,y in self._center_diffusion_points:
            x,y=self.calc_position(x,y,ratio)
            size=random.randint(1,2)
            all_points.append((x,y,size))
        self.all_points[generate_frame]=all_points
 
    def render(self,render_canvas,render_frame):
        for x,y,size in self.all_points[render_frame % self.generate_frame]:
            render_canvas.create_rectangle(x,y,x+size,y+size,width=0,fill=HEART_COLOR)
 
 
def draw(main: Tk,render_canvas: Canvas,render_heart: Heart,render_frame=0):
        render_canvas.delete('all')
        render_heart.render(render_canvas,render_frame)
        main.after(160,draw,main,render_canvas,render_heart,render_frame+1)
 
 
if __name__=='__main__':
    root=Tk()
    root.title("")
    canvas=Canvas(root,bg="black",height=CANVAS_HEIGHT,width=CANVAS_WIDTH)
    canvas.pack()
    heart = Heart()
    draw(root,canvas,heart)
    root.mainloop()

演示结果

总结

通过以上步骤,我们使用 Python 实现了一个跳动的爱心效果。这个项目不仅展示了 Python 在图形绘制和动画实现方面的强大功能,还让我们学习到了数学函数在计算机图形学中的应用。你可以根据自己的需求调整代码中的参数,如爱心的颜色、大小、跳动的频率等,让爱心更加个性化。

希望这个教程能帮助你实现属于自己的浪漫代码!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
李峋同款爱心Python代码版来了
最近看到不少关于李峋同款爱心的视频、文章,今天我们也分享一下李峋同款爱心 Python 代码版。要问李峋是谁?我也不太清楚,大家可自行百度,这个是我百度的结果,仅供参考。
Python小二
2022/12/20
2.3K0
李峋同款爱心Python代码版来了
用Python制作一个动态爱心效果!
大概率是AE这种做特效软件实现的,毕竟里面的编程语言、编辑器、程序出现太多问题啦。
小F
2023/01/03
5.4K0
用Python制作一个动态爱心效果!
李峋同款爱心代码!跳动的心,给你爱的人一个惊喜!
Hello 大家好!!!再过一周马上就快要到三八女神节了。一年中女神最重要的几个节日:生日、情人节、三八、七夕,安排好了,你这一年就轻松好过多了,如果忘记了,那就。。。。。。。
北京-宏哥
2024/02/29
2.8K0
李峋同款爱心代码!跳动的心,给你爱的人一个惊喜!
李峋同款爱心Python代码版来了
init(self, generate_frame=20): 这是类的初始化方法,用于创建一个对象时进行一些初始设置。
老虎也淘气
2024/01/30
9.1K15
李峋同款爱心Python代码版来了
七夕最强Python表白代码来了
毫无疑问,玫瑰一直都是七夕、520......这类节日的专属,带文字的玫瑰花,文字可以根据节日自行更改。
Python小二
2023/09/11
1.9K0
七夕最强Python表白代码来了
背景代码磁力小棍棍JS代码
好玩的JS特效,可以当做背景使用,代码在下面,也可以到示例网站复制源代码 示例网站:www.catcool.cn/gg 代码: <body> <script> ! function() { //封装方法,压缩之后减少文件大小 function get_attribute(node, attr, default_value) { return node.getAttribute(attr) || default_value; } //封装方法,压缩之后减少文件大小 function get_by_tagnam
叮当叮
2020/04/20
1.4K0
背景代码磁力小棍棍JS代码
几个很有趣的python迷你程序
这个程序可以生成自己所定义的小二维码,里面可以是网页,可以是文字,自由选择,很好玩,具体大家自己搞哈~
柳神
2024/05/30
2040
【双十一特辑】爱心代码(程序员的浪漫)-李峋
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),字体色)
天寒雨落
2022/11/20
5.1K0
【双十一特辑】爱心代码(程序员的浪漫)-李峋
Python 烟花展示:使用 Pygame 创建绚丽的夜空
小白的大数据之旅
2024/11/20
1870
Python 烟花展示:使用 Pygame 创建绚丽的夜空
复制粘贴-实现动态爱心 网页版
上一篇的python爱心代码有很多读者反馈不会用。 本篇来一个小白版的,无需会代码,有浏览器就可以。 复制以下内容,保存为.html文件,双击打开即可出现动态爱心 <!DOCTYPE html> <html> <head> <title></title> <script src="js/jquery.min.js"></script> </head> <style> * { padding: 0; margin: 0; }
小黑同学
2022/11/16
2.3K0
复制粘贴-实现动态爱心 网页版
除夕用不同的语言编写绚丽的烟花
如果你不希望有ui界面上的文字,要纯的烟花,可以在js文件中将 S.UI.simulate(‘除夕节日快乐’);进行注释。
兰舟千帆
2022/07/16
1.9K0
除夕用不同的语言编写绚丽的烟花
爱心
想浪漫一点吗,今天教大家用前端编写一个爱心,就用简单的HTML、CSS和 JavaScript,创造一个简洁而浪漫的动画效果
找Bug
2025/03/27
1130
爱心
基于HTML5的爱心表白动画特效
从视觉上看,它也是一个爱心轮廓,但是不同的是这个爱心轮廓由许多跳动的小爱心组成,更加有一种3D立体的效果。
芯动大师
2022/11/20
2.8K0
利用python给女朋友放个烟花
python烟花代码 如下 # -*- coding: utf-8 -*- import math, random,time import threading import tkinter as tk import re #import uuid Fireworks=[] maxFireworks=8 height,width=600,600 class firework(object): def __init__(self,color,speed,width,height):
python亦希
2021/12/30
2.8K0
技术汇总:第七章:三种验证方式
更多内容请见原文,原文转载自:https://blog.csdn.net/weixin_44519496/article/details/120575426
马克社区
2023/01/06
3140
技术汇总:第七章:三种验证方式
星辰秘典:揭示Python项目的宇宙奥秘——宇宙星空模拟器(改)
宇宙星空模拟器是一个用Python和Pygame库创建的小型项目,它可以模拟宇宙中的星星、星系和星云,并展现出美丽的星空效果。通过这个模拟器,你可以欣赏到宇宙中的无尽星辰,感受宇宙的浩瀚和神秘。
命运之光
2024/03/20
2120
星辰秘典:揭示Python项目的宇宙奥秘——宇宙星空模拟器(改)
canvas实现验证码功能
我们在做一些后台系统登录功能的时候,一般都会用到验证码,最多的就是后台生成的验证码图片返回给前端的。也可以不调用后端接口,前端使用canvas直接生成验证码。
用户1174387
2018/10/08
1.6K0
canvas实现验证码功能
layUI登录界面验证码功能模块儿封装
第一种做法是把动态验证码的功能放到后台来做,每次刷新验码需要请求下后台。需额外给服务端造成点负担。
杨永贞
2020/08/04
2.9K1
Python 小型项目大全 16~20
自己创建这个程序的一个有用的方法是首先在你的编辑器中“画”几个大小的钻石,然后随着钻石变大,找出它们遵循的模式。这项技术将帮助您认识到菱形轮廓的每一行都有四个部分:前导空格数、外部正斜杠、内部空格数和外部反斜杠。实心钻石有几个内部正斜线和反斜线,而不是内部空间。破解这个模式就是我写diamonds.py的方法。
ApacheCN_飞龙
2023/04/12
6130
【愚公系列】2022年01月 Django商城项目07-注册界面-图片验证码
文章目录 一、图形验证码 1.依赖包安装 2.图形验证码封装 二、后端使用 备注:`具体的前端请求图片上篇已经给出` 一、图形验证码 1.依赖包安装 pip install pillow 2.图形验证码封装 import random import string import os.path from io import BytesIO from PIL import Image from PIL import ImageFilter from PIL.ImageDraw import Draw fro
愚公搬代码
2022/01/14
2330
相关推荐
李峋同款爱心Python代码版来了
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验