Canvas生成艺术|意外诞生的混沌风暴(附完整源码+GitHub部署)

Canvas生成艺术|意外诞生的混沌风暴(附完整源码+GitHub部署)

文章目录

哈喽大家好!我是董翔(GitHub:dxiangwiki),一个刚入门Canvas的前端小白,今天给大家分享一个「无心插柳」的Canvas生成艺术作品------混沌风暴(Chaos Storm)

说出来你可能不信,这个看起来超炫酷的模糊风暴特效,最初只是我瞎改代码、手滑输错参数搞出来的"意外之作",从20万粒子CPU烤机版,到最终丝滑60fps优化版,全程充满了编程的乐趣和惊喜,今天就把完整创作过程、核心代码和GitHub部署教程,一次性分享给大家,新手也能直接上手复刻!

一、作品效果预览

先放一张动态效果描述(建议大家直接去我的GitHub Pages体验,更直观):

  • ✅ 全屏黑色背景,加载自动触发中心彩色爆炸

  • ✅ 鼠标移动即可触发全屏模糊风暴,越动越炸

  • ✅ 彩虹色随机线条交织,自带流动模糊感,视觉冲击力拉满

  • ✅ 优化后全程60fps,CPU不吵、不卡顿,普通电脑也能流畅运行

在线体验地址(GitHub Pages):https://dxiangwiki.github.io/chaos-storm/

GitHub仓库地址:https://github.com/dxiangwiki/chaos-storm

二、创作历程(主打一个"瞎改出奇迹")

作为Canvas新手,我本来只是想试试画圆、画线条,结果一步步"误打误撞"做出了这个特效,整个过程特别有趣,分享给同样刚入门的小伙伴,说不定能给你们带来灵感~

1. 初始阶段:从简单图形入手

刚开始接触Canvas,先练了最基础的操作:画圆形、画正方形、画线条,代码很简单,就是熟悉Canvas的基本API(arc、fill、beginPath这些),比如画一个黄色大圆、红色小圆,纯粹练手。

2. 进阶阶段:尝试粒子系统

练熟基础图形后,跟着教程写了一个简单的粒子类,实现了"点击生成粒子"的效果,这时候还只是普通的烟花雏形,没有任何特别的地方。

3. 神来之笔:误改参数,诞生模糊风暴

这是最关键的一步!我本来想调整粒子线条的方向,随手把代码里的「this.angle」改成了「this.angle / 2」,也就是这一个小小的改动,让线条方向和粒子运动方向错开了一半,瞬间从"笔直烟花"变成了"扭曲模糊风暴",效果直接拉满👇

js 复制代码
// 原本的代码(笔直线条)
ctx.lineTo(
  this.x - Math.cos(this.angle) * this.length,
  this.y - Math.sin(this.angle) * this.length
);

// 我瞎改后的代码(模糊风暴核心)
ctx.lineTo(
  this.x - Math.cos(this.angle / 2) * this.length,
  this.y - Math.sin(this.angle / 2) * this.length
);

4. 翻车时刻:20万粒子干响CPU

改出模糊风暴后,我一时兴起,把粒子生成数量从200改成了200000(手滑输多了两个0),结果一运行,CPU直接拉满、风扇疯狂转动,屏幕卡成PPT------这就是"CPU烤机版"混沌风暴,虽然炫酷,但根本没法正常体验😂

5. 最终优化:丝滑60fps版本

为了解决卡顿问题,我做了一系列优化(后面会详细说),严格限制粒子数量、简化计算、加快粒子消失速度,最终实现了"效果不变、丝滑运行"的版本,这也是现在GitHub上的最终版。

三、核心技术解析(新手友好,一看就懂)

这个项目的核心是「Canvas粒子系统」,没有复杂的框架,纯原生JS+Canvas实现,主要分为3个部分:初始化画布、粒子类、动画循环,下面拆解关键代码,新手也能看懂。

1. 初始化画布

首先创建Canvas元素,设置画布铺满整个屏幕,同时监听窗口 resize 事件,保证窗口缩放时,特效依然全屏显示。

js 复制代码
const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');

// 初始化画布铺满屏幕
function init() {
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
}
init();
// 窗口缩放时重新初始化
window.addEventListener('resize', init);

2. 随机数工具函数

整个特效的"混沌感"来自随机数,比如粒子的位置、速度、颜色、长度都是随机的,这里封装一个简单的随机数工具,方便后续调用。

