当前位置: 首页 > article >正文

HTML粉色烟花秀

图片

目录

系列文章

写在前面

完整代码

代码分析

写在最后


系列文章

序号目录
1HTML满屏跳动的爱心(可写字)
2HTML五彩缤纷的爱心
3HTML满屏漂浮爱心
4HTML情人节快乐
5HTML蓝色爱心射线
6HTML跳动的爱心(简易版)
7HTML粒子爱心
8HTML蓝色动态爱心
9HTML跳动的爱心(双心版)
10HTML橙色动态粒子爱心
11HTML旋转爱心
12HTML爱情树
13HTML3D相册
14HTML旋转相册
15HTML基础烟花秀
16HTML炫酷烟花秀
17HTML粉色烟花秀
18HTML新春烟花
19HTML龙年大吉
20HTML圣诞树
21HTML大雪纷飞
22HTML想见你
23HTML元素周期表
24HTML飞舞的花瓣
25HTML星空特效
26HTML黑客帝国字母雨
27HTML哆啦A梦
28HTML流星雨
29HTML沙漏爱心
30HTML爱心字母雨
31HTML爱心流星雨
32HTML生日蛋糕

写在前面

马上就要到2025年喽,博主用 html 给大家准备了粉色系的跨年烟花秀,一起来看看吧~

HTML(Hypertext Markup Language)是一种标记语言,用于创建网页的结构和内容。它使用一系列标签(tag)来标记文本,以指示浏览器如何展示内容。HTML是万维网的基础技术之一,它定义了网页的结构和链接方式。

HTML的发展可以追溯到1989年,由蒂姆·伯纳斯-李(Tim Berners-Lee)创始于欧洲核子研究组织(CERN)。最初,HTML只是用于将文档链接在一起,没有表现力很强。随着互联网的发展,HTML的功能逐渐增强,可以实现各种复杂的效果。

HTML由标签构成。标签通常用尖括号表示,例如<tag>。标签可以有属性(attribute),用于指定标签的属性值。属性通常包括名称和值,以键值对的形式表示。例如,<tag attribute="value">。

HTML文档通常由头部(head)和主体(body)组成。头部包含了文档的元信息,例如标题、样式表和脚本。主体包含了文档的实际内容,例如段落、标题、图像和链接。

HTML常用的标签和功能:

1. 标题标签(<h1>到<h6>)用于定义标题的级别和重要性。

2. 段落标签(<p>)用于定义段落。

3. 链接标签(<a>)用于创建链接到其他网页或文件的超链接。

4. 图像标签(<img>)用于在网页中插入图像。

5. 列表标签(<ul>和<ol>)用于创建无序列表和有序列表。

6. 表格标签(<table>、<tr>和<td>)用于创建表格。

7. 表单标签(<form>、<input>和<button>)用于创建交互式表单。

8. 样式标签(<style>)用于定义文档的样式。

9. 脚本标签(<script>)用于在网页中嵌入JavaScript脚本。

除了这些基本功能外,HTML还支持更多的标签和功能,例如音频和视频播放、动画效果、地理定位等。此外,HTML还可以与CSS(层叠样式表)和JavaScript等技术一起使用,以实现更复杂和交互式的网页效果。

总结起来,HTML是一种用于创建网页结构和内容的标记语言。它使用标签来标记文本,并告诉浏览器如何展示内容。HTML的功能丰富多样,可以实现各种各样的网页效果。掌握HTML是学习Web开发的第一步。

完整代码

<!DOCTYPE html>
<html lang="en">
<script>
  var _hmt = _hmt || [];
  (function () {
    var hm = document.createElement("script");
    hm.src = "https://hm.baidu.com/hm.js?c923daf3182a4b0ce01878475080aadc";
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(hm, s);
  })();
</script>

<head>
  <meta charset="UTF-8">
  <title>新年快乐!</title>
</head>
<style>
  body {
    margin: 0;
    overflow: hidden;
    background: black;
  }

  canvas {
    position: absolute;
  }
</style>

