HTML沙漏爱心

2024-08-28 09:28
文章标签 html frontend 爱心 沙漏

本文主要是介绍HTML沙漏爱心,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

写在前面

完整代码

代码分析

系列文章

写在最后


写在前面

教你用HTML语言实现炫酷的沙漏爱心,该代码不仅可以用电脑运行,手机、平板也可以直接运行哦。

完整代码

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html; charset=GBK"><title>love</title><meta name="Generator" content="EditPlus"><meta name="Keywords" ,="" content="beating heart"><meta name="Description" content="canvas beating heart"><style>html,body {height: 100%;padding: 0;margin: 0;background: #000;}canvas {position: absolute;width: 100%;height: 100%;}
</style><style class="mpa-style-fix ImageGatherer">.FotorFrame {position: fixed !important}
</style><style class="mpa-style-fix SideFunctionPanel">.weui-desktop-online-faq__wrp {top: 304px !important;bottom: unset !important}.weui-desktop-online-faq__wrp .weui-desktop-online-faq__switch {width: 38px !important}
</style>
</head><body mpa-version="9.0.21" mpa-extension-id="ibefaeehajgcpooopoegkifhgecigeeg"><canvas id="pinkboard" width="1707" height="906"></canvas><script>/** settings*/var settings = {particles: {// maximum amount of particleslength: 8100,// particle duration in secduration: 4,// parrticle velicity in plxels/secvelocity: 50,// play with this for a nice effecteffect: -0.75,// particle size in pixelssize: 3,},};/** RequestAnimationFrame polyfill by Erik M枚ller*/(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) } } }());/** Point class*/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;})();/** Particle class*/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;})();/** ParticlePool class*/var ParticlePool = (function () {var particles,firstActive = 0,firstFree = 0,duration = settings.particles.duration;function ParticlePool(length) {// create and populate particle poolparticles = 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 queuefirstFree++;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 particlesif (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 iinactive particleswhile (particles[firstActive].age >= duration && firstActive != firstFree) {firstActive++;if (firstActive == particles.length) firstActive = 0;}};ParticlePool.prototype.draw = function (context, image) {// draw active particlesif (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;})();/** Putting it all together*/(function (canvas) {var context = canvas.getContext('2d'),particles = new ParticlePool(settings.particles.length),// particles/secparticleRate = settings.particles.length / settings.particles.duration,time;// get point on hert with -PI <= t <= PIfunction 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 thw particle image using a dummy canvasvar 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 pathfunction to(t) {var point = pointOnHeart(t);point.x = settings.particles.size / 2 + point.x * settings.particles.size / 100;point.y = settings.particles.size / 2 - point.y * settings.particles.size / 100;return point;}// create the pathcontext.beginPath();var t = -Math.PI;var point = to(t);context.moveTo(point.x, point.y);while (t < Math.PI) {// baby stepst += 0.03;point = to(t);context.lineTo(point.x, point.y);}context.closePath();// create the fillcontext.fillStyle = '#ea80b0';context.fill();// create th imagevar image = new Image();image.src = canvas.toDataURL();return image;})();// render that thingfunction render() {// next animation framerequestAnimationFrame(render);// update timevar newTime = new Date().getTime() / 1000,deltaTime = newTime - (time || newTime);time = newTime;// clear canvascontext.clearRect(0, 0, canvas.width, canvas.height);// create new particlesvar amount = particleRate * deltaTime;for (var i = 0; i < amount; i++) {var pos = pointOnHeart(Math.PI - 50 * 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 particlesparticles.update(deltaTime);particles.draw(context, image);}// handle (re-)sizing of the canvasfunction onResize() {canvas.width = canvas.clientWidth;canvas.height = canvas.clientHeight;}window.onresize = onResize;// delay rendering bootstrapsetTimeout(function () {onResize();render();}, 50);})(document.getElementById('pinkboard'));
</script><div class="pinkboard lef"></div><div class="pinkboard cen"></div><div class="pinkboard rig"></div></div></section></template></div><div id="__FEISHU_CLIPPER__"></div>
</body></html>

代码分析

这个HTML和JavaScript代码通过一个画布元素(canvas)来实现动态的心形粒子动画效果。该代码主要通过JavaScript控制画布上的粒子运动,使其呈现出不断跳动的心形图案,具有较强的视觉冲击力和艺术美感。

首先,这段代码在HTML部分设置了基本的页面结构和样式。通过设置 html 和 body 标签的 height 为 100% ,并将 padding 和 margin 设置为0,确保画布能够完全覆盖整个浏览器窗口。此外,画布元素 canvas 被设置为绝对定位,这意味着它会随着窗口的大小变化而自动调整,以适应不同设备的屏幕尺寸。

JavaScript部分是这段代码的核心,负责实现心形图案的粒子动画效果。该部分代码包含了多个模块,分别是设置模块、辅助函数模块、粒子类模块、粒子池模块以及动画渲染模块。

首先,代码定义了一个 settings 对象,其中包含了粒子的相关参数设置,如粒子的数量、持续时间、速度、效果和尺寸等。这些参数直接影响着粒子动画的表现效果。例如,length 决定了粒子的数量,velocity 控制了粒子的运动速度,而 effect 则决定了粒子运动的加速度和方向。

接下来,代码实现了 Point 类,这个类用于表示二维空间中的一个点,并提供了一些基本的数学运算方法,如向量的长度计算和归一化处理。在 Point 类的基础上,代码进一步定义了 Particle 类,每个粒子对象都包含了其位置、速度、加速度和生存时间等属性。粒子类中的 initialize 方法用于初始化粒子的初始状态,而 update 方法则用于更新粒子的位置和速度,从而使其在画布上运动。

为了管理大量的粒子对象,代码实现了一个 ParticlePool 类,这个类采用了一个循环队列来管理粒子对象的分配和回收。通过 add 方法,可以将新的粒子添加到队列中,而 update 方法则负责更新所有活跃粒子的状态,并移除那些已经“死亡”的粒子。通过这种方式,代码能够高效地管理大量粒子的生命周期,从而实现流畅的动画效果。

在粒子图像生成方面,代码通过一个辅助的画布元素来绘制心形图案。这个图案的形状是通过参数化方程生成的,具体而言,心形图案由一个数学函数 pointOnHeart(t) 所描述,该函数以参数 t 为输入,生成一个二维平面的点。这个点的坐标被用来绘制心形的轮廓线,并最终填充为粉红色。

在整个粒子系统运行过程中,代码会根据当前时间生成一定数量的新粒子,并将它们添加到粒子池中。每个新生成的粒子根据心形函数的位置来决定其初始位置,并通过随机方向和速度赋予其生命力。然后,通过 render 方法,代码持续更新画布上的粒子位置,并根据粒子的生命时长来调整其透明度,逐渐让粒子消失,模拟出一个心跳的效果。

最后,代码还考虑了窗口尺寸变化对画布的影响,通过 onResize 方法动态调整画布的宽度和高度,以确保在不同设备和窗口大小下都能正确显示心形动画。

总的来说,这段代码通过巧妙的数学计算和高效的粒子管理,实现了一个美丽而动感的心形动画。这种动画效果不仅仅是技术的体现,更是数学与美学的结合,展示了代码在艺术创作中的潜力。

系列文章

序号

目录

1

HTML满屏跳动的爱心(可写字)

2

HTML五彩缤纷的爱心

3

HTML满屏漂浮爱心

4

HTML情人节快乐

5

HTML蓝色爱心射线

6

HTML跳动的爱心(简易版)

7

HTML粒子爱心

8

HTML蓝色动态爱心

9

HTML跳动的爱心(双心版)

10

HTML橙色动态粒子爱心

11

HTML旋转爱心

12

HTML爱情树

13

HTML3D相册

14

HTML旋转相册

15

HTML基础烟花秀

16

HTML炫酷烟花秀

17

HTML粉色烟花秀

18

HTML新春烟花

19

HTML龙年大吉

20

HTML圣诞树

21

HTML大雪纷飞

22

HTML想见你

23

HTML元素周期表

24

HTML飞舞的花瓣

25

HTML星空特效

26

HTML黑客帝国字母雨

27

HTML哆啦A梦

28

HTML流星雨

29HTML沙漏爱心
30HTML爱心字母雨

写在最后

我是一只有趣的兔子,感谢你的喜欢!

这篇关于HTML沙漏爱心的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1114369

相关文章

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

css中的 vertical-align与line-height作用详解

《css中的vertical-align与line-height作用详解》:本文主要介绍了CSS中的`vertical-align`和`line-height`属性,包括它们的作用、适用元素、属性值、常见使用场景、常见问题及解决方案,详细内容请阅读本文,希望能对你有所帮助... 目录vertical-ali

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

Python实现html转png的完美方案介绍

《Python实现html转png的完美方案介绍》这篇文章主要为大家详细介绍了如何使用Python实现html转png功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 1.增强稳定性与错误处理建议使用三层异常捕获结构:try: with sync_playwright(

Vue 调用摄像头扫描条码功能实现代码

《Vue调用摄像头扫描条码功能实现代码》本文介绍了如何使用Vue.js和jsQR库来实现调用摄像头并扫描条码的功能,通过安装依赖、获取摄像头视频流、解析条码等步骤,实现了从开始扫描到停止扫描的完整流... 目录实现步骤:代码实现1. 安装依赖2. vue 页面代码功能说明注意事项以下是一个基于 Vue.js

CSS @media print 使用详解

《CSS@mediaprint使用详解》:本文主要介绍了CSS中的打印媒体查询@mediaprint包括基本语法、常见使用场景和代码示例,如隐藏非必要元素、调整字体和颜色、处理链接的URL显示、分页控制、调整边距和背景等,还提供了测试方法和关键注意事项,并分享了进阶技巧,详细内容请阅读本文,希望能对你有所帮助...

Nginx实现前端灰度发布

《Nginx实现前端灰度发布》灰度发布是一种重要的策略,它允许我们在不影响所有用户的情况下,逐步推出新功能或更新,通过灰度发布,我们可以测试新版本的稳定性和性能,下面就来介绍一下前端灰度发布的使用,感... 目录前言一、基于权重的流量分配二、基于 Cookie 的分流三、基于请求头的分流四、基于请求参数的分

基于Canvas的Html5多时区动态时钟实战代码

《基于Canvas的Html5多时区动态时钟实战代码》:本文主要介绍了如何使用Canvas在HTML5上实现一个多时区动态时钟的web展示,通过Canvas的API,可以绘制出6个不同城市的时钟,并且这些时钟可以动态转动,每个时钟上都会标注出对应的24小时制时间,详细内容请阅读本文,希望能对你有所帮助...

HTML5 data-*自定义数据属性的示例代码

《HTML5data-*自定义数据属性的示例代码》HTML5的自定义数据属性(data-*)提供了一种标准化的方法在HTML元素上存储额外信息,可以通过JavaScript访问、修改和在CSS中使用... 目录引言基本概念使用自定义数据属性1. 在 html 中定义2. 通过 JavaScript 访问3.

CSS模拟 html 的 title 属性(鼠标悬浮显示提示文字效果)

《CSS模拟html的title属性(鼠标悬浮显示提示文字效果)》:本文主要介绍了如何使用CSS模拟HTML的title属性,通过鼠标悬浮显示提示文字效果,通过设置`.tipBox`和`.tipBox.tipContent`的样式,实现了提示内容的隐藏和显示,详细内容请阅读本文,希望能对你有所帮助... 效