HTML5+原生JS和Canvas实现粒子动态小人比心网页

 简介

这是一个基于原生Web技术打造的创意交互动画,通过HTML5,Canvas和JavaScript实现了一个粒子化背景动态小人比心动画。项目将传统动画与粒子系统相结合,展现了Web前端技术的强大表现力,无需任何第三方框架即可实现流畅的视觉效果和用户交互。

 介绍

该网页代码精简(<5KB),现博主已经出社会工作了便没有闲暇时间去完善该网页,如果遇到需要修改的模块可自行优化。话不多说,直接上代码。

效果图 

 

HTML和CSS代码

首先,我们需要一个canvas元素和一个div元素;canvas用于在其中绘制烟花,这个元素会铺满整个屏幕。div用于在屏幕中显示动态GIF(此处的表情包可设置为自己喜欢的)。

<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background: white;
        }

        canvas {
            display: block;
        }

        .text-container {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            text-align: center;
            z-index: 1;
        }

    </style>
</head>
<body>
    <div class="text-container">
        <!-- 此处可插入文字 -->
        <img src="img/biubiubiu.gif" ondragstart='return false;'>
    </div>
    <canvas id="canvas" style="z-index:1"></canvas>
    <!-- JavaScript代码将在这里插入 -->
</body>
</html>

js代码

我们需要通过js为canvas定义宽度和高度,定义Heart和particle两个动态类,并通过一些定义每次的函数去控制它们。

 1,Heart类

这是定义的一个心形坠落粒子类,每次进入该页面会生成30组粒子由上到下呈现坠落效果,且会重复生成。

//心形坠落粒子类
class Heart {
        constructor() {
            this.reset();
            this.size = Math.random() * 20 + 10;
            this.color = `hsl(${Math.random() * 360}, 70%, 60%)`;
        }

        reset() {
            this.x = Math.random() * canvas.width;
            this.y = -50;
            this.speed = Math.random() * 2 + 1;
            this.angle = Math.random() * Math.PI * 2;
        }

        draw() {
            ctx.save();
            ctx.translate(this.x, this.y);
            ctx.rotate(this.angle);
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.bezierCurveTo(-10, -15, -25, -10, -5, -25);
            ctx.bezierCurveTo(15, -40, 25, -10, 0, 0);
            ctx.fillStyle = this.color;
            ctx.fill();
            ctx.restore();
        }

        update() {
            this.y += this.speed;
            this.angle += 0.02;
            if (this.y > canvas.height + 50) this.reset();
        }
    }

    const hearts = Array(30).fill().map(() => new Heart());

    function animate() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        hearts.forEach(heart => {
            heart.update();
            heart.draw();
        });
        particles.forEach((particle, index) => {
            particle.update();
            particle.draw();
            if (particle.alpha <= 0) {
                particles.splice(index, 1);
            }
        });

        requestAnimationFrame(animate);
    }

 2,particle类

 这是定义的点击爆炸烟花粒子类,进入网页后可点击鼠标生成爆炸烟花效果。

//爆炸烟花粒子类 
class Particle {
        constructor(x, y) {
            this.x = x;
            this.y = y;
            this.size = Math.random() * 5 + 2;
            this.speedX = Math.random() * 6 - 3;
            this.speedY = Math.random() * 6 - 3;
            this.color = `hsl(${Math.random() * 60 + 330}, 70%, 60%)`;
            this.alpha = 1;
        }

        update() {
            this.x += this.speedX;
            this.y += this.speedY;
            this.speedY += 0.1; // 重力效果
            this.alpha -= 0.02;
        }

        draw() {
            ctx.save();
            ctx.globalAlpha = this.alpha;
            ctx.beginPath();
            ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
            ctx.fillStyle = this.color;
            ctx.fill();
            ctx.restore();
        }
    }

    function createParticles(x, y) {
        for (let i = 0; i < 20; i++) {
            particles.push(new Particle(x, y));
        }
    }

    animate();

    canvas.addEventListener('click', (e) => {
        createParticles(e.clientX, e.clientY);
        hearts.forEach(heart => {
            const dx = e.clientX - heart.x;
            const dy = e.clientY - heart.y;
            const dist = Math.sqrt(dx * dx + dy * dy);
            if (dist < 100) {
                heart.x += dx * 0.02;
                heart.y += dy * 0.02;
            }
        });
    });