<body>

  <canvas></canvas>
  <canvas></canvas>
  <canvas></canvas>

  <script>

    function GetRequest() {
      var url = decodeURI(location.search);
      var theRequest = new Object();
      if (url.indexOf("?") != -1) {
        var str = url.substr(1);
        strs = str.split("&");
        for (var i = 0; i < strs.length; i++) {
          theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
        }
      }
      return theRequest;
    }
    class Shard {
      constructor(x, y, hue) {
        this.x = x;
        this.y = y;
        this.hue = hue;
        this.lightness = 50;
        this.size = 15 + Math.random() * 10;
        const angle = Math.random() * 2 * Math.PI;
        const blastSpeed = 1 + Math.random() * 6;
        this.xSpeed = Math.cos(angle) * blastSpeed;
        this.ySpeed = Math.sin(angle) * blastSpeed;
        this.target = getTarget();
        this.ttl = 100;
        this.timer = 0;
      }
      draw() {
        ctx2.fillStyle = `hsl(${this.hue}, 100%, ${this.lightness}%)`;
        ctx2.beginPath();
        ctx2.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
        ctx2.closePath();
        ctx2.fill();
      }
      update() {
        if (this.target) {
          const dx = this.target.x - this.x;
          const dy = this.target.y - this.y;
          const dist = Math.sqrt(dx * dx + dy * dy);
          const a = Math.atan2(dy, dx);
          const tx = Math.cos(a) * 5;
          const ty = Math.sin(a) * 5;
          this.size = lerp(this.size, 1.5, 0.05);

          if (dist < 5) {
            this.lightness = lerp(this.lightness, 100, 0.01);
            this.xSpeed = this.ySpeed = 0;
            this.x = lerp(this.x, this.target.x + fidelity / 2, 0.05);
            this.y = lerp(this.y, this.target.y + fidelity / 2, 0.05);
            this.timer += 1;
          } else
            if (dist < 10) {
              this.lightness = lerp(this.lightness, 100, 0.01);
              this.xSpeed = lerp(this.xSpeed, tx, 0.1);
              this.ySpeed = lerp(this.ySpeed, ty, 0.1);
              this.timer += 1;
            } else {
              this.xSpeed = lerp(this.xSpeed, tx, 0.02);
              this.ySpeed = lerp(this.ySpeed, ty, 0.02);
            }
        } else {
          this.ySpeed += 0.05;

          this.size = lerp(this.size, 1, 0.05);

          if (this.y > c2.height) {
            shards.forEach((shard, idx) => {
              if (shard === this) {
                shards.splice(idx, 1);
              }
            });
          }
        }
        this.x = this.x + this.xSpeed;
        this.y = this.y + this.ySpeed;
      }
    }

    class Rocket {
      constructor() {
        const quarterW = c2.width / 4;
        this.x = quarterW + Math.random() * (c2.width - quarterW);
        this.y = c2.height - 15;
        this.angle = Math.random() * Math.PI / 4 - Math.PI / 6;
        this.blastSpeed = 6 + Math.random() * 7;
        this.shardCount = 15 + Math.floor(Math.random() * 15);
        this.xSpeed = Math.sin(this.angle) * this.blastSpeed;
        this.ySpeed = -Math.cos(this.angle) * this.blastSpeed;
        this.hue = Math.floor(Math.random() * 360);
        this.trail = [];
      }
      draw() {
        ctx2.save();
        ctx2.translate(this.x, this.y);
        ctx2.rotate(Math.atan2(this.ySpeed, this.xSpeed) + Math.PI / 2);
        ctx2.fillStyle = `hsl(${this.hue}, 100%, 50%)`;
        ctx2.fillRect(0, 0, 5, 15);
        ctx2.restore();
      }
      update() {
        this.x = this.x + this.xSpeed;
        this.y = this.y + this.ySpeed;
        this.ySpeed += 0.1;
      }

      explode() {
        for (let i = 0; i < 70; i++) {
          shards.push(new Shard(this.x, this.y, this.hue));
        }
      }
    }

    console.log(GetRequest('val').val)

    const [c1, c2, c3] = document.querySelectorAll('canvas');
    const [ctx1, ctx2, ctx3] = [c1, c2, c3].map(c => c.getContext('2d'));
    let fontSize = 200;
    const rockets = [];
    const shards = [];
    const targets = [];
    const fidelity = 3;
    let counter = 0;
    c2.width = c3.width = window.innerWidth;
    c2.height = c3.height = window.innerHeight;
    ctx1.fillStyle = 'skyblue';
    const text = '新年快乐'
    let textWidth = 9999;

    while (textWidth > window.innerWidth) {
      ctx1.font = `900 ${fontSize--}px Arial`;
      textWidth = ctx1.measureText(text).width;
    }

    c1.width = textWidth;
    c1.height = fontSize * 1.5;
    ctx1.font = `900 ${fontSize}px Arial`;
    ctx1.fillText(text, 0, fontSize - 30);
    const imgData = ctx1.getImageData(0, 0, c1.width, c1.height);
    for (let i = 0, max = imgData.data.length; i < max; i += 4) {
      const alpha = imgData.data[i + 3];
      const x = Math.floor(i / 4) % imgData.width;
      const y = Math.floor(i / 4 / imgData.width);

      if (alpha && x % fidelity === 0 && y % fidelity === 0) {
        targets.push({ x, y });
      }
    }

    ctx3.fillStyle = 'pink';
    ctx3.shadowColor = 'pink';
    ctx3.shadowBlur = 25;


    (function loop() {
      ctx2.fillStyle = "deeppink";
      ctx2.fillRect(0, 0, c2.width, c2.height);
      counter += 1;

      if (counter % 15 === 0) {
        rockets.push(new Rocket());
      }
      rockets.forEach((r, i) => {
        r.draw();
        r.update();
        if (r.ySpeed > 0) {
          r.explode();
          rockets.splice(i, 1);
        }
      });

      shards.forEach((s, i) => {
        s.draw();
        s.update();

        if (s.timer >= s.ttl || s.lightness >= 99) {
          ctx3.fillRect(s.target.x, s.target.y, fidelity + 1, fidelity + 1);
          shards.splice(i, 1);
        }
      });

      requestAnimationFrame(loop);
    })();

    const lerp = (a, b, t) => Math.abs(b - a) > 0.1 ? a + t * (b - a) : b;

    function getTarget() {
      if (targets.length > 0) {
        const idx = Math.floor(Math.random() * targets.length);
        let { x, y } = targets[idx];
        targets.splice(idx, 1);

        x += c2.width / 2 - textWidth / 2;
        y += c2.height / 2 - fontSize / 2;

        return { x, y };
      }
    }
  </script>

