情人节特别定制:多种语言编写动态爱心网页(附完整代码)
- 写在前面
- 案例1:HTML + Three.js库
- 案例2:HTML + CSS + JavaScript
- 案例3:Python环境 + Flask框架
- 结语
写在前面
随着七夕节的临近,许多人都在寻找独特而令人难忘的方式来表达爱意。在这个数字时代,结合创意和技术,我们可以使用多种开发语言来编写一个动态的新型网页,为这个浪漫的节日增添一份特别的礼物。在本文中,我们将带你探索如何使用不同的开发语言来打造一个充满心意的七夕表白网页。
案例1:HTML + Three.js库
网页效果

当使用 Three.js 库来创建一个动态的心形网页时,需要在 HTML 中引入 Three.js 库,然后创建一个用于渲染的画布,并编写 JavaScript 代码来生成动画效果。完整代码如下(可直接复制粘贴到文本文档或者开发软件中运行):
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Dynamic Heart Shape</title>
</head><body><script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script><canvas id="canvas"></canvas><script src="your-script.js"></script>
</body><script>// 获取画布元素const canvas = document.getElementById("canvas");// 创建场景const scene = new THREE.Scene();// 创建摄像机const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);camera.position.z = 5;// 创建渲染器const renderer = new THREE.WebGLRenderer({canvas});renderer.setSize(window.innerWidth, window.innerHeight);// 创建心形几何体const heartShape = new THREE.Shape();heartShape.moveTo(0, -1);heartShape.bezierCurveTo(0, -1.8, -1.5, -1.8, -1.5, -1);heartShape.bezierCurveTo(-1.5, -0.2, -0.6, 0.6, 0, 1.4);heartShape.bezierCurveTo(0.6, 0.6, 1.5, -0.2, 1.5, -1);heartShape.bezierCurveTo(1.5, -1.8, 0, -1.8, 0, -1);const heartGeometry = new THREE.ShapeGeometry(heartShape);const heartMaterial = new THREE.MeshBasicMaterial({color: 0xff4d6a});const heartMesh = new THREE.Mesh(heartGeometry, heartMaterial);scene.add(heartMesh);// 创建动画循环const animate = () => {requestAnimationFrame(animate);// 使心形旋转heartMesh.rotation.x += 0.005;heartMesh.rotation.y += 0.005;renderer.render(scene, camera);};animate();
</script></html>
上述代码使用到了 Three.js 库来创建一个动态的心形网页。它创建了一个场景、摄像机、渲染器以及一个心形几何体,然后通过动画循环让心形几何体旋转起来。大家可以根据需要进行调整和扩展,例如添加光源、调整心形的大小和颜色等等。
案例2:HTML + CSS + JavaScript
网页效果

