【趣味Html】第11课:动态闪烁发光粒子五角星

打造炫酷的动态闪烁发光粒子五角星效果

在这里插入图片描述

前言

在现代Web开发中,视觉效果的重要性不言而喻。今天我们将深入探讨如何使用HTML5 Canvas和JavaScript创建一个令人惊艳的动态闪烁发光粒子五角星效果。这个项目不仅展示了Canvas的强大功能,还涉及了粒子系统、动画循环、数学计算等多个技术要点。

项目概述

我们创建的效果包含以下特性:

  • 🌟 自动旋转的五角星
  • ✨ 动态发光效果(呼吸灯效果)
  • 🎆 粒子系统(从五角星边缘发射粒子)
  • 🎮 鼠标交互(靠近时产生更多粒子)
  • 📱 响应式设计

技术架构

1. 基础结构

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>动态闪烁发光粒子五角星</title><style>body {margin: 0;padding: 0;background: #000;overflow: hidden;display: flex;justify-content: center;align-items: center;height: 100vh;}canvas {border: 1px solid #333;}</style>
</head>
<body><canvas id="starCanvas"></canvas>
</body>
</html>

2. 核心类设计

Particle 类(粒子系统)

粒子类是整个效果的核心组件之一,负责创建和管理单个粒子的行为:

class Particle {constructor(x, y) {this.x = x;                                    // 粒子位置this.y = y;this.vx = (Math.random() - 0.5) * 2;          // 随机速度this.vy = (Math.random() - 0.5) * 2;this.life = 1;                                // 生命值this.decay = Math.random() * 0.02 + 0.005;    // 衰减速度this.size = Math.random() * 3 + 1;            // 粒子大小this.color = {                                // 随机颜色r: Math.random() * 100 + 155,g: Math.random() * 100 + 155,b: Math.random() * 100 + 155};}update() {this.x += this.vx;        // 更新位置this.y += this.vy;this.life -= this.decay;  // 减少生命值this.size *= 0.99;        // 缩小粒子}draw() {// 绘制发光效果和粒子本体}
}

设计要点:

  • 使用随机值创建自然的粒子运动
  • 生命周期管理确保粒子会自然消失
  • 渐变发光效果增强视觉冲击力
Star 类(五角星系统)

五角星类管理五角星的绘制、旋转和粒子生成:

class Star {constructor(x, y, size) {this.x = x;this.y = y;this.size = size;this.rotation = 0;              // 旋转角度this.glowIntensity = 0;         // 发光强度this.glowDirection = 1;         // 发光方向this.particles = [];            // 粒子数组this.lastParticleTime = 0;      // 上次生成粒子的时间}getStarPoints() {// 计算五角星的10个顶点坐标const points = [];const outerRadius = this.size;const innerRadius = this.size * 0.4;for (let i = 0; i < 10; i++) {const angle = (i * Math.PI) / 5 + this.rotation;const radius = i % 2 === 0 ? outerRadius : innerRadius;const x = this.x + Math.cos(angle) * radius;const y = this.y + Math.sin(angle) * radius;points.push({ x, y });}return points;}
}

核心算法解析

1. 五角星顶点计算

五角星的绘制是基于数学计算的。一个标准五角星有10个顶点(5个外顶点和5个内顶点):

// 五角星顶点计算公式
for (let i = 0; i < 10; i++) {const angle = (i * Math.PI) / 5 + this.rotation;  // 每个顶点间隔36度const radius = i % 2 === 0 ? outerRadius : innerRadius;const x = centerX + Math.cos(angle) * radius;const y = centerY + Math.sin(angle) * radius;
}

数学原理:

  • 五角星的外角为36°(2π/10)
  • 内外半径比例约为0.4,创造最佳视觉效果
  • 通过旋转角度实现动态旋转

2. 粒子生成策略

粒子的生成采用了多种策略来创造丰富的视觉效果:

generateParticles() {const points = this.getStarPoints();// 策略1:在五角星边缘生成粒子for (let i = 0; i < points.length; i++) {const point = points[i];const nextPoint = points[(i + 1) % points.length];// 线性插值在边缘随机位置生成粒子const t = Math.random();const x = point.x + (nextPoint.x - point.x) * t;const y = point.y + (nextPoint.y - point.y) * t;if (Math.random() < 0.3) {this.particles.push(new Particle(x, y));}}// 策略2:在顶点生成更多粒子for (let i = 0; i < points.length; i += 2) {const point = points[i];if (Math.random() < 0.5) {this.particles.push(new Particle(point.x, point.y));}}
}

3. 发光效果实现

发光效果通过Canvas的阴影和渐变功能实现:

// 动态发光强度
this.glowIntensity += this.glowDirection * 0.02;
if (this.glowIntensity >= 1 || this.glowIntensity <= 0) {this.glowDirection *= -1;  // 反向,创造呼吸效果
}// 应用发光效果
ctx.shadowColor = `rgba(255, 255, 100, ${this.glowIntensity})`;
ctx.shadowBlur = 20 + this.glowIntensity * 30;

性能优化技巧

1. 粒子生命周期管理

// 高效的粒子清理
this.particles = this.particles.filter(particle => {particle.update();return particle.life > 0;  // 只保留活着的粒子
});

2. 时间控制的粒子生成

// 避免每帧都生成粒子,控制生成频率
const now = Date.now();
if (now - this.lastParticleTime > 50) {this.generateParticles();this.lastParticleTime = now;
}

3. 渐进式画布清理

// 使用半透明矩形而非完全清除,创造拖尾效果
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);

交互设计

鼠标交互

canvas.addEventListener('mousemove', (e) => {const rect = canvas.getBoundingClientRect();const mouseX = e.clientX - rect.left;const mouseY = e.clientY - rect.top;stars.forEach(star => {const dx = mouseX - star.x;const dy = mouseY - star.y;const distance = Math.sqrt(dx * dx + dy * dy);if (distance < 150) {// 鼠标靠近时增加粒子生成for (let i = 0; i < 3; i++) {const angle = Math.random() * Math.PI * 2;const radius = Math.random() * star.size;const x = star.x + Math.cos(angle) * radius;const y = star.y + Math.sin(angle) * radius;star.particles.push(new Particle(x, y));}}});
});

响应式设计

window.addEventListener('resize', () => {canvas.width = window.innerWidth;canvas.height = window.innerHeight;// 重新定位五角星stars.forEach((star, i) => {star.x = canvas.width / 4 + (i * canvas.width / 4);star.y = canvas.height / 2 + Math.sin(i * 2) * 100;});
});

扩展可能性

1. 颜色主题

可以添加多种颜色主题,让用户选择不同的视觉风格:

const themes = {golden: { r: 255, g: 215, b: 0 },blue: { r: 100, g: 150, b: 255 },purple: { r: 200, g: 100, b: 255 }
};

2. 音频响应

可以集成Web Audio API,让粒子效果响应音频频率:

// 伪代码
const audioContext = new AudioContext();
// 根据音频频率调整粒子生成速度和五角星大小

3. 3D效果

使用WebGL或Three.js可以将效果扩展到3D空间。

总结

这个动态闪烁发光粒子五角星项目展示了现代Web技术的强大能力。通过合理的类设计、数学计算、性能优化和交互设计,我们创造了一个既美观又高效的视觉效果。

关键技术点:

  • Canvas 2D API的高级应用
  • 面向对象的JavaScript设计
  • 数学在图形编程中的应用
  • 性能优化策略
  • 用户交互设计

这个项目不仅可以作为学习Canvas和JavaScript的优秀案例,也可以作为更复杂视觉效果的基础框架。希望这篇博客能够帮助你理解现代Web图形编程的精髓,并激发你创造更多令人惊艳的视觉效果!

源码

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>动态闪烁发光粒子五角星</title><style>body {margin: 0;padding: 0;background: #000;overflow: hidden;display: flex;justify-content: center;align-items: center;height: 100vh;}canvas {border: 1px solid #333;}</style>
</head>
<body><canvas id="starCanvas"></canvas><script>const canvas = document.getElementById('starCanvas');const ctx = canvas.getContext('2d');// 设置画布大小canvas.width = window.innerWidth;canvas.height = window.innerHeight;// 粒子类class Particle {constructor(x, y) {this.x = x;this.y = y;this.vx = (Math.random() - 0.5) * 2;this.vy = (Math.random() - 0.5) * 2;this.life = 1;this.decay = Math.random() * 0.02 + 0.005;this.size = Math.random() * 3 + 1;this.color = {r: Math.random() * 100 + 155,g: Math.random() * 100 + 155,b: Math.random() * 100 + 155};}update() {this.x += this.vx;this.y += this.vy;this.life -= this.decay;this.size *= 0.99;}draw() {ctx.save();ctx.globalAlpha = this.life;// 创建发光效果const gradient = ctx.createRadialGradient(this.x, this.y, 0,this.x, this.y, this.size * 3);gradient.addColorStop(0, `rgba(${this.color.r}, ${this.color.g}, ${this.color.b}, 1)`);gradient.addColorStop(0.5, `rgba(${this.color.r}, ${this.color.g}, ${this.color.b}, 0.5)`);gradient.addColorStop(1, `rgba(${this.color.r}, ${this.color.g}, ${this.color.b}, 0)`);ctx.fillStyle = gradient;ctx.beginPath();ctx.arc(this.x, this.y, this.size * 3, 0, Math.PI * 2);ctx.fill();// 绘制核心粒子ctx.fillStyle = `rgba(${this.color.r}, ${this.color.g}, ${this.color.b}, 1)`;ctx.beginPath();ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);ctx.fill();ctx.restore();}}// 五角星类class Star {constructor(x, y, size) {this.x = x;this.y = y;this.size = size;this.rotation = 0;this.glowIntensity = 0;this.glowDirection = 1;this.particles = [];this.lastParticleTime = 0;}// 计算五角星的顶点getStarPoints() {const points = [];const outerRadius = this.size;const innerRadius = this.size * 0.4;for (let i = 0; i < 10; i++) {const angle = (i * Math.PI) / 5 + this.rotation;const radius = i % 2 === 0 ? outerRadius : innerRadius;const x = this.x + Math.cos(angle) * radius;const y = this.y + Math.sin(angle) * radius;points.push({ x, y });}return points;}update() {this.rotation += 0.01;// 更新发光强度this.glowIntensity += this.glowDirection * 0.02;if (this.glowIntensity >= 1 || this.glowIntensity <= 0) {this.glowDirection *= -1;}// 生成粒子const now = Date.now();if (now - this.lastParticleTime > 50) {this.generateParticles();this.lastParticleTime = now;}// 更新粒子this.particles = this.particles.filter(particle => {particle.update();return particle.life > 0;});}generateParticles() {const points = this.getStarPoints();// 在五角星边缘生成粒子for (let i = 0; i < points.length; i++) {const point = points[i];const nextPoint = points[(i + 1) % points.length];// 在边缘随机位置生成粒子const t = Math.random();const x = point.x + (nextPoint.x - point.x) * t;const y = point.y + (nextPoint.y - point.y) * t;if (Math.random() < 0.3) {this.particles.push(new Particle(x, y));}}// 在五角星顶点生成更多粒子for (let i = 0; i < points.length; i += 2) {const point = points[i];if (Math.random() < 0.5) {this.particles.push(new Particle(point.x, point.y));}}}draw() {const points = this.getStarPoints();// 绘制发光效果ctx.save();ctx.shadowColor = `rgba(255, 255, 100, ${this.glowIntensity})`;ctx.shadowBlur = 20 + this.glowIntensity * 30;// 绘制五角星主体ctx.fillStyle = `rgba(255, 255, 150, ${0.8 + this.glowIntensity * 0.2})`;ctx.strokeStyle = `rgba(255, 255, 200, ${0.9 + this.glowIntensity * 0.1})`;ctx.lineWidth = 2;ctx.beginPath();ctx.moveTo(points[0].x, points[0].y);for (let i = 1; i < points.length; i++) {ctx.lineTo(points[i].x, points[i].y);}ctx.closePath();ctx.fill();ctx.stroke();ctx.restore();// 绘制粒子this.particles.forEach(particle => particle.draw());}}// 创建多个五角星const stars = [];const numStars = 3;for (let i = 0; i < numStars; i++) {const x = canvas.width / 4 + (i * canvas.width / 4);const y = canvas.height / 2 + Math.sin(i * 2) * 100;const size = 50 + Math.random() * 30;stars.push(new Star(x, y, size));}// 动画循环function animate() {// 清除画布ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';ctx.fillRect(0, 0, canvas.width, canvas.height);// 更新和绘制所有五角星stars.forEach(star => {star.update();star.draw();});requestAnimationFrame(animate);}// 窗口大小调整window.addEventListener('resize', () => {canvas.width = window.innerWidth;canvas.height = window.innerHeight;// 重新定位五角星stars.forEach((star, i) => {star.x = canvas.width / 4 + (i * canvas.width / 4);star.y = canvas.height / 2 + Math.sin(i * 2) * 100;});});// 鼠标交互canvas.addEventListener('mousemove', (e) => {const rect = canvas.getBoundingClientRect();const mouseX = e.clientX - rect.left;const mouseY = e.clientY - rect.top;stars.forEach(star => {const dx = mouseX - star.x;const dy = mouseY - star.y;const distance = Math.sqrt(dx * dx + dy * dy);if (distance < 150) {// 鼠标靠近时增加粒子生成for (let i = 0; i < 3; i++) {const angle = Math.random() * Math.PI * 2;const radius = Math.random() * star.size;const x = star.x + Math.cos(angle) * radius;const y = star.y + Math.sin(angle) * radius;star.particles.push(new Particle(x, y));}}});});// 开始动画animate();</script>
</body>
</html>

如果你觉得这个效果有趣,不妨尝试修改参数,创造属于你自己的独特效果!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/908177.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6.RV1126-OPENCV 形态学基础膨胀及腐蚀

一.膨胀 1.膨胀原理 膨胀的本质就是通过微积分的转换&#xff0c;将图像A和图形B进行卷积操作合并成一个AB图像。核就是指任意的形状或者大小的图形B。例如下图&#xff0c;将核(也就是图形B)通过微积分卷积&#xff0c;和图像A合并成一个图像AB。 2.特点 图像就会更加明亮 …

机器学习实战37-基于情感字典和机器学习的股市舆情分析可视化系统

文章目录 一、项目背景数字时代情感分析情况二、项目流程1.数据采集与预处理2.复合情感分析模型构建3.舆情分析可视化:三、机器学习算法原理1.支持向量机基础2.核函数与高维映射3.情感分类特征融合4.模型训练与优化四、实现代码五、系统特点与优势1.复合情感分析模型2.多维度可…

STM32F407VET6学习笔记9:编译输出固定大小.bin文件

今日学习如何输出固定大小的.bin编译文件 目录 Keil_V5 fromelf.exe 软件目录&#xff1a; 魔棒添加命令输出bin文件&#xff1a; 输出固定大小的bin文件&#xff1a; 计算bin文件大小&#xff1a; 安装 SRecord 工具集&#xff1a; 使用SRecord&#xff1a; 参考文章&#…

【Web应用】若依框架:基础篇14 源码阅读-后端代码分析

文章目录 ⭐前言⭐一、课程讲解⭐总结 标题详情作者JosieBook头衔CSDN博客专家资格、阿里云社区专家博主、软件设计工程师博客内容开源、框架、软件工程、全栈&#xff08;,NET/Java/Python/C&#xff09;、数据库、操作系统、大数据、人工智能、工控、网络、程序人生口号成为你…

Java 单例模式详解

目录 1. 饿汉式&#xff08;Eager Initialization&#xff09; 2. 懒汉式&#xff08;Lazy Initialization&#xff09; 3. 懒汉式 同步锁&#xff08;线程安全&#xff09; 4. 双重检查锁&#xff08;Double-Checked Locking&#xff09; 5. 静态内部类&#xff08;推荐…

从 AMQP 到 RabbitMQ:核心组件设计与工作原理(一)

一、引言 ** 在当今分布式系统盛行的时代&#xff0c;消息队列作为一种关键的中间件技术&#xff0c;承担着系统间异步通信、解耦和削峰填谷的重要职责。AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;作为一种高级消息队列协议&#xff0c;为消息队列的实现…

概率单纯形(Probability Simplex)

目录 定义性质在统计学中的应用在机器学习中的应用在信息论中的应用在优化问题中的应用在其他领域的应用 定义 定义&#xff1a;在数学中&#xff0c;概率单纯形&#xff08;Probability Simplex&#xff09;是指在 n n n维空间中&#xff0c;所有分量非负且分量之和为1的向量…

项目练习:Vue2中el-button上的@click事件失效

文章目录 一、问题描述二、解决 一、问题描述 button按钮上绑定了一个click事件 对应的方法写在methods中 但是&#xff0c;测试点击时&#xff0c;无法触发函数 二、解决 1、问题代码 <el-buttonclick"changeConfirm(Y)"type"success"plainicon&qu…

十六、【前端强化篇】完善 TestCase 编辑器:支持 API 结构化定义与断言配置

【前端强化篇】完善 TestCase 编辑器:支持 API 结构化定义与断言配置 前言准备工作第一步:更新前端 `TestCase` 类型定义第二步:改造 `TestCaseEditView.vue` 表单第三步:修改后端代码中的TestCase模型和序列化器第四步:测试强化后的用例编辑器总结前言 在之前的后端文章…

HTTP连接管理——短连接,长连接,HTTP 流水线

连接管理是一个 HTTP 的关键话题&#xff1a;打开和保持连接在很大程度上影响着网站和 Web 应用程序的性能。在 HTTP/1.x 里有多种模型&#xff1a;短连接、_长连接_和 HTTP 流水线。 下面分别来详细解释 短连接 HTTP 协议最初&#xff08;0.9/1.0&#xff09;是个非常简单的…

MySQL范式和反范式

范式 是用一组规则定义的数据库设计标准&#xff0c;旨在确保数据库结构合理&#xff0c;避免数据冗余和异常。 目的 消除数据的重复&#xff0c;提高存储效率防止数据异常&#xff08;插入、删除、更新异常&#xff09;提高数据的完整性和一致性 第一范式 定义 所有列&am…

编程技能:格式化打印04,sprintf

专栏导航 本节文章分别属于《Win32 学习笔记》和《MFC 学习笔记》两个专栏&#xff0c;故划分为两个专栏导航。读者可以自行选择前往哪个专栏。 &#xff08;一&#xff09;WIn32 专栏导航 上一篇&#xff1a;编程技能&#xff1a;格式化打印03&#xff0c;printf 回到目录…

JavaScript性能优化实战:深入探讨JavaScript性能瓶颈与优化技巧

引言:为什么JavaScript性能至关重要 在现代Web开发中,JavaScript已成为构建交互式应用程序的核心技术。随着单页应用(SPA)和复杂前端架构的普及,JavaScript代码的性能直接影响用户体验、转化率甚至搜索引擎排名。研究表明,页面加载时间每增加1秒,转化率可能下降7%,而性能…

Java数据结构——八大排序

排序 插⼊排序希尔排序直接选择排序堆排序冒泡排序快速排序归并排序计数排序 排序的概念 排序&#xff1a;就是将一串东西&#xff0c;按照要求进行排序&#xff0c;按照递增或递减排序起来 稳定性&#xff1a;就是比如排序中有两个相同的数&#xff0c;如果排序后&#xff0c…

WPF响应式UI的基础:INotifyPropertyChanged

INotifyPropertyChanged 1 实现基础接口2 CallerMemberName优化3 数据更新触发策略4 高级应用技巧4.1 表达式树优化4.2 性能优化模式4.3 跨平台兼容实现 5 常见错误排查 在WPF的MVVM架构中&#xff0c; INotifyPropertyChanged是实现数据驱动界面的核心机制。本章将深入解析属…

低空城市场景下的多无人机任务规划与动态协调!CoordField:无人机任务分配的智能协调场

作者&#xff1a;Tengchao Zhang 1 ^{1} 1 , Yonglin Tian 2 ^{2} 2 , Fei Lin 1 ^{1} 1, Jun Huang 1 ^{1} 1, Patrik P. Sli 3 ^{3} 3, Rui Qin 2 , 4 ^{2,4} 2,4, and Fei-Yue Wang 5 , 1 ^{5,1} 5,1单位&#xff1a; 1 ^{1} 1澳门科技大学创新工程学院工程科学系&#xff0…

解决Java项目NoProviderFoundException报错

前言 在Java开发中&#xff0c;jakarta.validation.NoProviderFoundException 是一个令人困惑的运行时错误&#xff0c;常因校验框架依赖缺失或版本冲突导致。 问题复现&#xff1a;用户注册校验失败 业务场景 开发一个用户注册功能&#xff0c;要求&#xff1a; 校验邮箱…

重构跨境收益互换价值链:新一代TRS平台的破局之道

当香港券商面对内地汹涌的结构化产品需求&#xff0c;一套智能化的TRS系统正成为打开万亿市场的金钥匙 在跨境金融的暗流涌动中&#xff0c;一家中资背景的香港券商正面临甜蜜的烦恼&#xff1a;内地高净值客户对港股、美股的杠杆交易需求激增&#xff0c;但传统TRS业务深陷操作…

实验设计如何拯救我的 CEI VSR 28G 设计

为了确定总体设计裕量&#xff0c;CEI 28G VSR/100 Gb 以太网设计需要分析 500 万种通道变化、收发器工艺和均衡设置的组合。蛮力模拟需要 278 天&#xff0c;这显然超出了可用的时间表。 相反&#xff0c;我们使用实验设计 &#xff08;DOE&#xff09; 和响应面建模 &#x…

【仿生机器人】刀剑神域——爱丽丝苏醒计划,需求文档

仿生机器人"爱丽丝"系统架构设计需求文档 一、硬件基础 已完成头部和颈部硬件搭建 25个舵机驱动表情系统 颈部旋转功能 眼部摄像头&#xff08;视觉输入&#xff09; 麦克风阵列&#xff08;听觉输入&#xff09; 颈部发声装置&#xff08;语音输出&#xff09…