程序猿也懂浪漫,情人节将至,为她献上一款量身定制的爱心吧。

       情人节是一个表达爱意的好机会,作为一名程序猿,平时经常会被吐槽木讷不懂浪漫,2.14号即将到来,让我们来一次绝地反击吧,用我们的技术展现浓浓的的爱意,利用Python和HTML制作一个独特的情人节告白爱心,相信一定能打动你的那个她。

文章目录

一、Python实现(电视剧《点燃我,温暖你》版本)跳动的爱心

1.效果预览:

2.代码分步介绍:

3.完整代码:复制后可直接运行 !!!

二、用HTML实现扩散的爱心

1.效果预览:

2.个性化:

3.完整代码:复制后可直接保存成HTML格式 !!!

三、结语:记得点赞关注加收藏哦!!!


一、Python实现(电视剧《点燃我,温暖你》版本)跳动的爱心

1.效果预览:

2.代码分步介绍:

1)模块导入:

主要用到tkinter模块,Python的GUI工具包接口。

import random

from math import sin, cos, pi, log

from tkinter import *

2)形状颜色设置:

长宽、颜色都可以自己修改,颜色的具体参数可以参考:tkinter中颜色的代码

#FFB6C1 LightPink 浅粉红          #FFC0CB Pink 粉红
#DC143C Crimson 深红/猩红         #FF69B4 HotPink 热情的粉红
#C71585 MediumVioletRed 中紫罗兰红       #DA70D6 Orchid 暗紫色/兰花紫
#DDA0DD Plum 洋李色/李子紫 #EE82EE Violet 紫罗兰
#FF00FF Magenta 洋红/玫瑰红            #FF00FF Fuchsia 紫红/灯笼海棠
#8B008B DarkMagenta 深洋红        #800080 Purple 紫色
#BA55D3 MediumOrchid 中兰花紫       #9400D3 DarkViolet 暗紫罗兰
#4B0082 Indigo 靛青/紫兰色           #8A2BE2 BlueViolet 蓝紫罗兰
#9370DB MediumPurple 中紫色        #7B68EE MediumSlateBlue 中暗蓝色/中板岩蓝
#483D8B DarkSlateBlue 暗灰蓝色/暗板岩蓝   #E6E6FA Lavender 淡紫色/熏衣草淡紫
#000080 Navy 海军蓝            #4169E1 RoyalBlue 皇家蓝/宝蓝
#6495ED CornflowerBlue 矢车菊蓝        #B0C4DE LightSteelBlue 亮钢蓝
#778899 LightSlateGray 亮蓝灰/亮石板灰    #1E90FF DodgerBlue 闪兰色/道奇蓝
#F0F8FF AliceBlue 爱丽丝蓝            #4682B4 SteelBlue 钢蓝/铁青
#87CEFA LightSkyBlue 亮天蓝色        #87CEEB SkyBlue 天蓝色
#00BFFF DeepSkyBlue 深天蓝            #B0E0E6 PowderBlue 粉蓝色/火药青
#5F9EA0 CadetBlue 军兰色/军服蓝        #F0FFFF Azure 蔚蓝色
#E0FFFF LightCyan 淡青色            #AFEEEE PaleTurquoise 弱绿宝石
#00FFFF Cyan 青色               #00FFFF Aqua 浅绿色/水色
#00CED1 DarkTurquoise 暗绿宝石        #48D1CC MediumTurquoise 中绿宝石
#40E0D0 Turquoise 绿宝石            #7FFFD4 Aquamarine 宝石碧绿
#66CDAA MediumAquamarine 中宝石碧绿         #20B2AA LightSeaGreen 浅海洋绿
#00FA9A MediumSpringGreen 中春绿色        #F5FFFA MintCream 薄荷奶油
#00FF7F SpringGreen 春绿色            #3CB371 MediumSeaGreen 中海洋绿
#98FB98 PaleGreen 弱绿色            #8FBC8F DarkSeaGreen 暗海洋绿
#00FF00 Lime 闪光绿            #228B22 ForestGreen 森林绿
#006400 DarkGreen 暗绿色            #7FFF00 Chartreuse 黄绿色/查特酒绿
#7CFC00 LawnGreen 草绿色/草坪绿        #ADFF2F GreenYellow 绿黄色
#6B8E23 OliveDrab 橄榄褐色            #808000 Olive 橄榄
#BDB76B DarkKhaki 暗黄褐色/深卡叽布        #FFFACD LemonChiffon 柠檬绸
#FFD700 Gold 金色                #DAA520 Goldenrod 金菊黄
#FFE4B5 Moccasin 鹿皮色/鹿皮靴       #FFA500 Orange 橙色
#FFEFD5 PapayaWhip 番木色/番木瓜        #FF8C00 DarkOrange 深橙色
#FFDAB9 PeachPuff 桃肉色            #F4A460 SandyBrown 沙棕色
#D2691E Chocolate 巧克力色            #8B4513 SaddleBrown 重褐色/马鞍棕色
#FFF5EE Seashell 海贝壳            #FF7F50 Coral 珊瑚
#FF4500 OrangeRed 橙红色            #E9967A DarkSalmon 深鲜肉/鲑鱼色
#FF6347 Tomato 番茄红           #FFE4E1 MistyRose 浅玫瑰色/薄雾玫瑰
#8B0000 DarkRed 深红色            #DCDCDC Gainsboro 淡灰色
#D3D3D3 LightGrey 浅灰色            #C0C0C0 Silver 银灰色
CANVAS_WIDTH = 1280  # 宽

