HTML5之 夜景放烟花

参考网址

https://blog.csdn.net/Gou_Hailong/article/details/122269931

https://blog.csdn.net/u013343616/article/details/122233674

复制代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=gb2312">
  <style>
    body{margin:0;padding:0;overflow: hidden;}
    .city{width:100%;position:fixed;bottom: 0px;z-index: 100;}
    .city img{width: 100%;}
  </style>
  <title>html5夜景放烟花绽放动画效果</title>
</head>
<body onselectstart = "return false">

<div style="height:700px;overflow:hidden;">

  <canvas id='cas' style="background-color:rgba(0,5,24,1);">浏览器不支持canvas</canvas>
  <div class="city"><img src="img/city.png" alt="" /></div>
  <img src="img/moon.png" alt="" id="moon" style="visibility: hidden;"/>
  <div style="display:none">
    <div class="shape">新年快乐</div>
    <div class="shape">合家幸福</div>
        <div class="shape">万事如意</div>
        <div class="shape">心想事成</div>
        <div class="shape">财源广进</div>
  </div>
  
</div>

  <script>
    var canvas = document.getElementById("cas");
    var ocas = document.createElement("canvas");
    var octx = ocas.getContext("2d");
    var ctx = canvas.getContext("2d");
    ocas.width = canvas.width = window.innerWidth;
    ocas.height = canvas.height = 700;
    var bigbooms = [];
  
    window.onload = function(){
      initAnimate()
    }

    function initAnimate(){
      drawBg();

      lastTime = new Date();
      animate();
    }

    var lastTime;
    function animate(){
      ctx.save();
      ctx.fillStyle = "rgba(0,5,24,0.1)";
      ctx.fillRect(0,0,canvas.width,canvas.height);
      ctx.restore();


      var newTime = new Date();
            if(newTime-lastTime>500+(window.innerHeight-767)/2){
        var random = Math.random()*100>2?true:false;
        var x = getRandom(canvas.width/5 , canvas.width*4/5);
        var y = getRandom(50 , 200);
        if(random){
          var bigboom = new Boom(getRandom(canvas.width/3,canvas.width*2/3) ,2,"#FFF" , {x:x , y:y});
          bigbooms.push(bigboom)
        }
        else {
          var bigboom = new Boom(getRandom(canvas.width/3,canvas.width*2/3) ,2,"#FFF" , {x:canvas.width/2 , y:200} , document.querySelectorAll(".shape")[parseInt(getRandom(0, document.querySelectorAll(".shape").length))]);
          bigbooms.push(bigboom)
        }
        lastTime = newTime;
        console.log(bigbooms)
      }

      stars.foreach(function(){
        this.paint();
      })

      drawMoon();

      bigbooms.foreach(function(index){
        var that = this;
        if(!this.dead){
          this._move();
          this._drawLight();
        }
        else{
          this.booms.foreach(function(index){
            if(!this.dead) {
              this.moveTo(index);
            }
            else if(index === that.booms.length-1){
              bigbooms[bigbooms.indexOf(that)] = null;
            }
          })
        }
      });
      
      raf(animate);
    }

    function drawMoon(){
      var moon = document.getElementById("moon");
      var centerX = canvas.width-200 , centerY = 100 , width = 80;
      if(moon.complete){
        ctx.drawImage(moon , centerX , centerY , width , width )
      }
      else {
        moon.onload = function(){
          ctx.drawImage(moon ,centerX , centerY , width , width)
        }
      }
      var index = 0;
      for(var i=0;i<10;i++){
        ctx.save();
        ctx.beginPath();
        ctx.arc(centerX+width/2 , centerY+width/2 , width/2+index , 0 , 2*Math.PI);
        ctx.fillStyle="rgba(240,219,120,0.005)";
        index+=2;
        ctx.fill();
        ctx.restore();
      }
      
    }
	
	    Array.prototype.foreach = function(callback){
	      for(var i=0;i<this.length;i++){
	        if(this[i]!==null) callback.apply(this[i] , [i])
	      }
	    }

	    var raf = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60); };
	    
	    canvas.onclick = function(){
	      var x = event.clientX;
	      var y = event.clientY;
	      var bigboom = new Boom(getRandom(canvas.width/3,canvas.width*2/3) ,2,"#FFF" , {x:x , y:y});
	      bigbooms.push(bigboom)
	    }
	
	    // canvas.addEventLisener("touchstart" , function(event){
	    //  var touch = event.targetTouches[0];
	    //  var x = event.pageX;
	    //  var y = event.pageY;
	    //  var bigboom = new Boom(getRandom(canvas.width/3,canvas.width*2/3) ,2,"#FFF" , {x:x , y:y});
	    //  bigbooms.push(bigboom)
	    // })
	
	    var Boom = function(x,r,c,boomArea,shape){
	      this.booms = [];
	      this.x = x;
	      this.y = (canvas.height+r);
	      this.r = r;
	      this.c = c;
	      this.shape = shape || false;
	      this.boomArea = boomArea;
	      this.theta = 0;
	      this.dead = false;
	      this.ba = parseInt(getRandom(80 , 200));
	    }
	    Boom.prototype = {
	      _paint:function(){
	        ctx.save();
	        ctx.beginPath();
	        ctx.arc(this.x,this.y,this.r,0,2*Math.PI);
	        ctx.fillStyle = this.c;
	        ctx.fill();
	        ctx.restore();
	      },
	      _move:function(){
	        var dx = this.boomArea.x - this.x , dy = this.boomArea.y - this.y;
	        this.x = this.x+dx*0.01;
	        this.y = this.y+dy*0.01;
	
	        if(Math.abs(dx)<=this.ba && Math.abs(dy)<=this.ba){
	          if(this.shape){
	            this._shapBoom();
	          }
	          else this._boom();
	          this.dead = true;
	        }
	        else {
	          this._paint();
	        }
	      },
	      _drawLight:function(){
	        ctx.save();
	        ctx.fillStyle = "rgba(255,228,150,0.3)";
	        ctx.beginPath();
	        ctx.arc(this.x , this.y , this.r+3*Math.random()+1 , 0 , 2*Math.PI);
	        ctx.fill();
	        ctx.restore();
	      },
	      _boom:function(){
	        var fragNum = getRandom(30 , 200);
	        var style = getRandom(0,10)>=5? 1 : 2;
	        var color;
	        if(style===1){
	          color = {
	            a:parseInt(getRandom(128,255)),
	            b:parseInt(getRandom(128,255)),
	            c:parseInt(getRandom(128,255))
	          }
	        }
	
	        var fanwei = parseInt(getRandom(300, 400));
	        for(var i=0;i<fragNum;i++){
	          if(style===2){
	            color = {
	              a:parseInt(getRandom(128,255)),
	              b:parseInt(getRandom(128,255)),
	              c:parseInt(getRandom(128,255))
	            }
	          }
	          var a = getRandom(-Math.PI, Math.PI);
	          var x = getRandom(0, fanwei) * Math.cos(a) + this.x;
	          var y = getRandom(0, fanwei) * Math.sin(a) + this.y; 
	          var radius = getRandom(0 , 2)
	          var frag = new Frag(this.x , this.y , radius , color , x , y );
	          this.booms.push(frag);
	        }
	      },
	      _shapBoom:function(){
	        var that = this;
	        putValue(ocas , octx , this.shape , 5, function(dots){
	          var dx = canvas.width/2-that.x;
	          var dy = canvas.height/2-that.y;
	          for(var i=0;i<dots.length;i++){
	            color = {a:dots[i].a,b:dots[i].b,c:dots[i].c}
	            var x = dots[i].x;
	            var y = dots[i].y;
	            var radius = 1;
	            var frag = new Frag(that.x , that.y , radius , color , x-dx , y-dy);
	            that.booms.push(frag);
	          }
	        })
	      }
	    }
	
	    function putValue(canvas , context , ele , dr , callback){
	      context.clearRect(0,0,canvas.width,canvas.height);
	      var img = new Image();
	      if(ele.innerHTML.indexOf("img")>=0){
	        img.src = ele.getElementsByTagName("img")[0].src;
	        imgload(img , function(){
	          context.drawImage(img , canvas.width/2 - img.width/2 , canvas.height/2 - img.width/2);
	          dots = getimgData(canvas , context , dr);
	          callback(dots);
	        })
	      }
	      else {
	        var text = ele.innerHTML;
	        context.save();
	        var fontSize =200;
	        context.font = fontSize+"px 宋体 bold";
	        context.textAlign = "center";
	        context.textBaseline = "middle";
	        context.fillStyle = "rgba("+parseInt(getRandom(128,255))+","+parseInt(getRandom(128,255))+","+parseInt(getRandom(128,255))+" , 1)";
	        context.fillText(text , canvas.width/2 , canvas.height/2);
	        context.restore();
	        dots = getimgData(canvas , context , dr);
	        callback(dots);
	      }
	    }
	
	    function imgload(img , callback){
	      if(img.complete){
	        callback.call(img);
	      }
	      else {
	        img.onload = function(){
	          callback.call(this);
	        }
	      }
	    }
	
	    function getimgData(canvas , context , dr){
	      var imgData = context.getImageData(0,0,canvas.width , canvas.height);
	      context.clearRect(0,0,canvas.width , canvas.height);
	      var dots = [];
	      for(var x=0;x<imgData.width;x+=dr){
	        for(var y=0;y<imgData.height;y+=dr){
	          var i = (y*imgData.width + x)*4;
	          if(imgData.data[i+3] > 128){
	            var dot = {x:x , y:y , a:imgData.data[i] , b:imgData.data[i+1] , c:imgData.data[i+2]};
	            dots.push(dot);
	          }
	        }
	      }
	      return dots;
	    }
	
	    function getRandom(a , b){
	      return Math.random()*(b-a)+a;
	    }
	
	
	    var maxRadius = 1 , stars=[];
	    function drawBg(){
	      for(var i=0;i<100;i++){
	        var r = Math.random()*maxRadius;
	        var x = Math.random()*canvas.width;
	        var y = Math.random()*2*canvas.height - canvas.height;
	        var star = new Star(x , y , r);
	        stars.push(star);
	        star.paint()
	      }
	
	    }
	
	    var Star = function(x,y,r){
	      this.x = x;this.y=y;this.r=r;
	    }
	    Star.prototype = {
	      paint:function(){
	        ctx.save();
	        ctx.beginPath();
	        ctx.arc(this.x , this.y , this.r , 0 , 2*Math.PI);
	        ctx.fillStyle = "rgba(255,255,255,"+this.r+")";
	        ctx.fill();
	        ctx.restore();
	      }
	    }
	
	    var focallength = 250;
	    var Frag = function(centerX , centerY , radius , color ,tx , ty){
	      this.tx = tx;
	      this.ty = ty;
	      this.x = centerX;
	      this.y = centerY;
	      this.dead = false;
	      this.centerX = centerX;
	      this.centerY = centerY;
	      this.radius = radius;
	      this.color = color;
	    }
	
	    Frag.prototype = {
	      paint:function(){
	        ctx.save();
	        ctx.beginPath();
	        ctx.arc(this.x , this.y , this.radius , 0 , 2*Math.PI);
	        ctx.fillStyle = "rgba("+this.color.a+","+this.color.b+","+this.color.c+",1)";
	        ctx.fill()
	        ctx.restore();
	      },
	      moveTo:function(index){
	        this.ty = this.ty+0.3;
	        var dx = this.tx - this.x , dy = this.ty - this.y;
	        this.x = Math.abs(dx)<0.1 ? this.tx : (this.x+dx*0.1);
	        this.y = Math.abs(dy)<0.1 ? this.ty : (this.y+dy*0.1);
	        if(dx===0 && Math.abs(dy)<=80){
	          this.dead = true;
	        }
	        this.paint();
	      }
	    }
	  </script>
	
	</body>
	</html>

目录结构

相关推荐
weixin_382395237 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__7 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.7 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~8 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华9 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子11 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅11 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni12 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学13 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端