</body>

</html>

修改文字

在代码的第185、186可以修改中间的文字颜色哦~

在代码的第191行可以修改背景颜色哦~

代码分析

这段代码通过HTML和JavaScript结合,创建了一个“新年快乐”主题的烟花动画,并在屏幕上显示文字“新年快乐”。其实现方式主要涉及画布(canvas)操作、火箭发射、烟花爆炸以及文字的动态生成与展示。以下是这段代码的详细分析。

一、代码结构概览

代码主要分为三部分:

  1. HTML结构:通过<canvas>标签创建三个画布,用于不同的绘图操作。
  2. CSS样式:设置画布和页面的样式,使背景为黑色,并使画布覆盖整个页面。
  3. JavaScript逻辑:核心部分,负责烟花的发射、爆炸效果以及文字的生成。

二、画布的初始化与配置

在代码中,使用了三个canvas元素,它们通过JavaScript分别绑定到三个上下文对象:ctx1ctx2ctx3,用于不同的绘制操作。

  • ctx1:负责绘制“新年快乐”文字。
  • ctx2:负责绘制火箭的飞行和烟花的爆炸效果。
  • ctx3:用于绘制烟花爆炸后的残留效果。

这三个画布通过设置宽度和高度,确保其覆盖整个窗口。c1的宽高根据文字的宽度和字体大小动态调整,以确保文字能够适应屏幕。

三、文字的生成

代码通过ctx1.fillText方法在画布上绘制“新年快乐”文字。首先,代码根据屏幕的宽度动态调整字体大小,确保文字不会超出屏幕宽度。然后,getImageData方法获取画布上的像素数据,以提取出文字的形状。