完整代码如下(可直接复制粘贴到文本文档或者开发软件中运行):
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>love++</title><style>/* 设置全屏显示 */body {margin: 0;overflow: hidden;background: #f6d8e2;display: flex;align-items: center;justify-content: center;}/* 画布样式 */canvas {position: absolute;width: 100%;height: 100%;left: 0;top: 0;pointer-events: none;}</style>
</head><body><!-- 画布元素 --><canvas id="pinkboard"></canvas><script>var settings = {particles: {length: 1000,duration: 2,velocity: 150,effect: -0.5,size: 30,},};(function () {var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;window.requestAnimationFrame = requestAnimationFrame;var cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;window.cancelAnimationFrame = cancelAnimationFrame;if (!requestAnimationFrame || !cancelAnimationFrame) {var lastTime = 0;window.requestAnimationFrame = function (callback) {var currentTime = new Date().getTime();var timeToCall = Math.max(0, 16 - (currentTime - lastTime));var id = setTimeout(function () {callback(currentTime + timeToCall);}, timeToCall);lastTime = currentTime + timeToCall;return id;};window.cancelAnimationFrame = function (id) {clearTimeout(id);};}})();// 2D 坐标点类var Point = (function () {function Point(x, y) {this.x = x || 0;this.y = y || 0;}Point.prototype.clone = function () {return new Point(this.x, this.y);};Point.prototype.length = function (length) {if (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) {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);firstFree++;if (firstFree == particles.length) firstFree = 0;if (firstActive == firstFree) firstActive++;if (firstActive == particles.length) firstActive = 0;};ParticlePool.prototype.update = function (deltaTime) {var i;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);}while (particles[firstActive].age >= duration && firstActive != firstFree) {firstActive++;if (firstActive == particles.length) firstActive = 0;}};ParticlePool.prototype.draw = function (context, image) {// 绘制活跃的粒子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,time;function pointOnHeart(t) {return new Point(180 * Math.pow(Math.sin(t), 3),160 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25);}var image = (function () {var canvas = document.createElement('canvas'),context = canvas.getContext('2d');canvas.width = settings.particles.size;canvas.height = settings.particles.size;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;}context.beginPath();var t = -Math.PI;var point = to(t);context.moveTo(point.x, point.y);while (t < Math.PI) {t += 0.01;point = to(t);context.lineTo(point.x, point.y);}context.closePath();context.fillStyle = '#fa759f';context.fill();var image = new Image();image.src = canvas.toDataURL();return image;})();function render() {requestAnimationFrame(render);var newTime = new Date().getTime() / 1000,deltaTime = newTime - (time || newTime);time = newTime;context.clearRect(0, 0, canvas.width, canvas.height);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);}particles.update(deltaTime);particles.draw(context, image);}function onResize() {canvas.width = window.innerWidth;canvas.height = window.innerHeight;}window.onresize = onResize;setTimeout(function () {onResize();render();}, 50);})(document.getElementById('pinkboard'));</script>
</body></html>
这段代码实现了一个动态的桃心效果,包含文字、动画和特效。在 HTML 部分,你可以看到一个 canvas 元素,主要用于绘制动态的桃心效果。然后使用 CSS 内联样式来设置页面的宽度、高度和背景颜色,以及对 canvas 元素进行定位和设置宽高。最后 JavaScript 实现动态的桃心效果。
代码中的 Particle 和 ParticlePool 类定义了粒子和粒子池,用于绘制和管理粒子。pointOnHeart 函数返回一个位于桃心曲线上的点,用来初始化粒子的位置。然后使用 canvas 绘制小粒子创造一个形状为桃心的动态效果。代码中 render 函数是主要的渲染函数,用于更新粒子状态、绘制粒子以及创建新的粒子。最后通过延迟一段时间调用 onResize 函数,设置画布大小并开始渲染。
案例3:Python环境 + Flask框架
网页效果

我们也可以使用 Python 的 Web 框架(比如 Flask 或 Django)来搭建一个简单的服务器,将动态心形网页通过服务器动态地呈现给访问者。这里使用的是 flask 框架。
首先,打开开发工具(我用的是 PyCharm)并创建项目。安装 Flask 库(如果尚未安装):
pip install Flask
创建一个名为 app.py 的 Python 文件,将以下代码粘贴到文件中:
from flask import Flask, render_template
app = Flask(__name__)@app.route('/')
def index():return render_template('index.html')if __name__ == '__main__':app.run(debug=True)
在同一目录下创建一个名为 templates 的文件夹,然后在该文件夹内创建一个名为 index.html 的 HTML 文件,并将以下代码粘贴到文件中:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}"><title>动态爱心</title>
</head>
<body><canvas id="heartCanvas"></canvas><script src="{{ url_for('static', filename='script.js') }}"></script>
</body>
</html>
在同一目录下创建一个名为 static 的文件夹,然后在该文件夹内创建一个名为 styles.css 的 CSS 文件,并将以下代码粘贴到文件中:
body {display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;background-color: #f0f0f0;
}
在 static 文件夹内创建一个名为 script.js 的 JavaScript 文件,并将以下代码粘贴到文件中:
const canvas = document.getElementById("heartCanvas");
const ctx = canvas.getContext("2d");canvas.width = window.innerWidth;
canvas.height = window.innerHeight;function drawHeart(x, y, size) {ctx.beginPath();ctx.moveTo(x, y);ctx.bezierCurveTo(x, y - size / 3,x - size / 2, y,x, y + size / 3);ctx.bezierCurveTo(x + size / 2, y,x, y - size / 3,x, y);ctx.fillStyle = "#ff4d6a";ctx.fill();ctx.closePath();
}function animate() {requestAnimationFrame(animate);ctx.clearRect(0, 0, canvas.width, canvas.height);const heartSize = 300;const heartX = canvas.width / 2;const heartY = canvas.height / 2 + Math.sin(Date.now() * 0.005) * 30;drawHeart(heartX, heartY, heartSize);
}animate();
打开命令行窗口,导航到包含这些文件的目录,并运行以下命令来启动 Flask 应用:
python app.py
最后在你的浏览器中访问 http://127.0.0.1:5000/ 查看生成的动态爱心网页。
整个项目目录是这样的;

