canvas火焰效果

自己私下做的一个火焰效果,留下作为记录。如果觉得有用,就请给个赞吧!

相关的解释都在代码中注释了.如果不需要看解释,文末有全部代码.可以先复制下来看看效果.

首先创建canvas对象,同时创建获取随机数的函数,方便后续使用.

let canvas_el = document.getElementById("fireGraphic");
let ctx = canvas_el.getContext("2d");
canvas_el.width = canvas_el.height = 600;
function rand (min, max){
    return Math.floor((Math.random() * (max - min + 1)) + min);
};
//火焰粒子对象效果
function fireBall(position) {
    this.rest(position);
};
// 帧数动画对象
window.requestAnimFrame = function () {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame ||
                window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (a) {
                    window.setTimeout(a, 1E3 / 60)
                }
}();

 创建单个火焰粒子,具有独立的属性和方法.粒子状态需要重新初始化的判断条件有多个,比如:当粒子的半径减少为负数时,或粒子超出画布时,或粒子存活时间剩余为0时,都可以重置此粒子的状态.本文是采用当粒子半径减少为负数作为重置条件.

//火焰粒子对象效果
function fireBall(position) {
    this.rest(position);
};
 //初始/重置粒子状态
fireBall.prototype.rest = function (position) {
      this._radius = rand(5, 25);//随机产生初始粒子半径
      this._position = position || {x: 300, y: 300};//初始位置
      this._lineWidth = 1;//粒子边界线宽
      //rgba(255,'+rand(0,165)+','+rand(0,100)+',0.3)
      this._color = 'rgba(255,5,0,0.3)';//粒子颜色
}
//渲染
fireBall.prototype.render=function(){
      ctx.beginPath();
      ctx.arc(this._position.x, this._position.y, this._radius, 0, Math.PI * 2, false);
      ctx.fillStyle = ctx.strokeStyle = this._color;
      ctx.lineWidth = this._lineWidth;
      ctx.fill();
      ctx.stroke();
}
// 更新粒子状态
fireBall.prototype.update = function () {
      if(this._radius>0&&this._position.y >this._radius){
          this._position.x -= rand(-3,3);
          this._position.y -= rand(3,4);
          this._radius -= 0.5;
      }else{
          this.rest();
      }
}

 单个粒子的功能实现完成后,只需要使用多个粒子构成火球效果

//用多个粒子模拟火球视觉效果,粒子数量自定
let fires = [];
for(var i=0; i< 200; i++){
   fires.push(new fireBall())
}

随后,按照循环调用粒子函数,渲染每一帧的图像.

let loop = function(){
    //循环调用
    requestAnimFrame(loop, canvas_el)
    //覆盖上一帧图像
    ctx.globalCompositeOperation="destination-out";
    ctx.fillStyle = 'hsla(0, 0%, 0%, 0.2)';
    ctx.fillRect(0,0,600,600);
    ctx.globalCompositeOperation = 'lighter';
    //绘制本帧的图像,更新状态为下一帧做准备
    fires.forEach(fire=>{
         fire.render();
         fire.update();
    })
}
loop();

PS:在此基础上,可以封装一个火球对象,后续使用时会更方便.本文不再做更多探讨

效果图:

最后附上全部代码

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>新增页面</title>
    <style>
        body {
            background: #111;
        }

        canvas {
            display: block;
            left: 30%;
            position: absolute;
            top: 30%;
        }
    </style>
</head>
<body>
    <canvas id="fireGraphic"></canvas>
    <script>
        let canvas_el = document.getElementById("fireGraphic");
        let ctx = canvas_el.getContext("2d");
        canvas_el.width = canvas_el.height = 600;
        function rand (min, max){
            return Math.floor((Math.random() * (max - min + 1)) + min);
        };
        //火焰粒子对象效果
        function fireBall(position) {
            this.rest(position);
        };
        // 帧数动画对象
        window.requestAnimFrame = function () {
            return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame ||
                window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (a) {
                    window.setTimeout(a, 1E3 / 60)
                }
        }();
        //初始/重置粒子状态
        fireBall.prototype.rest = function (position) {
            this._radius = rand(5, 25);//随机产生初始粒子半径
            this._position = position || {x: 300, y: 300};//初始位置
            this._lineWidth = 1;//粒子边界线宽
            //rgba(255,'+rand(0,165)+','+rand(0,100)+',0.3)
            this._color = 'rgba(255,5,0,0.3)';//粒子颜色
        }
        //渲染
        fireBall.prototype.render=function(){
                ctx.beginPath();
                ctx.arc(this._position.x, this._position.y, this._radius, 0, Math.PI * 2, false);
                ctx.fillStyle = ctx.strokeStyle = this._color;
                ctx.lineWidth = this._lineWidth;
                ctx.fill();
                ctx.stroke();
        }
        // 更新粒子状态
        fireBall.prototype.update = function () {
            if(this._radius>0&&this._position.y >this._radius){
                this._position.x -= rand(-3,3);
                this._position.y -= rand(3,4);
                this._radius -= 0.5;
            }else{
                this.rest();//
            }
        }
        //用多个粒子模拟火球视觉效果,粒子数量自定
        let fires = [];
        for(var i=0; i< 200; i++){
            fires.push(new fireBall())
        }
        let loop = function(){
            //循环调用
            requestAnimFrame(loop, canvas_el)
            //覆盖上一帧图像
            ctx.globalCompositeOperation="destination-out";
            ctx.fillStyle = 'hsla(0, 0%, 0%, 0.2)';
            ctx.fillRect(0,0,600,600);
            ctx.globalCompositeOperation = 'lighter';
            //绘制本帧的图像,更新状态为下一帧做准备
            fires.forEach(fire=>{
                fire.render();
                fire.update();
            })
        }
        loop();
    </script>
</body>
</html>

 

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的3D粒子爱心代码HTML源码: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>3D粒子爱心效果</title> <style> body { margin: 0; padding: 0; overflow: hidden; background-color: #000; } canvas { display: block; } </style> </head> <body> <canvas id="canvas"></canvas> <script> var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var W = canvas.width = window.innerWidth; var H = canvas.height = window.innerHeight; var particleCount = 200; var particles = []; function Particle() { this.x = Math.random() * W; this.y = Math.random() * H; this.vx = Math.random() * 20 - 10; this.vy = Math.random() * 20 - 10; this.gravity = 0.3; this.alpha = Math.random(); this.color = 'rgb(' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ',' + Math.floor(Math.random() * 255) + ')'; } Particle.prototype.draw = function() { ctx.globalAlpha = this.alpha; ctx.fillStyle = this.color; ctx.beginPath(); ctx.arc(this.x, this.y, 5, 0, Math.PI * 2, false); ctx.fill(); }; function init() { for (var i = 0; i < particleCount; i++) { particles.push(new Particle()); } } function update() { ctx.clearRect(0, 0, W, H); for (var i = 0; i < particleCount; i++) { var p = particles[i]; p.vy += p.gravity; p.x += p.vx; p.y += p.vy; if (p.x > W || p.x < 0 || p.y > H || p.y < 0) { particles[i] = new Particle(); } p.draw(); } } init(); setInterval(update, 1000 / 60); </script> </body> </html> ``` 这个代码使用了HTML5的Canvas标签和JavaScript来实现3D粒子爱心效果。它通过在Canvas上绘制大量的带有随机颜色和透明度的小圆点来模拟出一个3D的爱心效果。通过改变圆点的位置和速度,可以让它们在屏幕上自由运动,从而创造出动态的效果

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值