js 复制代码
// 生成min到max之间的随机数
function random(min, max) {
    return Math.random() * (max - min) + min;
}

3. 核心粒子类(模糊风暴的关键)

粒子类是整个项目的核心,每个粒子都是一个独立的对象,包含位置、速度、角度、颜色等属性,还有更新(update)和绘制(draw)两个方法------这也是生成艺术中粒子系统的核心逻辑,通过控制每个粒子的行为,形成整体的视觉效果。

js 复制代码
class FireworkParticle {
    constructor(x, y) {
        this.x = x; // 粒子x坐标(鼠标位置)
        this.y = y; // 粒子y坐标(鼠标位置)
        this.angle = random(0, Math.PI * 2); // 随机角度(0-360度)
        this.speed = random(1, 4); // 随机速度(优化后,避免卡顿)
        this.length = random(8, 30); // 随机线条长度
        // 随机彩虹色(HSL色彩模型,更丰富的色彩变化)
        this.color = `hsl(${random(0, 360)}, 100%, ${random(50, 80)}%)`;
        this.lineWidth = random(1, 3); // 随机线条粗细
        this.alpha = 1; // 透明度(慢慢消失)
        this.decay = random(0.02, 0.05); // 透明度衰减速度(加快消失,减少堆积)
    }

    // 更新粒子状态(移动、透明度衰减)
    update() {
        this.x += Math.cos(this.angle) * this.speed; // 按角度移动x
        this.y += Math.sin(this.angle) * this.speed; // 按角度移动y
        this.alpha -= this.decay; // 透明度降低
        this.speed *= 0.98; // 速度衰减,模拟自然减速
    }

    // 绘制粒子(模糊风暴的核心代码)
    draw() {
        ctx.save();
        ctx.globalAlpha = this.alpha; // 设置透明度
        ctx.strokeStyle = this.color; // 设置线条颜色
        ctx.lineWidth = this.lineWidth; // 设置线条粗细
        ctx.lineCap = 'round'; // 线条圆角,更柔和
        ctx.beginPath();
        // 关键:角度除以2,造成线条错位,形成模糊风暴
        ctx.moveTo(this.x, this.y);
        ctx.lineTo(
            this.x - Math.cos(this.angle / 2) * this.length,
            this.y - Math.sin(this.angle / 2) * this.length
        );
        ctx.stroke();
        ctx.restore();
    }
}

4. 动画循环与交互逻辑

用 requestAnimationFrame 实现动画循环,每帧更新粒子状态、绘制粒子,同时添加鼠标移动事件,实现"鼠标一动就炸屏"的交互效果;另外加入粒子数量限制,避免CPU过载,这也是优化卡顿的关键。

js 复制代码
let particles = [];
const MAX_PARTICLES = 5000; // 最大粒子数,限制数量,避免卡顿

// 生成爆炸(单次生成数量限制)
function createExplosion(x, y, count = 200) {
    // 防止粒子溢出,只在总数没满的时候生成
    const canAdd = MAX_PARTICLES - particles.length;
    const actualCount = Math.min(count, canAdd);
    for (let i = 0; i < actualCount; i++) {
        particles.push(new FireworkParticle(x, y));
    }
}

// 页面加载自动触发中心爆炸
createExplosion(canvas.width / 2, canvas.height / 2, 300);

// 鼠标移动触发爆炸(核心交互)
canvas.addEventListener('mousemove', (e) => {
    createExplosion(e.x, e.y, 100);
});

// 动画循环(每帧更新、绘制粒子)
function animate() {
    requestAnimationFrame(animate);

    // 半透明背景,实现拖尾效果,更有流动感
    ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 过滤掉透明度小于0.01的粒子,减少计算量
    particles = particles.filter(p => p.alpha > 0.01);
    // 遍历所有粒子,更新状态、绘制粒子
    particles.forEach(p => {
        p.update();
        p.draw();
    });
}

// 启动动画
animate();

四、性能优化要点(解决卡顿问题)

从20万粒子卡顿版,优化到丝滑60fps,主要做了5个关键优化,新手可以参考这些优化思路,避免自己写的Canvas特效卡顿:

  1. 严格限制最大粒子数:设置 MAX_PARTICLES = 5000,多一个都不生成,从根源上减少CPU计算量,这是最有效的优化手段之一。

  2. 减少单次生成数量:鼠标移动时,单次生成100个粒子,避免瞬间堆爆粒子池。

  3. 加快粒子消失速度:提高透明度衰减速度(decay),让粒子快速消失,减少画面冗余和计算量。

  4. 简化随机计算:去掉双重随机(比如原本的 speed = random(2, random(4,8))),改为固定范围随机,减少CPU计算压力。

  5. 优化绘制逻辑:缩短线条长度、减少不必要的绘制操作,同时使用全屏半透明擦除,保证拖尾效果的同时,提升渲染效率。