案例使用函数简要介绍:
- ctx.beginPath():开始创建一个新的路径。
- ctx.moveTo(x, y):将绘图路径的起始点移动到给定的 (x, y) 坐标。
- ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y):绘制一个三次贝塞尔曲线,其中 cp1 和 cp2 是控制点的坐标,x 和 y 是结束点的坐标。这个方法用于绘制复杂的曲线。通过两次调用 bezierCurveTo 方法,分别绘制出心形的上半部分和下半部分。
- ctx.fillStyle = “#ff4d6a”:设置填充颜色为"#ff4d6a",这是一种深红色。
- ctx.fill():使用之前指定的颜色填充当前路径。
- ctx.closePath():关闭路径,将当前点连接到起始点,并填充颜色。
结语
在这个特别的七夕节,用自己的方式编写一个动态的表白网页,将你的真挚情感展现给爱人。无论你选择哪种开发语言,都可以运用创意和技术来制作一个让人难以忘怀的表白礼物。不仅仅是代码,更是一份对爱人的真挚表达,希望这个七夕会成为你们美好回忆的一部分。
相关文章:
情人节特别定制:多种语言编写动态爱心网页(附完整代码)
写在前面案例1:HTML Three.js库案例2:HTML CSS JavaScript案例3:Python环境 Flask框架结语 写在前面 随着七夕节的临近,许多人都在寻找独特而令人难忘的方式来表达爱意。在这个数字时代,结合创意和技术࿰…...
Docker mysql主从同步安装
1. 构建master实例 docker run -p 3307:3306 --name mysql-master \ -v /mydata/mysql-master/log:/var/log/mysql \ -v /mydata/mysql-master/data:/var/lib/mysql \ -v /mydata/mysql-master/conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORDroot \ -d mysql:5.7 2. 构建master配置…...
docker update 命令
docker update 更新一个或多个容器的配置。官方文档 用法 $ docker update [OPTIONS] CONTAINER [CONTAINER...]请参阅选项部分OPTIONS,了解此命令可用的概述。 描述 该docker update命令动态更新容器配置。您可以使用此命令来防止容器消耗 Docker 主机的过多资…...
阻塞和挂起的区别和联系
阻塞和挂起是进程两种不同的状态,其描述如下: 阻塞:正在执行的进程由于发生某时间(如I/O请求、申请缓冲区失败等)暂时无法继续执行。此时引起进程调度,OS把处理机分配给另一个就绪进程,而让受阻…...
水力发电厂测量装置配置选型及厂用电管理系统
《水力发电厂测量装置配置设计规范》对水电厂的测量装置配置做了详细要求和指导。测量装置是水力发电厂运行监测的重要环节,水电厂的测量主要分为电气量测量和非电量测量。电气测量指使用电的方式对电气实时参数进行测量,包括电流、电压、频率、功率因数…...
【RabbitMQ】RabbitMQ整合SpringBoot案例
文章目录 1、前情提要【RabbitMQ】2、RabbitMQ-SpringBoot案例 -fanout模式2.1 实现架构总览2.2 具体实现2.2.1生产者2.2.1消费者 1、前情提要【RabbitMQ】 【RabbitMQ】消息队列-RabbitMQ篇章 RabbitMQ实现流程 2、RabbitMQ-SpringBoot案例 -fanout模式 2.1 实现架构总览…...
如何在window下cmd窗口执行linux指令?
1.Git:https://git-scm.com/downloads(官网地址) 2.根据自己的实际路径,添加两个环境变量 3.重启电脑...
c++基础系列:字符串、向量和数组
字符串、向量和数组 命名空间的using声明 目前用到的库函数基本上都属于命名空间std;通过using声明(using declaration)实现更简单的途径使用到命名空间中的成员。 标准库类型string string表示可变长的字符序列,必须先包含st…...
docker 05(dockerfile)
一、docker镜像原理 镜像可以复用 二、容器转镜像 将容器保存为镜像[参考] docker commit -a -m 现有容器ID 保存后的名称:版本号 -a :提交的镜像作者; -c :使用Dockerfile指令来创建镜像; -m :提交时的说明文字; -p :…...
PostMan 测试项目是否支持跨域
使用PostMan可以方便快速的进行跨域测试。 只需要在请求头中手动添加一个Origin的标头,声明需要跨域跨到的域(IP:端口)就行,其余参数PostMan会自动生成。添加此标头后,请求会被做为一条跨域的请求来进行处…...
jsp 协同过滤 图书管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目
一、源码特点 JSP 协同过滤 图书管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境 为TOMCAT7.0,Myeclipse8.5开发,数据库为My…...
商城-学习整理-高级-商城业务-商品上架es(十)
目录 一、商品上架1、sku在ES中存储模型分析2、nested数据类型场景3、构造基本数据(商品上架) 二、首页1、项目介绍2、整合thymeleaf(spring-boot下模板引擎)渲染页面3、页面修改不重启服务器实时更新4、渲染二级三级数据 三、搭建…...
【水文学法总结】河道内生态流量计算方法(含MATLAB实现代码)
生态流量(Ecological Flow, EF) 是指维持河道内生态环境所需要的水流流量。生态流量计算方法众多,主要分为水文学方法、栖息地模拟法、水力学方法、整体法等,各方法多用于计算维持河道生态平衡的最小生态流量(Minimum …...
特斯拉Model 3的七年狂飙
作者 | 张祥威 编辑 | 德新 发布一周拿下32万张订单,之后用时五年,交付量突破100万辆。粗略计算,自2016年发布至今,特斯拉Model 3已交付超150万辆。 放眼新能源赛道,如此战绩 别无二家。 Model 3踩中纯电动车的…...
物流签收异常,财务对账复杂,怎么解决?
电子商务行业的蓬勃发展为人们的购物体验带来了巨大的便利,然而,随之而来的物流签收异常和财务对账复杂问题却给电商企业的财务部门带来了一系列困扰。 每天大量的订单和货物流转,不可避免地导致了物流签收数据与财务记录之间的不一致和差异…...
docker之镜像与数据卷
镜像 简介 1.镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于环境开发的软件,他包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量、配置文件 2.将所有的应用和环境11,直接打包成docker镜像&…...
服务器为什么会被攻击?43.248.186.x
进入信息时代,各种行业对数据的安全和技术要求也越来越高,同时也遇到了各种各样的服务器故障问题,但是网络攻击才是最大的伤害,在这上面造成了企业不必要的损失,那么服务器为什么会被攻击,这里给大家讲解一下服务器被攻击有哪几种情况 一、服…...
文心一言 VS 讯飞星火 VS chatgpt (79)-- 算法导论7.4 4题
四、请用go语言,证明:RANDOMIZED-QUICKSORT 期望运行时间是 Ω(nlgn)。 文心一言: 首先,为了证明RANDOMIZED-QUICKSORT的期望运行时间是Ω(nlg n),我们需要证明在最坏的情况下,该算法的运行时间是O(nlg n)。然后&…...
整理mongodb文档:索引
个人博客 整理mongodb文档:索引 个人博客,求关注,有问题的地方欢迎指出,觉得讲解的繁琐的也请指出 文章概叙 本文主要还是在shell下的操作。让大家了解下mongodb中index的用途,基本的索引的新增、查看、删除等,最后…...
EPICS libCom库(4) -- epicsTimer
epicsTimer.h描述了一个C和C timer功能。 1 C接口 1.1 epicsTimerNotify和epicsTimer /* 使用一个timer的代码必须实现epicsTimerNotify */ class LIBCOM_API epicsTimerNotify { public:enum restart_t { noRestart, restart };class expireStatus {public:LIBCOM_API expir…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...
goreplay
1.github地址 https://github.com/buger/goreplay 2.简单介绍 GoReplay 是一个开源的网络监控工具,可以记录用户的实时流量并将其用于镜像、负载测试、监控和详细分析。 3.出现背景 随着应用程序的增长,测试它所需的工作量也会呈指数级增长。GoRepl…...
