HTML实战:爱心图的实现
设计思路
-
使用纯CSS创建多种风格的爱心
-
添加平滑的动画效果
-
实现交互式爱心生成器
-
响应式设计适应不同设备
-
优雅的UI布局和色彩方案
-
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML爱心图实战</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #ffafbd, #ffc3a0);
color: #5a2a2a;
min-height: 100vh;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
header {
text-align: center;
padding: 30px 0;
width: 100%;
max-width: 1200px;
}
h1 {
font-size: 2.8rem;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
color: #7a1f1f;
position: relative;
display: inline-block;
}
h1::after {
content: "";
position: absolute;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
width: 120px;
height: 4px;
background: linear-gradient(90deg, transparent, #ff5e7d, transparent);
border-radius: 2px;
}
.subtitle {
font-size: 1.2rem;
max-width: 700px;
margin: 20px auto;
line-height: 1.6;
color: #5a2a2a;
}
.container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 40px;
max-width: 1200px;
margin: 20px auto;
}
.card {
background: rgba(255, 255, 255, 0.85);
border-radius: 20px;
box-shadow: 0 10px 30px rgba(150, 50, 50, 0.2);
padding: 25px;
width: 100%;
max-width: 500px;
transition: transform 0.3s ease;
}
.card:hover {
transform: translateY(-10px);
}
.card h2 {
text-align: center;
margin-bottom: 20px;
color: #d83f5d;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.heart-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 300px;
margin: 20px 0;
}
/* 方法1:使用伪元素创建爱心 */
.heart-1 {
width: 100px;
height: 100px;
background-color: #ff5e7d;
position: relative;
transform: rotate(-45deg);
animation: beat-1 1.2s infinite;
}
.heart-1::before,
.heart-1::after {
content: "";
width: 100px;
height: 100px;
background-color: #ff5e7d;
border-radius: 50%;
position: absolute;
}
.heart-1::before {
top: -50px;
left: 0;
}
.heart-1::after {
top: 0;
left: 50px;
}
/* 方法2:使用border-radius创建爱心 */
.heart-2 {
width: 100px;
height: 100px;
background-color: #ff3366;
position: relative;
animation: beat-2 1.4s infinite;
}
.heart-2::before,
.heart-2::after {
content: "";
position: absolute;
width: 100px;
height: 100px;
background-color: #ff3366;
border-radius: 50%;
}
.heart-2::before {
top: 0;
left: -50px;
}
.heart-2::after {
top: -50px;
left: 0;
}
/* 方法3:使用CSS clip-path创建爱心 */
.heart-3 {
width: 100px;
height: 90px;
background-color: #ff1493;
clip-path: path("M10,30 A20,20,0,0,1,50,30 A20,20,0,0,1,90,30 Q90,60,50,90 Q10,60,10,30 Z");
animation: beat-3 1.6s infinite;
}
/* 方法4:使用SVG创建爱心 */
.heart-4 {
width: 100px;
height: 100px;
animation: beat-4 1.8s infinite;
}
.heart-4 svg {
width: 100%;
height: 100%;
}
/* 方法5:文字爱心 */
.heart-5 {
font-size: 100px;
color: #ff5e7d;
text-shadow: 0 0 20px rgba(255, 0, 85, 0.4);
animation: beat-5 2s infinite;
}
/* 动画效果 */
@keyframes beat-1 {
0%, 100% { transform: rotate(-45deg) scale(1); }
50% { transform: rotate(-45deg) scale(1.1); }
}
@keyframes beat-2 {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
@keyframes beat-3 {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.15); }
}
@keyframes beat-4 {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.12); }
}
@keyframes beat-5 {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.2); }
}
.code-block {
background: #2d2d2d;
color: #f8f8f2;
border-radius: 10px;
padding: 15px;
margin-top: 20px;
font-family: 'Courier New', monospace;
font-size: 0.9rem;
line-height: 1.5;
overflow-x: auto;
max-height: 200px;
overflow-y: auto;
}
.generator {
background: rgba(255, 255, 255, 0.85);
border-radius: 20px;
box-shadow: 0 10px 30px rgba(150, 50, 50, 0.2);
padding: 30px;
width: 100%;
max-width: 800px;
margin: 40px auto;
text-align: center;
}
.controls {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
margin: 30px 0;
}
.control-group {
display: flex;
flex-direction: column;
align-items: center;
}
label {
margin-bottom: 8px;
font-weight: 500;
color: #7a1f1f;
}
input[type="range"] {
width: 200px;
accent-color: #ff5e7d;
}
input[type="color"] {
width: 60px;
height: 40px;
border: none;
border-radius: 8px;
cursor: pointer;
}
.generated-heart {
margin: 30px auto;
width: 150px;
height: 150px;
background-color: #ff5e7d;
position: relative;
transform: rotate(-45deg);
}
.generated-heart::before,
.generated-heart::after {
content: "";
position: absolute;
width: 150px;
height: 150px;
background-color: inherit;
border-radius: 50%;
}
.generated-heart::before {
top: -75px;
left: 0;
}
.generated-heart::after {
top: 0;
left: 75px;
}
button {
background: #ff5e7d;
color: white;
border: none;
padding: 12px 25px;
border-radius: 50px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
margin: 10px;
box-shadow: 0 4px 15px rgba(255, 94, 125, 0.4);
}
button:hover {
background: #ff3366;
transform: translateY(-3px);
box-shadow: 0 7px 20px rgba(255, 94, 125, 0.6);
}
footer {
text-align: center;
padding: 30px 0;
width: 100%;
max-width: 1200px;
color: #5a2a2a;
font-size: 1rem;
margin-top: auto;
}
@media (max-width: 768px) {
.container {
flex-direction: column;
align-items: center;
}
.card {
max-width: 90%;
}
h1 {
font-size: 2.2rem;
}
.controls {
flex-direction: column;
align-items: center;
}
}
</style>
</head>
<body>
<header>
<h1><i class="fas fa-heart"></i> HTML爱心图实战</h1>
<p class="subtitle">探索使用纯CSS和HTML创建爱心的多种方法。从基础形状到高级技巧,学习如何实现各种风格的爱心及其动画效果。</p>
</header>
<div class="container">
<div class="card">
<h2><i class="fas fa-shapes"></i> 伪元素方法</h2>
<div class="heart-container">
<div class="heart-1"></div>
</div>
<div class="code-block">
/* 使用两个伪元素创建爱心 */
.heart {
width: 100px;
height: 100px;
background-color: #ff5e7d;
position: relative;
transform: rotate(-45deg);
}.heart::before,
.heart::after {
content: "";
width: 100px;
height: 100px;
background-color: #ff5e7d;
border-radius: 50%;
position: absolute;
}.heart::before {
top: -50px;
left: 0;
}.heart::after {
top: 0;
left: 50px;
}</div>
</div>
<div class="card">
<h2><i class="fas fa-border-style"></i> Border-radius方法</h2>
<div class="heart-container">
<div class="heart-2"></div>
</div>
<div class="code-block">
/* 使用border-radius创建爱心 */
.heart {
width: 100px;
height: 100px;
background-color: #ff3366;
position: relative;
}.heart::before,
.heart::after {
content: "";
position: absolute;
width: 100px;
height: 100px;
background-color: #ff3366;
border-radius: 50%;
}.heart::before {
top: 0;
left: -50px;
}.heart::after {
top: -50px;
left: 0;
}</div>
</div>
<div class="card">
<h2><i class="fas fa-cut"></i> Clip-path方法</h2>
<div class="heart-container">
<div class="heart-3"></div>
</div>
<div class="code-block">
/* 使用CSS clip-path创建爱心 */
.heart {
width: 100px;
height: 90px;
background-color: #ff1493;
clip-path: path("M10,30 A20,20,0,0,1,50,30 A20,20,0,0,1,90,30 Q90,60,50,90 Q10,60,10,30 Z");
}</div>
</div>
<div class="card">
<h2><i class="fas fa-code"></i> SVG方法</h2>
<div class="heart-container">
<div class="heart-4">
<svg viewBox="0 0 32 29.6">
<path d="M23.6,0c-3.4,0-6.3,2.7-7.6,5.6C14.7,2.7,11.8,0,8.4,0C3.8,0,0,3.8,0,8.4c0,9.4,9.5,11.9,16,21.2
c6.1-9.3,16-12.1,16-21.2C32,3.8,28.2,0,23.6,0z" fill="#ff5e7d"/>
</svg>
</div>
</div>
<div class="code-block">
<!-- 使用内联SVG创建爱心 -->
<svg viewBox="0 0 32 29.6">
<path d="M23.6,0c-3.4,0-6.3,2.7-7.6,5.6C14.7,2.7,11.8,0,8.4,0C3.8,0,0,3.8,0,8.4c0,9.4,9.5,11.9,16,21.2
c6.1-9.3,16-12.1,16-21.2C32,3.8,28.2,0,23.6,0z" fill="#ff5e7d"/>
</svg></div>
</div>
</div>
<div class="generator">
<h2><i class="fas fa-magic"></i> 爱心生成器</h2>
<p>自定义您的爱心:调整大小、颜色和动画速度</p>
<div class="controls">
<div class="control-group">
<label for="size">尺寸: <span id="size-value">150px</span></label>
<input type="range" id="size" min="50" max="300" value="150">
</div>
<div class="control-group">
<label for="color">颜色</label>
<input type="color" id="color" value="#ff5e7d">
</div>
<div class="control-group">
<label for="speed">动画速度: <span id="speed-value">正常</span></label>
<input type="range" id="speed" min="0" max="10" value="5">
</div>
</div>
<div class="heart-container">
<div class="generated-heart" id="custom-heart"></div>
</div>
<button id="animate-btn"><i class="fas fa-play"></i> 播放动画</button>
<button id="reset-btn"><i class="fas fa-redo"></i> 重置</button>
</div>
<footer>
<p>© 2023 HTML爱心图实战 | 使用纯CSS和HTML创建 | 探索前端设计的艺术</p>
<p>❤️ 让爱在代码中传递 ❤️</p>
</footer><script>
// 获取DOM元素
const sizeSlider = document.getElementById('size');
const colorPicker = document.getElementById('color');
const speedSlider = document.getElementById('speed');
const customHeart = document.getElementById('custom-heart');
const animateBtn = document.getElementById('animate-btn');
const resetBtn = document.getElementById('reset-btn');
const sizeValue = document.getElementById('size-value');
const speedValue = document.getElementById('speed-value');
// 更新尺寸显示
sizeSlider.addEventListener('input', function() {
const size = this.value;
sizeValue.textContent = `${size}px`;
// 更新爱心尺寸
customHeart.style.width = `${size}px`;
customHeart.style.height = `${size}px`;
// 更新伪元素尺寸
const pseudoSize = `${size}px`;
customHeart.style.setProperty('--pseudo-size', pseudoSize);
// 更新伪元素位置
const pseudoOffset = `${size / 2}px`;
customHeart.style.setProperty('--pseudo-offset', pseudoOffset);
});
// 更新颜色
colorPicker.addEventListener('input', function() {
customHeart.style.backgroundColor = this.value;
});
// 更新速度显示
speedSlider.addEventListener('input', function() {
const speed = this.value;
let speedText;
if (speed < 3) speedText = '慢速';
else if (speed < 7) speedText = '正常';
else speedText = '快速';
speedValue.textContent = speedText;
});
// 动画按钮事件
animateBtn.addEventListener('click', function() {
const speed = speedSlider.value;
const duration = 2 - (speed * 0.15); // 根据速度计算动画时长
customHeart.style.animation = `none`;
setTimeout(() => {
customHeart.style.animation = `beat ${duration}s infinite`;
}, 10);
});
// 重置按钮事件
resetBtn.addEventListener('click', function() {
// 重置滑块和值
sizeSlider.value = 150;
colorPicker.value = '#ff5e7d';
speedSlider.value = 5;
// 更新显示
sizeValue.textContent = '150px';
speedValue.textContent = '正常';
// 重置爱心样式
customHeart.style.width = '150px';
customHeart.style.height = '150px';
customHeart.style.backgroundColor = '#ff5e7d';
customHeart.style.animation = 'none';
// 重置伪元素尺寸
customHeart.style.setProperty('--pseudo-size', '150px');
customHeart.style.setProperty('--pseudo-offset', '75px');
});
// 添加CSS动画关键帧
const style = document.createElement('style');
style.textContent = `
@keyframes beat {
0%, 100% { transform: rotate(-45deg) scale(1); }
50% { transform: rotate(-45deg) scale(1.15); }
}
`;
document.head.appendChild(style);
</script>
</body>
</html> -
功能亮点
-
五种爱心实现方法:
-
伪元素方法(最常用)
-
Border-radius方法
-
CSS clip-path方法
-
SVG方法
-
文字方法(使用❤️字符)
-
-
动画效果:
-
每个爱心都有独特的脉动动画
-
平滑的缩放效果模拟心跳
-
不同的动画速度创造多样化效果
-
-
爱心生成器:
-
实时调整爱心尺寸(50px-300px)
-
自定义爱心颜色
-
控制动画速度(慢速/正常/快速)
-
播放/重置功能
-
-
响应式设计:
-
在手机、平板和桌面设备上均完美显示
-
在小屏幕设备上自动调整布局
-
-
代码展示:
-
每个方法都附带源代码展示
-
语法高亮提高可读性
-
代码块可滚动查看
-
相关文章:
HTML实战:爱心图的实现
设计思路 使用纯CSS创建多种风格的爱心 添加平滑的动画效果 实现交互式爱心生成器 响应式设计适应不同设备 优雅的UI布局和色彩方案 <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8"> <meta nam…...