五、完整源码(可直接复制使用)

下面是完整的 index.html 代码,复制保存为HTML文件,直接在浏览器打开就能看到效果,也可以直接上传到GitHub部署。

html 复制代码
<!DOCTYPE html>
混沌风暴 - 董翔的Canvas生成艺术

六、GitHub部署教程(超简单,新手也能会)

很多小伙伴想把自己的作品部署到GitHub Pages,这样可以直接分享链接给别人看,下面是详细步骤,跟着点就行:

1. 准备文件

创建一个名为 chaos-storm 的文件夹,里面放入3个文件(前面已经准备好):

  • index.html(上面的完整源码)

  • README.md(项目介绍,前面帮大家写好的)

  • LICENSE(MIT协议,2026年版,前面提供的)

2. 上传到GitHub

bash 复制代码
# 1. 初始化git(打开终端,进入项目文件夹)
git init

# 2. 添加所有文件
git add .

# 3. 提交代码(备注可自定义)
git commit -m "✨ Chaos Storm 混沌风暴 - 董翔的Canvas生成艺术"

# 4. 关联GitHub仓库(替换成你的仓库地址)
git remote add origin https://github.com/dxiangwiki/chaos-storm.git

# 5. 上传到GitHub(报错就用git push -u origin master)
git push -u origin main

3. 开启GitHub Pages

  1. 进入你的GitHub仓库(chaos-storm),点击顶部「Settings」

  2. 往下滑找到「Pages」选项

  3. Branch选择「main」(或master),文件夹选择「/root」

  4. 点击「Save」,等待1-2分钟,即可获得在线链接

七、总结与感悟

作为一个刚入门Canvas的小白,这个项目让我深刻感受到了编程的乐趣------艺术往往诞生于意外和失控

没有复杂的技术,没有严谨的规划,只是随手改一个参数、手滑输错一个数字,就诞生了一个独一无二的作品。这也让我明白,学习前端不必一直循规蹈矩,偶尔"瞎改"一下,说不定就能收获意想不到的惊喜。

这个项目虽然简单,但包含了Canvas粒子系统、动画循环、性能优化等核心知识点,新手可以通过这个项目,快速熟悉Canvas的基本用法,同时体会生成艺术的魅力------让代码成为画笔,让随机性成为灵感,这就是生成艺术的终极浪漫。

最后,附上我的GitHub仓库地址,欢迎大家Star、Fork,也可以根据自己的喜好修改参数,玩出属于自己的混沌风暴!

GitHub仓库:https://github.com/dxiangwiki/chaos-storm

在线体验:https://dxiangwiki.github.io/chaos-storm/

如果大家有更好的优化方案,或者想一起交流Canvas创作,欢迎在评论区留言,一起进步~

作者:董翔(dxiangwiki)

邮箱:3631247406@qq.com

相关推荐
CoderJia程序员甲7 小时前
GitHub 热榜项目 - 日榜(2026-04-04)
人工智能·ai·大模型·github·ai教程
OPHKVPS7 小时前
黑客反被黑:研究人员利用 XSS 漏洞劫持 StealC 控制面板,窃取攻击者情报
前端·网络·npm
whyfail8 小时前
Pretext:告别DOM重排,让文本布局飞起来
前端·dom
楚轩努力变强8 小时前
2026 年前端破局:从页面开发到前端隐私计算全链路架构师,构建原生数据安全合规体系
前端·国密算法·数据安全合规·前端安全·web crypto api·前端隐私计算·2026前端趋势
敲敲了个代码9 小时前
React 那么多状态管理库,到底选哪个?如果非要焊死一个呢?这篇文章解决你的选择困难症
前端·javascript·学习·react.js·前端框架
yungcy61639 小时前
React性能优化实战:从卡顿到丝滑,15个核心技巧覆盖全场景
前端·react.js·性能优化
阿珊和她的猫9 小时前
React 中 CSS 书写方式全解析
前端·css·react.js
Geoking.9 小时前
GitHub 多账号生存指南:从 SSH 连接到 GPG 签名全流程
运维·ssh·github