CANVAS_HEIGHT = 840  # 高

CANVAS_CENTER_X = CANVAS_WIDTH / 2

CANVAS_CENTER_Y = CANVAS_HEIGHT / 2

IMAGE_ENLARGE = 12  # 放大比例

HEART_COLOR = "#FFB6C1"

3)爱心类:

定义一个爱心的类,里面包含实现爱心的轮廓、缩放,扩散,光环等函数。

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.05)

                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.17)

            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(-1, 1)

        dy = ratio * force * (y - CANVAS_CENTER_Y) + random.randint(-1, 1)

        return x - dx, y - dy

    def calc(self, generate_frame):

        ratio = 10 * curve(generate_frame / 10 * pi)  # 圆滑的周期的缩放比例

        halo_radius = int(4 + 6 * (1 + curve(generate_frame / 10 * pi)))

        halo_number = int(3000 + 4000 * abs(curve(generate_frame / 10 * 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.6)  # 魔法参数

            x, y = shrink(x, y, halo_radius)

            if (x, y) not in heart_halo_point:
                # 处理新的点

                heart_halo_point.add((x, y))

                x += random.randint(-14, 14)

                y += random.randint(-14, 14)

                size = random.choice((1, 2, 2))

                all_points.append((x, y, size))

        # 轮廓

        for x, y in self._points:
            x, y = self.calc_position(x, y, ratio)

            size = random.randint(1, 3)

            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)

4)生成爱心函数:

生成爱心的函数主要用来计算粒子的坐标位置

def heart_function(t, shrink_ratio: float = IMAGE_ENLARGE):
    """
    “爱心函数生成器”
    :param shrink_ratio: 放大比例
    :param t: 参数
    :return: 坐标
    """

    # 基础函数

    x = 16 * (sin(t) ** 3)

    y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * 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):
    """
    随机内部扩散
    :param x: 原x
    :param y: 原y
    :param beta: 强度
    :return: 新坐标
    """

    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):
    """
    抖动
    :param x: 原x
    :param y: 原y
    :param ratio: 比例
    :return: 新坐标
    """

    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):
    """
    自定义曲线函数,调整跳动周期
    :param p: 参数
    :return: 正弦
    """

    return 2 * (2 * sin(4 * p)) / (2 * pi)

5)主函数入口:

if __name__ == '__main__':
    root = Tk()  # 一个Tk

    canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)

    canvas.pack()

    heart = Heart()  # 心

    draw(root, canvas, heart)

    root.mainloop()

3.完整代码:复制后可直接运行 !!!

import random

from math import sin, cos, pi, log

from tkinter import *

CANVAS_WIDTH = 1280  # 宽

CANVAS_HEIGHT = 840  # 高

CANVAS_CENTER_X = CANVAS_WIDTH / 2

CANVAS_CENTER_Y = CANVAS_HEIGHT / 2

IMAGE_ENLARGE = 12  # 放大比例

HEART_COLOR = "#FFB6C1"