定时任务:springboot集成xxl-job-core(二)
定时任务实现方式: 存在的问题: xxl-job的原理: 可以根据服务器的个数进行动态分片,每台服务器分到的处理数据是不一样的。 1. 多台机器动态注册 多台机器同时配置了调度器xxl-job-admin之后,执行器那里会有多个注…...

DeviceNET转EtherCAT网关:医院药房自动化的智能升级神经中枢
在现代医院药房自动化系统中,高效、精准、可靠的设备通信是保障患者用药安全与效率的核心。当面临既有支持DeviceNET协议的传感器、执行器(如药盒状态传感器、机械臂限位开关)需接入先进EtherCAT高速实时网络时,JH-DVN-ECT疆鸿智能…...

一:UML类图
一、类的设计 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 学习设计模式的第一步是看懂UML类图,类图能直观的表达类、对象之间的关系,这将有助于后续对代码的编写。 类图在软件设计及应用框架前期设计中是不可缺少的一部分,它的主要成分包括:类名、…...
数据库三范式的理解
最近在学习数据库知识,发现 “数据库三范式” 这个概念特别重要,今天就来和大家分享一下我的理解,欢迎各位指正 一、数据库三范式是什么? 数据库三范式是为了让数据库结构更合理、减少数据冗余、提高数据完整性的设计规则。 第一范式&…...