项目完整代码 

<!DOCTYPE html>
<html>
<head>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background: white;
        }

        canvas {
            display: block;
        }

        .text-container {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            text-align: center;
            z-index: 1;
        }

    </style>
</head>
<body>
    <div class="text-container">
        <!-- 此处可插入文字 -->
        <img src="img/biubiubiu.gif" ondragstart='return false;'>
    </div>
    <canvas id="canvas" style="z-index:1"></canvas>

    <script>
        var canvas = document.getElementById('canvas');
        var ctx = canvas.getContext('2d');
        var particles = [];

        function resizeCanvas() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        }
        resizeCanvas();
        window.addEventListener('resize', resizeCanvas);

        class Heart {
            constructor() {
                this.reset();
                this.size = Math.random() * 20 + 10;
                this.color = `hsl(${Math.random() * 360}, 70%, 60%)`;
            }

            reset() {
                this.x = Math.random() * canvas.width;
                this.y = -50;
                this.speed = Math.random() * 2 + 1;
                this.angle = Math.random() * Math.PI * 2;
            }

            draw() {
                ctx.save();
                ctx.translate(this.x, this.y);
                ctx.rotate(this.angle);
                ctx.beginPath();
                ctx.moveTo(0, 0);
                ctx.bezierCurveTo(-10, -15, -25, -10, -5, -25);
                ctx.bezierCurveTo(15, -40, 25, -10, 0, 0);
                ctx.fillStyle = this.color;
                ctx.fill();
                ctx.restore();
            }

            update() {
                this.y += this.speed;
                this.angle += 0.02;
                if (this.y > canvas.height + 50) this.reset();
            }
        }

        var hearts = Array(30).fill().map(() => new Heart());

        function animate() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            hearts.forEach(heart => {
                heart.update();
                heart.draw();
            });

            particles.forEach((particle, index) => {
                particle.update();
                particle.draw();
                if (particle.alpha <= 0) {
                   particles.splice(index, 1);
                }
            });

            requestAnimationFrame(animate);
        }

        class Particle {
            constructor(x, y) {
                this.x = x;
                this.y = y;
                this.size = Math.random() * 5 + 2;
                this.speedX = Math.random() * 6 - 3;
                this.speedY = Math.random() * 6 - 3;
                this.color = `hsl(${Math.random() * 60 + 330}, 70%, 60%)`;
                this.alpha = 1;
            }

            update() {
                this.x += this.speedX;
                this.y += this.speedY;
                this.speedY += 0.1; // 重力效果
                this.alpha -= 0.02;
            }

            draw() {
                ctx.save();
                ctx.globalAlpha = this.alpha;
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
                ctx.fillStyle = this.color;
                ctx.fill();
                ctx.restore();
            }
        }

        function createParticles(x, y) {
            for (let i = 0; i < 20; i++) {
                particles.push(new Particle(x, y));
            }
        }

        animate();

        canvas.addEventListener('click', (e) => {
            createParticles(e.clientX, e.clientY);
            hearts.forEach(heart => {
                var dx = e.clientX - heart.x;
                var dy = e.clientY - heart.y;
                var dist = Math.sqrt(dx * dx + dy * dy);
                if (dist < 100) {
                    heart.x += dx * 0.02;
                    heart.y += dy * 0.02;
                }
            });
        });

    </script>
</body>
</html>

总结

通过使用HTML5,Canvas和JavaScript,我们成功地创建了一个粒子动态小人比心网页。你可以根据自己的喜好调整粒子数量、速度和颜色等参数,创造出更多样化的效果。本文到此已结束,谢谢观看!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值