def heart_function(t, shrink_ratio: float = IMAGE_ENLARGE):
    """
    “爱心函数生成器”
    :param shrink_ratio: 放大比例
    :param t: 参数
    :return: 坐标
    """

    # 基础函数

    x = 16 * (sin(t) ** 3)

    y = -(13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * 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):
    """
    随机内部扩散
    :param x: 原x
    :param y: 原y
    :param beta: 强度
    :return: 新坐标
    """

    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):
    """
    抖动
    :param x: 原x
    :param y: 原y
    :param ratio: 比例
    :return: 新坐标
    """

    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):
    """
    自定义曲线函数,调整跳动周期
    :param p: 参数
    :return: 正弦
    """

    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.05)

                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.17)

            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(-1, 1)

        dy = ratio * force * (y - CANVAS_CENTER_Y) + random.randint(-1, 1)

        return x - dx, y - dy

    def calc(self, generate_frame):

        ratio = 10 * curve(generate_frame / 10 * pi)  # 圆滑的周期的缩放比例

        halo_radius = int(4 + 6 * (1 + curve(generate_frame / 10 * pi)))

        halo_number = int(3000 + 4000 * abs(curve(generate_frame / 10 * 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.6)  # 魔法参数

            x, y = shrink(x, y, halo_radius)

            if (x, y) not in heart_halo_point:
                # 处理新的点

                heart_halo_point.add((x, y))

                x += random.randint(-14, 14)

                y += random.randint(-14, 14)

                size = random.choice((1, 2, 2))

                all_points.append((x, y, size))

        # 轮廓

        for x, y in self._points:
            x, y = self.calc_position(x, y, ratio)

            size = random.randint(1, 3)

            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)


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()  # 一个Tk

    canvas = Canvas(root, bg='black', height=CANVAS_HEIGHT, width=CANVAS_WIDTH)

    canvas.pack()

    heart = Heart()  # 心

    draw(root, canvas, heart)

    root.mainloop()

二、用HTML实现扩散的爱心

可以直接保存成HTML格式,发送给心爱的她,当她点开网址后一定能感受到惊喜,实测有效!!

1.效果预览:

2.个性化:

1)可以在在下图body标签下<p>     </p>中插入你想对心仪的她说的话!

2)同时可以调整下列参数实现爱心展现形式的个性化

3.完整代码:复制后可直接保存成HTML格式 !!!

<html>
<head>
    <meta charset="utf-8">
    <title>loveHeart</title>
    <link rel="shortcut icon" href="http://zhouql.vip/images/心.png" type="image/x-icon">
    <style>
        html,
        body {
            height: 100%;
            padding: 0;
            margin: 0;
            background: #000;
        }
        canvas {
            position: absolute;
            width: 100%;
            height: 100%;
        }
        p{
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%,-50%);
            color: pink;
            animation: k 1.5s ease-in-out infinite;
        }
        @keyframes k{
            100%{
                font-size: 24px;
                opacity: 0;
            }
        }
    </style>