通过逐个检查像素的透明度值(alpha),代码识别出文字中每个可见部分的坐标。接着,这些坐标存储在targets数组中,作为烟花爆炸的目标点。烟花爆炸后,碎片会逐渐飞向这些目标点,最终在屏幕上组成文字“新年快乐”。

四、烟花动画

烟花动画的核心是Rocket(火箭)和Shard(烟花碎片)两个类。

  • Rocket类:代表烟花的发射过程。每个火箭有随机的初始位置和发射角度,沿着一条随机的轨迹上升。update方法用于更新火箭的位置,模拟火箭上升的运动;当火箭达到一定高度后,通过explode方法使其爆炸,生成多个Shard对象。
  • Shard类:代表烟花爆炸后的碎片。每个碎片有随机的速度和方向,在空中飞行并逐渐减速。碎片的目标是之前生成的文字的像素点,它们会逐渐朝着这些目标移动,直到到达目标点后停止。

在代码中,使用了requestAnimationFrame实现动画的平滑更新。loop函数是动画的主循环,在每一帧中都会更新火箭和碎片的位置,并重绘整个画布。

五、颜色和效果

在这段代码中,颜色的变化通过HSL色彩模型实现。每个火箭和烟花碎片都有一个随机的hue值,决定了它们的颜色。Shard类的draw方法使用ctx2.arc画圆的方法绘制每个碎片,并通过调整lightness值模拟烟花的逐渐消失效果。

此外,代码还通过shadowColorshadowBlur为爆炸后的烟花添加了阴影效果,使得爆炸显得更加闪亮逼真。

六、目标点与插值

碎片飞向文字目标点的过程使用了线性插值(lerp)算法,lerp函数用于在当前碎片位置与目标位置之间进行平滑过渡。通过不断缩小位置差距,碎片能够逐渐接近并最终停留在目标点。

七、火箭与碎片的生命周期

每个火箭和碎片都有各自的生命周期。当火箭上升到一定高度时,会自动触发爆炸,生成碎片。而每个碎片则在到达目标点或超过一定的存活时间后从数组中移除。这样可以避免画布上元素的无限增长,保证动画的性能和流畅度。

八、总结

这段代码通过使用HTML5的canvas元素,结合JavaScript中的对象和动画操作,实现了一个复杂而又美观的烟花动画。代码的核心思想是将烟花的爆炸与文字的显示相结合,通过计算每个像素点的位置,使烟花碎片能够精确地拼成文字。同时,代码还采用了多种动画技巧,如随机生成、插值算法和帧动画,确保动画的自然流畅。

写在最后

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


http://www.kler.cn/a/314759.html

相关文章:

  • 以往运维岗本人面试真题分享
  • AI写作(四)预训练语言模型:开启 AI 写作新时代(4/10)
  • 谷歌浏览器的自动翻译功能如何开启
  • 《JavaEE进阶》----20.<基于Spring图书管理系统①(登录+添加图书)>
  • 协程3 --- golang的协程调度
  • LeetCode【0016】最接近的三数之和
  • python新手的五个练习题
  • MySQl索引事务(B树)
  • 基于 K8S kubernetes 的常见日志收集方案
  • 大模型如何学习数据
  • NLP 文本分类核心问题
  • LangChain教程 - 构建一个检索增强生成 (RAG) 应用程序
  • 面试金典题8
  • go webapi上传文件
  • 【Linux】Docker:离线主机部署
  • 【Temporal】日志打印控制
  • 【AI视频】AI虚拟主播制作网站推荐
  • 深度学习02-pytorch-06-张量的形状操作
  • 基于深度学习的智能电网优化
  • Java异常架构与异常关键字
  • Spring后端直接用枚举类接收参数,自定义通用枚举类反序列化器
  • IT行业:未来发展的无限可能
  • 【医学半监督】置信度指导遮蔽学习的半监督医学图像分割
  • 51单片机-系列-数码管中断和定时器
  • Lsposed Java HOOK原理及检测
  • 我的AI工具箱Tauri版-VideoIntroductionClipCut视频介绍混剪