爱心气泡表白代码-HTML【附源码】

简介: 每戳破一颗爱心气泡,都会有一句专属于你的情话悄然绽放~愿天下有情人终成眷属

一:效果展示

P51emFS8_converted.gif

二:核心动画

(1)交互功能:

  • 爱心被点击后触发爆炸并生成情话文字

(2)爱心气泡动画:

  • 在随机位置生成多种颜色多种样式不同大小(32px~64px)的爱心
  • 爱心从屏幕底部缓慢上升到顶部,同时旋转360度并逐渐透明
  • 限制屏幕内最大爱心数量为30,避免卡顿

(3)随机情话文字:

  • 点击爱心时在爆炸位置显示情话
  • 从预设的文案中随机选择生成(如:我爱你;遇见你真好....等)
  • 随机颜色和字体大小(16px~22px)增强视觉层次

(4)背景特效:

  • 使用linear-gradient创建粉色系渐变天空(#ff9a9e → #fad0c4)
  • 通过JavaScript动态生成30个随机位置、大小、颜色的圆形星星(div.star
  • 应用twinkle动画让星星闪烁(缩放+透明度变化)

三:完整代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>多彩爱心气泡上升动画</title>
    <style>
        body {
    
            margin: 0;
            padding: 0;
            overflow: hidden;
            height: 100vh;
            background: linear-gradient(45deg, #ff9a9e 0%, #fad0c4 99%, #fad0c4 100%);
        }

        .floating-heart {
    
            position: fixed;
            font-size: 24px;
            z-index: 1000;
            pointer-events: auto; 
            cursor: default; 
            transform: translateY(100vh) rotate(0deg);
            opacity: 0;
            animation: floatHeart linear forwards;
            will-change: transform, opacity;
            transition: transform 0.2s ease, opacity 0.2s ease; 
        }

        @keyframes floatHeart {
    
            0% {
    
                transform: translateY(100vh) rotate(0deg);
                opacity: 1;
            }
            100% {
    
                transform: translateY(-100px) rotate(360deg);
                opacity: 0;
            }
        }

        @keyframes burstHeart {
    
            0% {
    
                transform: translate(-50%, -50%) scale(1) rotate(0deg);
                opacity: 1;
            }
            30% {
    
                transform: translate(-50%, -50%) scale(1.8) rotate(180deg);
                opacity: 0.9;
            }
            100% {
    
                transform: translate(-50%, -50%) scale(0) rotate(360deg);
                opacity: 0;
            }
        }

        .love-text {
    
            position: fixed;
            font-size: 18px;
            color: #fff;
            font-family: "Microsoft Yahei", sans-serif;
            text-shadow: 0 0 5px rgba(0,0,0,0.3);
            z-index: 1001;
            pointer-events: none;
            opacity: 0;
            animation: loveTextFade 1s ease forwards;
            transform: translate(-50%, -50%); 
        }

        @keyframes loveTextFade {
    
            0% {
    
                transform: translate(-50%, -50%) scale(0);
                opacity: 1;
            }
            50% {
    
                transform: translate(-50%, -50%) scale(1.2);
                opacity: 1;
            }
            100% {
    
                transform: translate(-50%, -50%) scale(0);
                opacity: 0;
            }
        }
        .star {
    
            position: absolute;
            background-color: #fff;
            border-radius: 50%;
            z-index: 1;
            animation: twinkle infinite;
        }

        @keyframes twinkle {
    
            0%, 100% {
     opacity: 0.3; transform: scale(0.8); }
            50% {
     opacity: 1; transform: scale(1.2); }
        }
    </style>
</head>
<body>
    <div class="bg-animation" id="bgAnimation"></div>

    <script>
        const config = {
    
            bgStarCount: 30,
            maxHeartsOnScreen: 30,
            heartSizeRange: [32, 64],
            animationDurationRange: [8, 15],
            spawnInterval: 500,
            heartSymbols: ['❤️', '💖', '💘', '💝', '💓', '💗', '💕', '💙', '💛', '💜', '💚'],
            heartColors: [
                '#ff69b4', '#ff1493', '#ff4500', '#ffd700', '#ff8c00',
                '#ff6347', '#dc143c', '#c71585', '#ff00ff', '#9370db',
                '#00bfff', '#00fa9a', '#ff7f50', '#ff6eb4', '#ff91a4'
            ],
            loveTexts: [
    "我爱你", "喜欢你", "心动了", "遇见你真好", "满心欢喜",
    "余生都是你", "满眼都是你", "超喜欢你", "你最珍贵", "甜蜜暴击",
    "心有灵犀", "双向奔赴", "温柔以待", "人间理想", "甜度超标",
    "星河万顷都是你", "万物不及你", "为你心动", "浪漫不渝", "岁岁年年",
    "你是我的例外与偏爱", "想和你共度每一个晨昏", "你的笑容是我每日的阳光",
    "遇见你,是我这辈子最美的意外", "我的世界因你而完整", "你是我所有的少女心和英雄梦",
    "想牵你的手,从心动到古稀", "你是我平淡岁月里的心之所向", "我贪恋的人间烟火,不偏不倚全是你",
    "你是我疲惫生活中的温柔梦想", "想和你一起浪费时光,直到时光的尽头", "我的宇宙里,你是最亮的星",
    "你是我漫漫余生里斩钉截铁的梦想", "想和你一起看遍世间风景,然后只与你细水长流",
    "你是我疲惫生活中的唯一解药", "我的喜欢写在风里,从此整个世界都是你",
    "你是我所有温柔与浪漫的源头", "想和你一起虚度短的沉默,长的无意义,一起消磨精致而苍老的宇宙",
    "你是我灵魂的归宿,是我一生的守候", "我的爱意汹涌,看世间万物都浪漫心动",
    "你是我平淡岁月里的星辰大海", "想和你一起走过四季,看遍人间烟火",
    "你是我所有美好与幸运的起点", "我的世界很小,小到只能装下你一个人",
    "你是我疲惫生活中的不期而遇", "想和你一起慢慢变老,直到哪里也去不了"
]

        };

        let activeHearts = 0;
        let allHearts = [];

        function createBackgroundStars() {
    
            const bgAnimation = document.getElementById('bgAnimation');

            for (let i = 0; i < config.bgStarCount; i++) {
    
                const star = document.createElement('div');
                star.className = 'star';
                const size = Math.random() * 3 + 1;
                star.style.width = `${
      size}px`;
                star.style.height = `${
      size}px`;
                star.style.left = `${
      Math.random() * 100}%`;
                star.style.top = `${
      Math.random() * 100}%`;
                star.style.animationDuration = `${
      Math.random() * 3 + 2}s`;
                star.style.animationDelay = `${
      Math.random() * 5}s`;
                star.style.backgroundColor = `hsl(${
      Math.random() * 360}, 80%, 80%)`;

                bgAnimation.appendChild(star);
            }
        }

        function createLoveText(x, y) {
    
            const text = document.createElement('div');
            text.className = 'love-text';
            const randomText = config.loveTexts[Math.floor(Math.random() * config.loveTexts.length)];
            text.innerText = randomText;
            text.style.left = `${
      x}px`;
            text.style.top = `${
      y}px`;
            const randomColor = config.heartColors[Math.floor(Math.random() * config.heartColors.length)];
            text.style.color = randomColor;
            const fontSize = Math.random() * 6 + 16;
            text.style.fontSize = `${
      fontSize}px`;
            document.body.appendChild(text);

            setTimeout(() => {
    
                if (text.parentNode) {
    
                    text.parentNode.removeChild(text);
                }
            }, 1000);
        }

        function handleHeartClick(e) {
    
            const heart = e.target;
            const rect = heart.getBoundingClientRect();
            const centerX = rect.left + rect.width / 2;
            const centerY = rect.top + rect.height / 2;
            heart.style.animation = 'none';
            heart.style.transition = 'none';
            heart.style.left = `${
      centerX}px`;
            heart.style.top = `${
      centerY}px`;
            heart.style.transform = 'translate(-50%, -50%)';
            heart.style.animation = 'burstHeart 0.5s ease forwards';
            createLoveText(centerX, centerY);

            setTimeout(() => {
    
                if (heart.parentNode) {
    
                    heart.parentNode.removeChild(heart);
                }
                activeHearts = Math.max(0, activeHearts - 1);
                allHearts = allHearts.filter(h => h !== heart);
            }, 500);
        }

        function createHeart() {
    
            if (activeHearts >= config.maxHeartsOnScreen) return;
            activeHearts++;
            const heart = document.createElement('div');
            heart.className = 'floating-heart';
            const randomSymbol = config.heartSymbols[Math.floor(Math.random() * config.heartSymbols.length)];
            heart.innerHTML = randomSymbol;
            const randomColor = config.heartColors[Math.floor(Math.random() * config.heartColors.length)];
            heart.style.color = randomColor;
            const leftPos = Math.random() * (window.innerWidth - 60) + 30;
            heart.style.left = `${
      leftPos}px`;
            const size = Math.random() * (config.heartSizeRange[1] - config.heartSizeRange[0]) + config.heartSizeRange[0];
            heart.style.fontSize = `${
      size}px`;
            const duration = Math.random() * (config.animationDurationRange[1] - config.animationDurationRange[0]) + config.animationDurationRange[0];
            heart.style.animationDuration = `${
      duration}s`;
            const rotationDirection = Math.random() > 0.5 ? 1 : -1;
            heart.style.setProperty('--rotation', `${
      360 * rotationDirection}deg`);
            heart.addEventListener('click', handleHeartClick);
            document.body.appendChild(heart);
            allHearts.push(heart);

            heart.addEventListener('animationend', function(e) {
    
                if (e.animationName === 'floatHeart') {
    
                    if (heart.parentNode) {
    
                        heart.parentNode.removeChild(heart);
                    }
                    activeHearts = Math.max(0, activeHearts - 1);
                    allHearts = allHearts.filter(h => h !== heart);
                }
            });
        }

        function startHeartSpawner() {
    
            for (let i = 0; i < config.maxHeartsOnScreen / 2; i++) {
    
                setTimeout(createHeart, i * config.spawnInterval / 2);
            }

            setInterval(createHeart, config.spawnInterval);
        }

        window.addEventListener('resize', () => {
    
            allHearts.forEach(heart => {
    
                if (heart.parentNode) {
    
                    heart.parentNode.removeChild(heart);
                }
            });

            activeHearts = 0;
            allHearts = [];
            startHeartSpawner();
        });

        window.addEventListener('load', () => {
    
            createBackgroundStars();
            startHeartSpawner();
        });
    </script>
</body>
</html>

四:代码分析

(1)爱心动画模块

        /* 浮动爱心基础样式 */
        .floating-heart {
   
            position: fixed;
            font-size: 24px;
            z-index: 1000;
            pointer-events: auto; /* 允许点击事件 */
            cursor: default; 
            transform: translateY(100vh) rotate(0deg); /* 初始位置在底部 */
            opacity: 0;
            animation: floatHeart linear forwards; /* 应用上升动画 */
            will-change: transform, opacity; /* 优化动画性能 */
            transition: transform 0.2s ease, opacity 0.2s ease; /* 平滑过渡效果 */
        }

        /* 爱心上升动画 */
        @keyframes floatHeart {
   
            0% {
   
                transform: translateY(100vh) rotate(0deg); /* 从底部开始 */
                opacity: 1;
            }
            100% {
   
                transform: translateY(-100px) rotate(360deg); /* 上升到顶部并旋转一圈 */
                opacity: 0; /* 逐渐消失 */
            }
        }

        /* 爱心点击爆炸动画 */
        @keyframes burstHeart {
   
            0% {
   
                transform: translate(-50%, -50%) scale(1) rotate(0deg);
                opacity: 1;
            }
            30% {
   
                transform: translate(-50%, -50%) scale(1.8) rotate(180deg); /* 放大并旋转 */
                opacity: 0.9;
            }
            100% {
   
                transform: translate(-50%, -50%) scale(0) rotate(360deg); /* 缩小消失 */
                opacity: 0;
            }
        }

        /* 爱心文字样式 */
        .love-text {
   
            position: fixed;
            font-size: 18px;
            color: #fff;
            font-family: "Microsoft Yahei", sans-serif;
            text-shadow: 0 0 5px rgba(0,0,0,0.3); /* 文字阴影 */
            z-index: 1001;
            pointer-events: none; /* 禁止点击事件 */
            opacity: 0;
            animation: loveTextFade 1s ease forwards; /* 淡入淡出动画 */
            transform: translate(-50%, -50%); /* 居中定位 */
        }

        /* 文字淡入淡出动画 */
        @keyframes loveTextFade {
   
            0% {
   
                transform: translate(-50%, -50%) scale(0); /* 从缩小开始 */
                opacity: 1;
            }
            50% {
   
                transform: translate(-50%, -50%) scale(1.2); /* 放大效果 */
                opacity: 1;
            }
            100% {
   
                transform: translate(-50%, -50%) scale(0); /* 缩小消失 */
                opacity: 0;
            }
        }

(2)配置对象

        // 配置对象,集中管理所有可配置参数
        const config = {
   
            bgStarCount: 30, // 背景星星数量
            maxHeartsOnScreen: 30, // 屏幕上最大爱心数量
            heartSizeRange: [32, 64], // 爱心大小范围(px)
            animationDurationRange: [8, 15], // 动画持续时间范围(s)
            spawnInterval: 500, // 爱心生成间隔(ms)
            heartSymbols: ['❤️', '💖', '💘', '💝', '💓', '💗', '💕', '💙', '💛', '💜', '💚'], // 爱心符号集合
            heartColors: [ // 爱心颜色集合
                '#ff69b4', '#ff1493', '#ff4500', '#ffd700', '#ff8c00',
                '#ff6347', '#dc143c', '#c71585', '#ff00ff', '#9370db',
                '#00bfff', '#00fa9a', '#ff7f50', '#ff6eb4', '#ff91a4'
            ],
            loveTexts: [ // 点击爱心后显示的文字集合
                "我爱你", "喜欢你", "心动了", "遇见你真好", "满心欢喜",
                "余生都是你", "满眼都是你", "超喜欢你", "你最珍贵", "甜蜜暴击",
                // 更多文字...
            ]
        };

        let activeHearts = 0; // 当前屏幕上活跃的爱心数量
        let allHearts = []; // 存储所有爱心元素的数组

(3)背景星星模块

        function createBackgroundStars() {
   
            const bgAnimation = document.getElementById('bgAnimation');
            for (let i = 0; i < config.bgStarCount; i++) {
   
                const star = document.createElement('div');
                star.className = 'star';
                const size = Math.random() * 3 + 1; // 随机大小(1-4px)
                star.style.width = `${
     size}px`;
                star.style.height = `${
     size}px`;
                star.style.left = `${
     Math.random() * 100}%`; // 随机水平位置
                star.style.top = `${
     Math.random() * 100}%`; // 随机垂直位置
                star.style.animationDuration = `${
     Math.random() * 3 + 2}s`; // 随机动画持续时间
                star.style.animationDelay = `${
     Math.random() * 5}s`; // 随机延迟
                star.style.backgroundColor = `hsl(${
     Math.random() * 360}, 80%, 80%)`; // 随机颜色
                bgAnimation.appendChild(star);
            }
        }

(4)爱心生成模块

        function createHeart() {
   
            if (activeHearts >= config.maxHeartsOnScreen) return; // 达到上限则不创建

            activeHearts++;
            const heart = document.createElement('div');
            heart.className = 'floating-heart';

            // 随机选择爱心符号和颜色
            const randomSymbol = config.heartSymbols[Math.floor(Math.random() * config.heartSymbols.length)];
            heart.innerHTML = randomSymbol;
            const randomColor = config.heartColors[Math.floor(Math.random() * config.heartColors.length)];
            heart.style.color = randomColor;

            // 随机位置和大小
            const leftPos = Math.random() * (window.innerWidth - 60) + 30;
            heart.style.left = `${
     leftPos}px`;
            const size = Math.random() * (config.heartSizeRange[1] - config.heartSizeRange[0]) + config.heartSizeRange[0];
            heart.style.fontSize = `${
     size}px`;

            // 随机动画持续时间
            const duration = Math.random() * (config.animationDurationRange[1] - config.animationDurationRange[0]) + config.animationDurationRange[0];
            heart.style.animationDuration = `${
     duration}s`;

            // 随机旋转方向
            const rotationDirection = Math.random() > 0.5 ? 1 : -1;
            heart.style.setProperty('--rotation', `${
     360 * rotationDirection}deg`);

            // 添加点击事件
            heart.addEventListener('click', handleHeartClick);
            document.body.appendChild(heart);
            allHearts.push(heart);

            // 动画结束后的处理
            heart.addEventListener('animationend', function(e) {
   
                if (e.animationName === 'floatHeart') {
   
                    if (heart.parentNode) {
   
                        heart.parentNode.removeChild(heart);
                    }
                    activeHearts = Math.max(0, activeHearts - 1);
                    allHearts = allHearts.filter(h => h !== heart);
                }
            });
        }

(5)文字显示模块

        function createLoveText(x, y) {
   
            const text = document.createElement('div');
            text.className = 'love-text';
            const randomText = config.loveTexts[Math.floor(Math.random() * config.loveTexts.length)];
            text.innerText = randomText;
            text.style.left = `${
     x}px`;
            text.style.top = `${
     y}px`;
            const randomColor = config.heartColors[Math.floor(Math.random() * config.heartColors.length)];
            text.style.color = randomColor;
            const fontSize = Math.random() * 6 + 16; // 随机字体大小(16-22px)
            text.style.fontSize = `${
     fontSize}px`;
            document.body.appendChild(text);

            // 1秒后自动移除文字元素
            setTimeout(() => {
   
                if (text.parentNode) {
   
                    text.parentNode.removeChild(text);
                }
            }, 1000);
        }

(6)点击交互模块

        function handleHeartClick(e) {
   
            const heart = e.target;
            const rect = heart.getBoundingClientRect();
            const centerX = rect.left + rect.width / 2;
            const centerY = rect.top + rect.height / 2;

            // 重置样式为爆炸动画做准备
            heart.style.animation = 'none';
            heart.style.transition = 'none';
            heart.style.left = `${
     centerX}px`;
            heart.style.top = `${
     centerY}px`;
            heart.style.transform = 'translate(-50%, -50%)';
            heart.style.animation = 'burstHeart 0.5s ease forwards'; // 应用爆炸动画

            // 在爱心位置创建文字
            createLoveText(centerX, centerY);

            // 动画结束后移除爱心元素
            setTimeout(() => {
   
                if (heart.parentNode) {
   
                    heart.parentNode.removeChild(heart);
                }
                activeHearts = Math.max(0, activeHearts - 1);
                allHearts = allHearts.filter(h => h !== heart);
            }, 500);
        }
目录
相关文章
|
1天前
|
人工智能 JSON 机器人
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
本文带你零成本玩转OpenClaw:学生认证白嫖6个月阿里云服务器,手把手配置飞书机器人、接入免费/高性价比AI模型(NVIDIA/通义),并打造微信公众号“全自动分身”——实时抓热榜、AI选题拆解、一键发布草稿,5分钟完成热点→文章全流程!
10149 30
让龙虾成为你的“公众号分身” | 阿里云服务器玩Openclaw
|
13天前
|
人工智能 安全 Linux
【OpenClaw保姆级图文教程】阿里云/本地部署集成模型Ollama/Qwen3.5/百炼 API 步骤流程及避坑指南
2026年,AI代理工具的部署逻辑已从“单一云端依赖”转向“云端+本地双轨模式”。OpenClaw(曾用名Clawdbot)作为开源AI代理框架,既支持对接阿里云百炼等云端免费API,也能通过Ollama部署本地大模型,完美解决两类核心需求:一是担心云端API泄露核心数据的隐私安全诉求;二是频繁调用导致token消耗过高的成本控制需求。
5861 14
|
21天前
|
人工智能 JavaScript Ubuntu
5分钟上手龙虾AI!OpenClaw部署(阿里云+本地)+ 免费多模型配置保姆级教程(MiniMax、Claude、阿里云百炼)
OpenClaw(昵称“龙虾AI”)作为2026年热门的开源个人AI助手,由PSPDFKit创始人Peter Steinberger开发,核心优势在于“真正执行任务”——不仅能聊天互动,还能自动处理邮件、管理日程、订机票、写代码等,且所有数据本地处理,隐私完全可控。它支持接入MiniMax、Claude、GPT等多类大模型,兼容微信、Telegram、飞书等主流聊天工具,搭配100+可扩展技能,成为兼顾实用性与隐私性的AI工具首选。
22951 119
|
7天前
|
人工智能 JavaScript API
解放双手!OpenClaw Agent Browser全攻略(阿里云+本地部署+免费API+网页自动化场景落地)
“让AI聊聊天、写代码不难,难的是让它自己打开网页、填表单、查数据”——2026年,无数OpenClaw用户被这个痛点困扰。参考文章直击核心:当AI只能“纸上谈兵”,无法实际操控浏览器,就永远成不了真正的“数字员工”。而Agent Browser技能的出现,彻底打破了这一壁垒——它给OpenClaw装上“上网的手和眼睛”,让AI能像真人一样打开网页、点击按钮、填写表单、提取数据,24小时不间断完成网页自动化任务。
1760 4

热门文章

最新文章