</head>
<body>
    <p></p>
    <canvas id="pinkboard"></canvas>
    <script>
        var settings = {
            particles: {
                length: 600,  // 爱心的大小
                duration: 2.5,  // 爱心扩散速度,越小速度越快
                velocity: 100,  // 爱心扩散速度,越小速度越慢
                effect: -0.8, // 爱心收缩效果,比如:1扩散,-2收缩
                size: 28, // 爱心数量
            },
        };
        (function () { var b = 0; var c = ["ms", "moz", "webkit", "o"]; for (var a = 0; a < c.length && !window.requestAnimationFrame; ++a) { window.requestAnimationFrame = window[c[a] + "RequestAnimationFrame"]; window.cancelAnimationFrame = window[c[a] + "CancelAnimationFrame"] || window[c[a] + "CancelRequestAnimationFrame"] } if (!window.requestAnimationFrame) { window.requestAnimationFrame = function (h, e) { var d = new Date().getTime(); var f = Math.max(0, 16 - (d - b)); var g = window.setTimeout(function () { h(d + f) }, f); b = d + f; return g } } if (!window.cancelAnimationFrame) { window.cancelAnimationFrame = function (d) { clearTimeout(d) } } }());

        var Point = (function () {
            function Point(x, y) {
                this.x = (typeof x !== 'undefined') ? x : 0;
                this.y = (typeof y !== 'undefined') ? y : 0;
            }
            Point.prototype.clone = function () {
                return new Point(this.x, this.y);
            };
            Point.prototype.length = function (length) {
                if (typeof length == 'undefined')
                    return Math.sqrt(this.x * this.x + this.y * this.y);
                this.normalize();
                this.x *= length;
                this.y *= length;
                return this;
            };
            Point.prototype.normalize = function () {
                var length = this.length();
                this.x /= length;
                this.y /= length;
                return this;
            };
            return Point;
        })();
        var Particle = (function () {
            function Particle() {
                this.position = new Point();
                this.velocity = new Point();
                this.acceleration = new Point();
                this.age = 0;
            }
            Particle.prototype.initialize = function (x, y, dx, dy) {
                this.position.x = x;
                this.position.y = y;
                this.velocity.x = dx;
                this.velocity.y = dy;
                this.acceleration.x = dx * settings.particles.effect;
                this.acceleration.y = dy * settings.particles.effect;
                this.age = 0;
            };
            Particle.prototype.update = function (deltaTime) {
                this.position.x += this.velocity.x * deltaTime;
                this.position.y += this.velocity.y * deltaTime;
                this.velocity.x += this.acceleration.x * deltaTime;
                this.velocity.y += this.acceleration.y * deltaTime;
                this.age += deltaTime;
            };
            Particle.prototype.draw = function (context, image) {
                function ease(t) {
                    return (--t) * t * t + 1;
                }
                var size = image.width * ease(this.age / settings.particles.duration);
                context.globalAlpha = 1 - this.age / settings.particles.duration;
                context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);
            };
            return Particle;
        })();
        var ParticlePool = (function () {
            var particles,
                firstActive = 0,
                firstFree = 0,
                duration = settings.particles.duration;
            function ParticlePool(length) {
                // create and populate particle pool
                particles = new Array(length);
                for (var i = 0; i < particles.length; i++)
                    particles[i] = new Particle();
            }
            ParticlePool.prototype.add = function (x, y, dx, dy) {
                particles[firstFree].initialize(x, y, dx, dy);
                // handle circular queue
                firstFree++;
                if (firstFree == particles.length) firstFree = 0;
                if (firstActive == firstFree) firstActive++;
                if (firstActive == particles.length) firstActive = 0;
            };
            ParticlePool.prototype.update = function (deltaTime) {
                var i;
                // update active particles
                if (firstActive < firstFree) {
                    for (i = firstActive; i < firstFree; i++)
                        particles[i].update(deltaTime);
                }
                if (firstFree < firstActive) {
                    for (i = firstActive; i < particles.length; i++)
                        particles[i].update(deltaTime);
                    for (i = 0; i < firstFree; i++)
                        particles[i].update(deltaTime);
                }
                // remove inactive particles
                while (particles[firstActive].age >= duration && firstActive != firstFree) {
                    firstActive++;
                    if (firstActive == particles.length) firstActive = 0;
                }
            };
            ParticlePool.prototype.draw = function (context, image) {
                // draw active particles
                if (firstActive < firstFree) {
                    for (i = firstActive; i < firstFree; i++)
                        particles[i].draw(context, image);
                }
                if (firstFree < firstActive) {
                    for (i = firstActive; i < particles.length; i++)
                        particles[i].draw(context, image);
                    for (i = 0; i < firstFree; i++)
                        particles[i].draw(context, image);
                }
            };
            return ParticlePool;
        })();
        (function (canvas) {
            var context = canvas.getContext('2d'),
                particles = new ParticlePool(settings.particles.length),
                particleRate = settings.particles.length / settings.particles.duration, // particles/sec
                time;
            // get point on heart with -PI <= t <= PI
            function pointOnHeart(t) {
                return new Point(
                    160 * Math.pow(Math.sin(t), 3),
                    130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25
                );
            }
            // creating the particle image using a dummy canvas
            var image = (function () {
                var canvas = document.createElement('canvas'),
                    context = canvas.getContext('2d');
                canvas.width = settings.particles.size;
                canvas.height = settings.particles.size;
                // helper function to create the path
                function to(t) {
                    var point = pointOnHeart(t);
                    point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;
                    point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;
                    return point;
                }
                // create the path
                context.beginPath();
                var t = -Math.PI;
                var point = to(t);
                context.moveTo(point.x, point.y);
                while (t < Math.PI) {
                    t += 0.01; // baby steps!
                    point = to(t);
                    context.lineTo(point.x, point.y);
                }
                context.closePath();
                // create the fill
                context.fillStyle = '#ea80b0';
                context.fill();
                // create the image
                var image = new Image();
                image.src = canvas.toDataURL();
                return image;
            })();
            // render that thing!
            function render() {
                // next animation frame
                requestAnimationFrame(render);
                // update time
                var newTime = new Date().getTime() / 1000,
                    deltaTime = newTime - (time || newTime);
                time = newTime;
                // clear canvas
                context.clearRect(0, 0, canvas.width, canvas.height);
                // create new particles
                var amount = particleRate * deltaTime;
                for (var i = 0; i < amount; i++) {
                    var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());
                    var dir = pos.clone().length(settings.particles.velocity);
                    particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);
                }
                // update and draw particles
                particles.update(deltaTime);
                particles.draw(context, image);
            }
            // handle (re-)sizing of the canvas
            function onResize() {
                canvas.width = canvas.clientWidth;
                canvas.height = canvas.clientHeight;
            }
            window.onresize = onResize;
            // delay rendering bootstrap
            setTimeout(function () {
                onResize();
                render();
            }, 10);
        })(document.getElementById('pinkboard'));
        </script>
</body>

</html>

三、结语:记得点赞关注加收藏哦!!!

两个爱心版本实测都可以完美运行,完整代码如上,免费共享,给大家借鉴参考!有需要的伙伴们可以自行下载研究,共同努力共同学习!记得点赞+关注+收藏哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值