本文主要是介绍HTML爱心流星雨,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
写在前面
完整代码
代码分析
推荐系列
写在后面
写在前面
如何用HTML代码实现爱心+流星雨的动态效果?本期博主将带着大家探索神奇的HTML。
完整代码
<!doctype html>
<html>
<head><meta charset="utf-8"><title>爱心流星雨</title><style>html,body {height: 100%;padding: 0;margin: 0;background-color: black;}canvas {position: absolute;width: 100%;height: 100%;}
</style>
</head>
<body><canvas id="pinkboard"></canvas><canvas id="stars"></canvas><script>var context;var arr = new Array();var starCount = 800;var rains = new Array();var rainCount = 20;//初始化画布及contextfunction init() {//获取canvasvar stars = document.getElementById("stars");windowWidth = window.innerWidth; //当前的窗口的高度stars.width = windowWidth;stars.height = window.innerHeight;//获取contextcontext = stars.getContext("2d");}//创建一个星星对象var Star = function () {this.x = windowWidth * Math.random();//横坐标this.y = 5000 * Math.random();//纵坐标this.text = "❤";//文本this.color = "#ea80b0";//颜色//产生随机颜色this.getColor = function () {var _r = Math.random();if (_r < 0.5) {this.color = "#333";} else {this.color = "#ea80b0";}}//初始化this.init = function () {this.getColor();}//绘制this.draw = function () {context.fillStyle = this.color;context.fillText(this.text, this.x, this.y);}}//页面加载的时候window.onload = function () {init();//画星星for (var i = 0; i < starCount; i++) {var star = new Star();star.init();star.draw();arr.push(star);}//画流星for (var i = 0; i < rainCount; i++) {var rain = new MeteorRain();rain.init();rain.draw();rains.push(rain);}playStars();//绘制闪动的星星playRains();//绘制流星}//星星闪起来function playStars() {for (var n = 0; n < starCount; n++) {arr[n].getColor();arr[n].draw();}setTimeout("playStars()", 100);}var MeteorRain = function () {this.x = -1;this.y = -1;this.length = -1;//长度this.angle = 30; //倾斜角度this.width = -1;//宽度this.height = -1;//高度this.speed = 1;//速度this.offset_x = -1;//横轴移动偏移量this.offset_y = -1;//纵轴移动偏移量this.alpha = 1; //透明度this.color1 = "#ea80b0";//流星的色彩this.color2 = ""; //流星的色彩this.init = function () //初始化
{this.getPos();this.alpha = 1;//透明度this.getRandomColor();//最小长度,最大长度var x = Math.random() * 80 + 150;this.length = Math.ceil(x);// x = Math.random()*10+30;this.angle = 30; //流星倾斜角x = Math.random() + 0.5;this.speed = Math.ceil(x); //流星的速度var cos = Math.cos(this.angle * 3.14 / 180);var sin = Math.sin(this.angle * 3.14 / 180);this.width = this.length * cos; //流星所占宽度this.height = this.length * sin;//流星所占高度this.offset_x = this.speed * cos;this.offset_y = this.speed * sin;}this.getRandomColor = function () {var a = Math.ceil(255 - 240 * Math.random());//中段颜色this.color1 = "rgba(" + a + "," + a + "," + a + ",1)";//结束颜色this.color2 = "black";}this.countPos = function ()//
{//往左下移动,x减少,y增加this.x = this.x - this.offset_x;this.y = this.y + this.offset_y;}this.getPos = function () //
{//横坐标200--1200this.x = Math.random() * window.innerWidth; //窗口高度//纵坐标小于600this.y = Math.random() * window.innerHeight; //窗口宽度}this.draw = function () //绘制一个流星的函数
{context.save();context.beginPath();context.lineWidth = 1; //宽度context.globalAlpha = this.alpha; //设置透明度//创建横向渐变颜色,起点坐标至终点坐标var line = context.createLinearGradient(this.x, this.y,this.x + this.width,this.y - this.height);//分段设置颜色line.addColorStop(0, "#ea80b0");line.addColorStop(0.3, this.color1);line.addColorStop(0.6, this.color2);context.strokeStyle = line;//起点context.moveTo(this.x, this.y);//终点context.lineTo(this.x + this.width, this.y - this.height);context.closePath();context.stroke();context.restore();}this.move = function () {//清空流星像素var x = this.x + this.width - this.offset_x;var y = this.y - this.height;context.clearRect(x - 3, y - 3, this.offset_x + 5, this.offset_y + 5);// context.strokeStyle="red";// context.strokeRect(x,y-1,this.offset_x+1,this.offset_y+1);//重新计算位置,往左下移动this.countPos();//透明度增加this.alpha -= 0.002;//重绘this.draw();}}//绘制流星function playRains() {for (var n = 0; n < rainCount; n++) {var rain = rains[n];rain.move();//移动if (rain.y > window.innerHeight) {//超出界限后重来context.clearRect(rain.x, rain.y - rain.height, rain.width, rain.height);rains[n] = new MeteorRain();rains[n].init();}}setTimeout("playRains()", 2);}var settings = {particles: {length: 500, duration: 2, velocity: 100, effect: -0.75, size: 20, },};(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) } }}());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;})();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(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);}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 = '#ea80b0';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 = canvas.clientWidth;canvas.height = canvas.clientHeight;}window.onresize = onResize;setTimeout(function () {onResize();render();}, 10);})(document.getElementById('pinkboard'));
</script>
</body>
</html>
代码分析
HTML和CSS
页面主要包含两个部分:一个<canvas>
标签用于绘制粒子爱心效果,另一个<canvas>
标签用于绘制闪烁的心形和流星动画。CSS设置了整个页面的背景颜色为黑色,并使两个画布覆盖整个浏览器窗口。
JavaScript
JavaScript部分主要通过window.onload
事件来初始化画布和启动动画。init()
函数设置了stars
画布的宽度和高度,并获取其绘图上下文。
心形动画
心形动画由一个Star
类实现,该类有以下属性和方法:
-
x
:心形的横坐标。 -
y
:心形的纵坐标。 -
text
:显示的文本(心形符号)。 -
color
:心形的颜色。
-
getColor()
:随机设置心形颜色。 -
init()
:初始化心形的颜色。 -
draw()
:在画布上绘制心形。
在页面加载时,会创建大量的Star
对象,并调用其init()
和draw()
方法进行绘制。playStars()
函数使心形闪烁,通过不断调用getColor()
和draw()
方法,并使用setTimeout
定时器循环实现。
流星动画
流星动画由一个MeteorRain
类实现,该类有以下属性和方法:
-
x
和y
:流星的起始位置。 -
length
:流星的长度。 -
angle
:流星的倾斜角度。 -
width
和height
:流星的宽高。 -
speed
:流星的速度。 -
offset_x
和offset_y
:流星的横向和纵向位移量。 -
alpha
:流星的透明度。 -
color1
和color2
:流星的颜色(使用渐变效果)。
-
init()
:初始化流星的起始位置、速度和颜色。 -
getRandomColor()
:随机生成流星的颜色。 -
countPos()
:计算流星的位置。 -
getPos()
:生成流星的起始位置。 -
draw()
:在画布上绘制流星。 -
move()
:更新流星的位置。
在页面加载时,会创建一定数量的MeteorRain
对象,并调用其init()
和draw()
方法进行绘制。playRains()
函数通过不断调用move()
方法来更新流星的位置,并使用setTimeout
定时器循环实现。
爱心动画
粒子爱心效果由多个类实现,包括Point
、Particle
和ParticlePool。
-
Point类:表示二维平面上的一个点,提供克隆、长度和归一化方法。
-
Particle类:表示一个粒子,具有位置、速度、加速度和年龄等属性,提供初始化、更新和绘制方法。
-
ParticlePool类:管理粒子的池,提供添加、更新和绘制粒子的方法。
粒子爱心效果通过pointOnHeart(t)
函数生成心形路径上的点。粒子池管理和更新这些粒子,并在每一帧动画中绘制它们。
在初始化时,会创建一个心形路径的粒子图像,并通过requestAnimationFrame
实现动画的逐帧渲染。render()
函数是动画的核心,负责更新时间、清空画布、创建新粒子、更新和绘制粒子。onResize()
函数确保画布在窗口大小改变时自适应调整。
总结
整个代码通过HTML、CSS和JavaScript实现了一个视觉效果丰富的网页动画,展示了闪烁的心形和流星,以及中心的粒子爱心效果。通过使用canvas
和逐帧动画技术,代码创造了一个生动的视觉体验。
推荐系列
序号 | 目录 |
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流星雨 |
29 | HTML沙漏爱心 |
30 | HTML爱心字母雨 |
31 | HTML爱心流星雨 |
写在后面
我是一只有趣的兔子,感谢你的喜欢!
这篇关于HTML爱心流星雨的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!