Java 中 MySQL 索引深度解析:面试核心知识点与实战
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Java 中 MySQL 索引深度解析:面试…...
DeepSeek 部署中的常见问题及解决方案
技术文章大纲:DeepSeek 部署中的常见问题及解决方案 部署环境配置问题 硬件兼容性问题(如GPU驱动版本不匹配) 操作系统及依赖库版本冲突(CUDA/cuDNN版本) Python虚拟环境配置错误 模型加载与初始化失败 预训练模型…...
Nvidia Intern 笔试回忆
Nvidia intern compute arch 的笔试回忆,感觉强度拉满,两个半小时6道编程题,难度堪比ACM,需要自己写好输入输出(ACM好歹有个签到题 ),图论的题比较多,跟大厂面试题不是同一level...…...
鸿蒙OS基于UniApp的WebRTC视频会议系统实践:从0到1的HarmonyOS适配之路#三方框架 #Uniapp
基于UniApp的WebRTC视频会议系统实践:从0到1的HarmonyOS适配之路 引言 在移动互联网时代,实时音视频通讯已成为各类应用的标配功能。本文将结合我在某大型企业协同办公项目中的实战经验,详细讲解如何使用UniApp框架开发一个支持鸿蒙系统的W…...

设计模式之结构型:装饰器模式
装饰器模式(Decorator Pattern) 定义 装饰器模式是一种结构型设计模式,允许动态地为对象添加新功能,而无需修改其原始类。它通过将对象包装在装饰器类中,以组合代替继承,实现功能的灵活扩展(如 Java I/O …...
mysql分布式教程
MySQL 主从复制 主从复制原理:MySQL 主从复制是指数据可以从一个 MySQL 数据库服务器主节点复制到一个或多个从节点。主库将写操作记录在二进制日志文件中,从库的 IO 线程请求读取主库的二进制日志并写入中继日志,然后 SQL 线程执行中继日志中…...

MySQL安装及启用详细教程(Windows版)
MySQL安装及启用详细教程(Windows版) 📋 概述 本文档将详细介绍MySQL数据库在Windows系统下的下载、安装、配置和启用过程。 📥 MySQL下载 官方下载地址 官方网站: https://dev.mysql.com/downloads/社区版本: https://dev.my…...
Vue3.5 企业级管理系统实战(二十一):菜单权限
有了菜单及角色管理后,我们还需要根据用户访问的token,去获取用户信息,根据用户的角色信息,拉取所有的菜单权限,进而生成左侧菜单树数据。 1 增加获取用户信息 api 在 src/api/user.ts 中,添加获取用户信…...
kafka幂等生产者和事务生产者区别
#作者:张桐瑞 文章目录 消息交付可靠性保障什么是幂等性(Idempotence)?幂等性Producer事务事务型Producer 消息交付可靠性保障 所谓的消息交付可靠性保障,是指Kafka对Producer和Consumer要处理的消息提供什么样的承诺…...

【HarmonyOS Next之旅】DevEco Studio使用指南(二十九) -> 开发云数据库
目录 1 -> 开发流程 2 -> 创建对象类型 3 -> 添加数据条目 3.1 -> 手动创建数据条目文件 3.2 -> 自动生成数据条目文件 4 -> 部署云数据库 1 -> 开发流程 云数据库是一款端云协同的数据库产品,提供端云数据的协同管理、统一的数据模型和…...

批量导出CAD属性块信息生成到excel——CAD C#二次开发(插件实现)
本插件可实现批量导出文件夹内大量dwg文件的指定块名的属性信息到excel,效果如下: 插件界面: dll插件如下: 使用方法: 1、获取此dll插件。 2、cad命令行输入netload ,加载此dll(要求AutoCAD&…...
可视化大屏如何制作
超详细!手把手教你制作可视化大屏 在当今数字化时代,数据犹如一座蕴藏无尽价值的宝藏,而可视化大屏则是开启这座宝藏大门、让数据价值得以充分展现的关键钥匙。无论是企业运营监控、数据分析展示,还是项目成果汇报,可视…...

Goreplay最新版本的安装和简单使用
一:概述 Gor 是一个开源工具,用于捕获实时 HTTP 流量并将其重放到测试环境中,以便使用真实数据持续测试您的系统。它可用于提高对代码部署、配置更改和基础设施更改的信心。简单易用。 项目地址:buger/goreplay: GoReplay is an …...

Android Studio 解决报错 not support JCEF 记录
问题:Android Studio 安装Markdown插件后,报错not support JCEF不能预览markdown文件。 原因:Android Studio不是新装,之前没留意IDE自带的版本是不支持JCEF的。 解决办法: 在菜单栏选中Help→Find Actionÿ…...
SMT高速贴片机核心技术深度剖析
内容概要 在智能制造升级背景下,SMT高速贴片机的性能直接影响电子产品的生产效率和可靠性。本文将从微米级贴装精度的实现机制出发,探讨高速运动控制与精准定位的协同优化方案,同时分析视觉系统在多类型元件识别中的动态补偿策略。针对消费电…...

sigmastar实现SD卡升级
参考文章:http://wx.comake.online/doc/DD22dk2f3zx-SSD21X-SSD22X/customer/development/software/Px/zh/sys/P3/usb%20&%20sd%20update.html#21-sd 1、构建SD卡升级包 在project下make image完成后使用make_sd_upgrade_sigmastar.sh脚本打包SD卡升级包。 ./make_sd_up…...

kafka学习笔记(三、消费者Consumer使用教程——配置参数大全及性能调优)
本章主要介绍kafka consumer的配置参数及性能调优的点,其kafka的从零开始的安装到生产者,消费者的详解介绍、源码及分析及原理解析请到博主kafka专栏 。 1.消费者Consumer配置参数 配置参数默认值含义bootstrap.servers无(必填)…...
yarn、pnpm、npm
非常好,这样从“问题驱动 → 工具诞生 → 优化演进”的角度来讲,更清晰易懂。下面我按时间线和动机,把 npm → yarn → pnpm 的演变脉络讲清楚。 🧩 一、npm 为什么一开始不够好? 早期(npm v4 及之前&…...
JVM——Truffle:语言实现框架
引入 在编程语言的实现领域,传统的编译器和解释器设计往往面临着复杂性和性能优化的双重挑战。尤其是对于动态语言,解释器的效率问题一直是一个难以突破的瓶颈。而 Truffle 框架的出现,为这一难题提供了全新的解决方案。Truffle 是一个高性能…...
C++ STL vector容器详解:从原理到实践
引言 亲爱的小伙伴们,今天我要和大家分享一个C编程中的"神器"——vector容器!作为STL(标准模板库)中最常用的容器之一,vector就像是一个"超级数组",既有数组的高效随机访问特性&#…...
视频压制(Video Encoding/Compression)
视频压制(Video Encoding/Compression) 视频压制是指通过特定的算法和技术,将原始视频文件转换为更小体积或更适合传播的格式的过程。其核心目的是在尽量保持画质的前提下,减少视频的文件大小,或适配不同播放设备、网络环境的需求…...

【论文笔记】Transcoders Find Interpretable LLM Feature Circuits
Abstract 机制可解释性(mechanistic interpretability)的核心目标是路径分析(circuit analysis):在模型中找出与特定行为或能力对应的稀疏子图。 然而,MLP 子层使得在基于 Transformer 的语言模型中进行细粒度的路径分析变得困难。具体而言,…...
音视频融合中的语音分离技术实现
音视频融合中的语音分离技术实现 一、任务概述 语音分离是音频信号处理的核心任务,旨在从混合音频中分离出目标语音。音视频融合技术通过结合视觉信息(如嘴唇运动)显著提升分离效果。本方案将实现一个基于深度学习的音视频融合语音分离系统。 二、系统架构 #mermaid-svg-3…...

每天总结一个html标签——a标签
文章目录 一、定义与使用说明二、支持的属性三、支持的事件四、默认样式五、常见用法1. 文本链接2. 图片链接3. 导航栏 在前端开发中,a标签(锚点标签)是最常用的HTML标签之一,主要用于创建超链接,实现页面间的跳转或下…...
在Babylon.js中创建3D文字:简单而强大的方法
引言 在3D场景中添加文字是许多WebGL项目的常见需求。Babylon.js提供了多种创建3D文字的方法,其中使用TextBlock结合平面网格是一种简单而高效的方式。本文将介绍如何使用Babylon.js的GUI系统在3D空间中创建美观的文字效果。 方法概述 Babylon.js的GUI系统允许我…...